(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 2 ? arguments[2] : undefined; var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to); var inc = 1; if (from < to && to < from + count) { inc = -1; from += count - 1; to += count - 1; } while (count-- > 0) { if (from in O) O[to] = O[from]; else delete O[to]; to += inc; from += inc; } return O; }; },{"114":114,"118":118,"119":119}],9:[function(_dereq_,module,exports){ // 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length) 'use strict'; var toObject = _dereq_(119); var toAbsoluteIndex = _dereq_(114); var toLength = _dereq_(118); module.exports = function fill(value /* , start = 0, end = @length */) { var O = toObject(this); var length = toLength(O.length); var aLen = arguments.length; var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length); var end = aLen > 2 ? arguments[2] : undefined; var endPos = end === undefined ? length : toAbsoluteIndex(end, length); while (endPos > index) O[index++] = value; return O; }; },{"114":114,"118":118,"119":119}],10:[function(_dereq_,module,exports){ var forOf = _dereq_(39); module.exports = function (iter, ITERATOR) { var result = []; forOf(iter, false, result.push, result, ITERATOR); return result; }; },{"39":39}],11:[function(_dereq_,module,exports){ // false -> Array#indexOf // true -> Array#includes var toIObject = _dereq_(117); var toLength = _dereq_(118); var toAbsoluteIndex = _dereq_(114); module.exports = function (IS_INCLUDES) { return function ($this, el, fromIndex) { var O = toIObject($this); var length = toLength(O.length); var index = toAbsoluteIndex(fromIndex, length); var value; // Array#includes uses SameValueZero equality algorithm // eslint-disable-next-line no-self-compare if (IS_INCLUDES && el != el) while (length > index) { value = O[index++]; // eslint-disable-next-line no-self-compare if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not } else for (;length > index; index++) if (IS_INCLUDES || index in O) { if (O[index] === el) return IS_INCLUDES || index || 0; } return !IS_INCLUDES && -1; }; }; },{"114":114,"117":117,"118":118}],12:[function(_dereq_,module,exports){ // 0 -> Array#forEach // 1 -> Array#map // 2 -> Array#filter // 3 -> Array#some // 4 -> Array#every // 5 -> Array#find // 6 -> Array#findIndex var ctx = _dereq_(25); var IObject = _dereq_(47); var toObject = _dereq_(119); var toLength = _dereq_(118); var asc = _dereq_(15); module.exports = function (TYPE, $create) { var IS_MAP = TYPE == 1; var IS_FILTER = TYPE == 2; var IS_SOME = TYPE == 3; var IS_EVERY = TYPE == 4; var IS_FIND_INDEX = TYPE == 6; var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; var create = $create || asc; return function ($this, callbackfn, that) { var O = toObject($this); var self = IObject(O); var f = ctx(callbackfn, that, 3); var length = toLength(self.length); var index = 0; var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined; var val, res; for (;length > index; index++) if (NO_HOLES || index in self) { val = self[index]; res = f(val, index, O); if (TYPE) { if (IS_MAP) result[index] = res; // map else if (res) switch (TYPE) { case 3: return true; // some case 5: return val; // find case 6: return index; // findIndex case 2: result.push(val); // filter } else if (IS_EVERY) return false; // every } } return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result; }; }; },{"118":118,"119":119,"15":15,"25":25,"47":47}],13:[function(_dereq_,module,exports){ var aFunction = _dereq_(3); var toObject = _dereq_(119); var IObject = _dereq_(47); var toLength = _dereq_(118); module.exports = function (that, callbackfn, aLen, memo, isRight) { aFunction(callbackfn); var O = toObject(that); var self = IObject(O); var length = toLength(O.length); var index = isRight ? length - 1 : 0; var i = isRight ? -1 : 1; if (aLen < 2) for (;;) { if (index in self) { memo = self[index]; index += i; break; } index += i; if (isRight ? index < 0 : length <= index) { throw TypeError('Reduce of empty array with no initial value'); } } for (;isRight ? index >= 0 : length > index; index += i) if (index in self) { memo = callbackfn(memo, self[index], index, O); } return memo; }; },{"118":118,"119":119,"3":3,"47":47}],14:[function(_dereq_,module,exports){ var isObject = _dereq_(51); var isArray = _dereq_(49); var SPECIES = _dereq_(128)('species'); module.exports = function (original) { var C; if (isArray(original)) { C = original.constructor; // cross-realm fallback if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined; if (isObject(C)) { C = C[SPECIES]; if (C === null) C = undefined; } } return C === undefined ? Array : C; }; },{"128":128,"49":49,"51":51}],15:[function(_dereq_,module,exports){ // 9.4.2.3 ArraySpeciesCreate(originalArray, length) var speciesConstructor = _dereq_(14); module.exports = function (original, length) { return new (speciesConstructor(original))(length); }; },{"14":14}],16:[function(_dereq_,module,exports){ 'use strict'; var aFunction = _dereq_(3); var isObject = _dereq_(51); var invoke = _dereq_(46); var arraySlice = [].slice; var factories = {}; var construct = function (F, len, args) { if (!(len in factories)) { for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']'; // eslint-disable-next-line no-new-func factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')'); } return factories[len](F, args); }; module.exports = Function.bind || function bind(that /* , ...args */) { var fn = aFunction(this); var partArgs = arraySlice.call(arguments, 1); var bound = function (/* args... */) { var args = partArgs.concat(arraySlice.call(arguments)); return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that); }; if (isObject(fn.prototype)) bound.prototype = fn.prototype; return bound; }; },{"3":3,"46":46,"51":51}],17:[function(_dereq_,module,exports){ // getting tag from 19.1.3.6 Object.prototype.toString() var cof = _dereq_(18); var TAG = _dereq_(128)('toStringTag'); // ES3 wrong here var ARG = cof(function () { return arguments; }()) == 'Arguments'; // fallback for IE11 Script Access Denied error var tryGet = function (it, key) { try { return it[key]; } catch (e) { /* empty */ } }; module.exports = function (it) { var O, T, B; return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T // builtinTag case : ARG ? cof(O) // ES3 arguments fallback : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; }; },{"128":128,"18":18}],18:[function(_dereq_,module,exports){ var toString = {}.toString; module.exports = function (it) { return toString.call(it).slice(8, -1); }; },{}],19:[function(_dereq_,module,exports){ 'use strict'; var dP = _dereq_(72).f; var create = _dereq_(71); var redefineAll = _dereq_(93); var ctx = _dereq_(25); var anInstance = _dereq_(6); var forOf = _dereq_(39); var $iterDefine = _dereq_(55); var step = _dereq_(57); var setSpecies = _dereq_(100); var DESCRIPTORS = _dereq_(29); var fastKey = _dereq_(66).fastKey; var validate = _dereq_(125); var SIZE = DESCRIPTORS ? '_s' : 'size'; var getEntry = function (that, key) { // fast case var index = fastKey(key); var entry; if (index !== 'F') return that._i[index]; // frozen object case for (entry = that._f; entry; entry = entry.n) { if (entry.k == key) return entry; } }; module.exports = { getConstructor: function (wrapper, NAME, IS_MAP, ADDER) { var C = wrapper(function (that, iterable) { anInstance(that, C, NAME, '_i'); that._t = NAME; // collection type that._i = create(null); // index that._f = undefined; // first entry that._l = undefined; // last entry that[SIZE] = 0; // size if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); }); redefineAll(C.prototype, { // 23.1.3.1 Map.prototype.clear() // 23.2.3.2 Set.prototype.clear() clear: function clear() { for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) { entry.r = true; if (entry.p) entry.p = entry.p.n = undefined; delete data[entry.i]; } that._f = that._l = undefined; that[SIZE] = 0; }, // 23.1.3.3 Map.prototype.delete(key) // 23.2.3.4 Set.prototype.delete(value) 'delete': function (key) { var that = validate(this, NAME); var entry = getEntry(that, key); if (entry) { var next = entry.n; var prev = entry.p; delete that._i[entry.i]; entry.r = true; if (prev) prev.n = next; if (next) next.p = prev; if (that._f == entry) that._f = next; if (that._l == entry) that._l = prev; that[SIZE]--; } return !!entry; }, // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined) // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined) forEach: function forEach(callbackfn /* , that = undefined */) { validate(this, NAME); var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3); var entry; while (entry = entry ? entry.n : this._f) { f(entry.v, entry.k, this); // revert to the last existing entry while (entry && entry.r) entry = entry.p; } }, // 23.1.3.7 Map.prototype.has(key) // 23.2.3.7 Set.prototype.has(value) has: function has(key) { return !!getEntry(validate(this, NAME), key); } }); if (DESCRIPTORS) dP(C.prototype, 'size', { get: function () { return validate(this, NAME)[SIZE]; } }); return C; }, def: function (that, key, value) { var entry = getEntry(that, key); var prev, index; // change existing entry if (entry) { entry.v = value; // create new entry } else { that._l = entry = { i: index = fastKey(key, true), // <- index k: key, // <- key v: value, // <- value p: prev = that._l, // <- previous entry n: undefined, // <- next entry r: false // <- removed }; if (!that._f) that._f = entry; if (prev) prev.n = entry; that[SIZE]++; // add to index if (index !== 'F') that._i[index] = entry; } return that; }, getEntry: getEntry, setStrong: function (C, NAME, IS_MAP) { // add .keys, .values, .entries, [@@iterator] // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11 $iterDefine(C, NAME, function (iterated, kind) { this._t = validate(iterated, NAME); // target this._k = kind; // kind this._l = undefined; // previous }, function () { var that = this; var kind = that._k; var entry = that._l; // revert to the last existing entry while (entry && entry.r) entry = entry.p; // get next entry if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) { // or finish the iteration that._t = undefined; return step(1); } // return step by kind if (kind == 'keys') return step(0, entry.k); if (kind == 'values') return step(0, entry.v); return step(0, [entry.k, entry.v]); }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); // add [@@species], 23.1.2.2, 23.2.2.2 setSpecies(NAME); } }; },{"100":100,"125":125,"25":25,"29":29,"39":39,"55":55,"57":57,"6":6,"66":66,"71":71,"72":72,"93":93}],20:[function(_dereq_,module,exports){ // https://github.com/DavidBruant/Map-Set.prototype.toJSON var classof = _dereq_(17); var from = _dereq_(10); module.exports = function (NAME) { return function toJSON() { if (classof(this) != NAME) throw TypeError(NAME + "#toJSON isn't generic"); return from(this); }; }; },{"10":10,"17":17}],21:[function(_dereq_,module,exports){ 'use strict'; var redefineAll = _dereq_(93); var getWeak = _dereq_(66).getWeak; var anObject = _dereq_(7); var isObject = _dereq_(51); var anInstance = _dereq_(6); var forOf = _dereq_(39); var createArrayMethod = _dereq_(12); var $has = _dereq_(41); var validate = _dereq_(125); var arrayFind = createArrayMethod(5); var arrayFindIndex = createArrayMethod(6); var id = 0; // fallback for uncaught frozen keys var uncaughtFrozenStore = function (that) { return that._l || (that._l = new UncaughtFrozenStore()); }; var UncaughtFrozenStore = function () { this.a = []; }; var findUncaughtFrozen = function (store, key) { return arrayFind(store.a, function (it) { return it[0] === key; }); }; UncaughtFrozenStore.prototype = { get: function (key) { var entry = findUncaughtFrozen(this, key); if (entry) return entry[1]; }, has: function (key) { return !!findUncaughtFrozen(this, key); }, set: function (key, value) { var entry = findUncaughtFrozen(this, key); if (entry) entry[1] = value; else this.a.push([key, value]); }, 'delete': function (key) { var index = arrayFindIndex(this.a, function (it) { return it[0] === key; }); if (~index) this.a.splice(index, 1); return !!~index; } }; module.exports = { getConstructor: function (wrapper, NAME, IS_MAP, ADDER) { var C = wrapper(function (that, iterable) { anInstance(that, C, NAME, '_i'); that._t = NAME; // collection type that._i = id++; // collection id that._l = undefined; // leak store for uncaught frozen objects if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); }); redefineAll(C.prototype, { // 23.3.3.2 WeakMap.prototype.delete(key) // 23.4.3.3 WeakSet.prototype.delete(value) 'delete': function (key) { if (!isObject(key)) return false; var data = getWeak(key); if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key); return data && $has(data, this._i) && delete data[this._i]; }, // 23.3.3.4 WeakMap.prototype.has(key) // 23.4.3.4 WeakSet.prototype.has(value) has: function has(key) { if (!isObject(key)) return false; var data = getWeak(key); if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key); return data && $has(data, this._i); } }); return C; }, def: function (that, key, value) { var data = getWeak(anObject(key), true); if (data === true) uncaughtFrozenStore(that).set(key, value); else data[that._i] = value; return that; }, ufstore: uncaughtFrozenStore }; },{"12":12,"125":125,"39":39,"41":41,"51":51,"6":6,"66":66,"7":7,"93":93}],22:[function(_dereq_,module,exports){ 'use strict'; var global = _dereq_(40); var $export = _dereq_(33); var redefine = _dereq_(94); var redefineAll = _dereq_(93); var meta = _dereq_(66); var forOf = _dereq_(39); var anInstance = _dereq_(6); var isObject = _dereq_(51); var fails = _dereq_(35); var $iterDetect = _dereq_(56); var setToStringTag = _dereq_(101); var inheritIfRequired = _dereq_(45); module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) { var Base = global[NAME]; var C = Base; var ADDER = IS_MAP ? 'set' : 'add'; var proto = C && C.prototype; var O = {}; var fixMethod = function (KEY) { var fn = proto[KEY]; redefine(proto, KEY, KEY == 'delete' ? function (a) { return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); } : KEY == 'has' ? function has(a) { return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); } : KEY == 'get' ? function get(a) { return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a); } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; } : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; } ); }; if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () { new C().entries().next(); }))) { // create collection constructor C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); redefineAll(C.prototype, methods); meta.NEED = true; } else { var instance = new C(); // early implementations not supports chaining var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance; // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); }); // most early implementations doesn't supports iterables, most modern - not close it correctly var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new // for early implementations -0 and +0 not the same var BUGGY_ZERO = !IS_WEAK && fails(function () { // V8 ~ Chromium 42- fails only with 5+ elements var $instance = new C(); var index = 5; while (index--) $instance[ADDER](index, index); return !$instance.has(-0); }); if (!ACCEPT_ITERABLES) { C = wrapper(function (target, iterable) { anInstance(target, C, NAME); var that = inheritIfRequired(new Base(), target, C); if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that); return that; }); C.prototype = proto; proto.constructor = C; } if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { fixMethod('delete'); fixMethod('has'); IS_MAP && fixMethod('get'); } if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); // weak collections should not contains .clear method if (IS_WEAK && proto.clear) delete proto.clear; } setToStringTag(C, NAME); O[NAME] = C; $export($export.G + $export.W + $export.F * (C != Base), O); if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP); return C; }; },{"101":101,"33":33,"35":35,"39":39,"40":40,"45":45,"51":51,"56":56,"6":6,"66":66,"93":93,"94":94}],23:[function(_dereq_,module,exports){ var core = module.exports = { version: '2.5.0' }; if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef },{}],24:[function(_dereq_,module,exports){ 'use strict'; var $defineProperty = _dereq_(72); var createDesc = _dereq_(92); module.exports = function (object, index, value) { if (index in object) $defineProperty.f(object, index, createDesc(0, value)); else object[index] = value; }; },{"72":72,"92":92}],25:[function(_dereq_,module,exports){ // optional / simple context binding var aFunction = _dereq_(3); module.exports = function (fn, that, length) { aFunction(fn); if (that === undefined) return fn; switch (length) { case 1: return function (a) { return fn.call(that, a); }; case 2: return function (a, b) { return fn.call(that, a, b); }; case 3: return function (a, b, c) { return fn.call(that, a, b, c); }; } return function (/* ...args */) { return fn.apply(that, arguments); }; }; },{"3":3}],26:[function(_dereq_,module,exports){ 'use strict'; // 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString() var fails = _dereq_(35); var getTime = Date.prototype.getTime; var $toISOString = Date.prototype.toISOString; var lz = function (num) { return num > 9 ? num : '0' + num; }; // PhantomJS / old WebKit has a broken implementations module.exports = (fails(function () { return $toISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z'; }) || !fails(function () { $toISOString.call(new Date(NaN)); })) ? function toISOString() { if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value'); var d = this; var y = d.getUTCFullYear(); var m = d.getUTCMilliseconds(); var s = y < 0 ? '-' : y > 9999 ? '+' : ''; return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) + '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) + 'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) + ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z'; } : $toISOString; },{"35":35}],27:[function(_dereq_,module,exports){ 'use strict'; var anObject = _dereq_(7); var toPrimitive = _dereq_(120); var NUMBER = 'number'; module.exports = function (hint) { if (hint !== 'string' && hint !== NUMBER && hint !== 'default') throw TypeError('Incorrect hint'); return toPrimitive(anObject(this), hint != NUMBER); }; },{"120":120,"7":7}],28:[function(_dereq_,module,exports){ // 7.2.1 RequireObjectCoercible(argument) module.exports = function (it) { if (it == undefined) throw TypeError("Can't call method on " + it); return it; }; },{}],29:[function(_dereq_,module,exports){ // Thank's IE8 for his funny defineProperty module.exports = !_dereq_(35)(function () { return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; }); },{"35":35}],30:[function(_dereq_,module,exports){ var isObject = _dereq_(51); var document = _dereq_(40).document; // typeof document.createElement is 'object' in old IE var is = isObject(document) && isObject(document.createElement); module.exports = function (it) { return is ? document.createElement(it) : {}; }; },{"40":40,"51":51}],31:[function(_dereq_,module,exports){ // IE 8- don't enum bug keys module.exports = ( 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' ).split(','); },{}],32:[function(_dereq_,module,exports){ // all enumerable object keys, includes symbols var getKeys = _dereq_(81); var gOPS = _dereq_(78); var pIE = _dereq_(82); module.exports = function (it) { var result = getKeys(it); var getSymbols = gOPS.f; if (getSymbols) { var symbols = getSymbols(it); var isEnum = pIE.f; var i = 0; var key; while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key); } return result; }; },{"78":78,"81":81,"82":82}],33:[function(_dereq_,module,exports){ var global = _dereq_(40); var core = _dereq_(23); var hide = _dereq_(42); var redefine = _dereq_(94); var ctx = _dereq_(25); var PROTOTYPE = 'prototype'; var $export = function (type, name, source) { var IS_FORCED = type & $export.F; var IS_GLOBAL = type & $export.G; var IS_STATIC = type & $export.S; var IS_PROTO = type & $export.P; var IS_BIND = type & $export.B; var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]; var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); var key, own, out, exp; if (IS_GLOBAL) source = name; for (key in source) { // contains in native own = !IS_FORCED && target && target[key] !== undefined; // export native or passed out = (own ? target : source)[key]; // bind timers to global for call from export context exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; // extend global if (target) redefine(target, key, out, type & $export.U); // export if (exports[key] != out) hide(exports, key, exp); if (IS_PROTO && expProto[key] != out) expProto[key] = out; } }; global.core = core; // type bitmap $export.F = 1; // forced $export.G = 2; // global $export.S = 4; // static $export.P = 8; // proto $export.B = 16; // bind $export.W = 32; // wrap $export.U = 64; // safe $export.R = 128; // real proto method for `library` module.exports = $export; },{"23":23,"25":25,"40":40,"42":42,"94":94}],34:[function(_dereq_,module,exports){ var MATCH = _dereq_(128)('match'); module.exports = function (KEY) { var re = /./; try { '/./'[KEY](re); } catch (e) { try { re[MATCH] = false; return !'/./'[KEY](re); } catch (f) { /* empty */ } } return true; }; },{"128":128}],35:[function(_dereq_,module,exports){ module.exports = function (exec) { try { return !!exec(); } catch (e) { return true; } }; },{}],36:[function(_dereq_,module,exports){ 'use strict'; var hide = _dereq_(42); var redefine = _dereq_(94); var fails = _dereq_(35); var defined = _dereq_(28); var wks = _dereq_(128); module.exports = function (KEY, length, exec) { var SYMBOL = wks(KEY); var fns = exec(defined, SYMBOL, ''[KEY]); var strfn = fns[0]; var rxfn = fns[1]; if (fails(function () { var O = {}; O[SYMBOL] = function () { return 7; }; return ''[KEY](O) != 7; })) { redefine(String.prototype, KEY, strfn); hide(RegExp.prototype, SYMBOL, length == 2 // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue) // 21.2.5.11 RegExp.prototype[@@split](string, limit) ? function (string, arg) { return rxfn.call(string, this, arg); } // 21.2.5.6 RegExp.prototype[@@match](string) // 21.2.5.9 RegExp.prototype[@@search](string) : function (string) { return rxfn.call(string, this); } ); } }; },{"128":128,"28":28,"35":35,"42":42,"94":94}],37:[function(_dereq_,module,exports){ 'use strict'; // 21.2.5.3 get RegExp.prototype.flags var anObject = _dereq_(7); module.exports = function () { var that = anObject(this); var result = ''; if (that.global) result += 'g'; if (that.ignoreCase) result += 'i'; if (that.multiline) result += 'm'; if (that.unicode) result += 'u'; if (that.sticky) result += 'y'; return result; }; },{"7":7}],38:[function(_dereq_,module,exports){ 'use strict'; // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray var isArray = _dereq_(49); var isObject = _dereq_(51); var toLength = _dereq_(118); var ctx = _dereq_(25); var IS_CONCAT_SPREADABLE = _dereq_(128)('isConcatSpreadable'); function flattenIntoArray(target, original, source, sourceLen, start, depth, mapper, thisArg) { var targetIndex = start; var sourceIndex = 0; var mapFn = mapper ? ctx(mapper, thisArg, 3) : false; var element, spreadable; while (sourceIndex < sourceLen) { if (sourceIndex in source) { element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex]; spreadable = false; if (isObject(element)) { spreadable = element[IS_CONCAT_SPREADABLE]; spreadable = spreadable !== undefined ? !!spreadable : isArray(element); } if (spreadable && depth > 0) { targetIndex = flattenIntoArray(target, original, element, toLength(element.length), targetIndex, depth - 1) - 1; } else { if (targetIndex >= 0x1fffffffffffff) throw TypeError(); target[targetIndex] = element; } targetIndex++; } sourceIndex++; } return targetIndex; } module.exports = flattenIntoArray; },{"118":118,"128":128,"25":25,"49":49,"51":51}],39:[function(_dereq_,module,exports){ var ctx = _dereq_(25); var call = _dereq_(53); var isArrayIter = _dereq_(48); var anObject = _dereq_(7); var toLength = _dereq_(118); var getIterFn = _dereq_(129); var BREAK = {}; var RETURN = {}; var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable); var f = ctx(fn, that, entries ? 2 : 1); var index = 0; var length, step, iterator, result; if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); // fast case for arrays with default iterator if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); if (result === BREAK || result === RETURN) return result; } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { result = call(iterator, f, step.value, entries); if (result === BREAK || result === RETURN) return result; } }; exports.BREAK = BREAK; exports.RETURN = RETURN; },{"118":118,"129":129,"25":25,"48":48,"53":53,"7":7}],40:[function(_dereq_,module,exports){ // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self // eslint-disable-next-line no-new-func : Function('return this')(); if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef },{}],41:[function(_dereq_,module,exports){ var hasOwnProperty = {}.hasOwnProperty; module.exports = function (it, key) { return hasOwnProperty.call(it, key); }; },{}],42:[function(_dereq_,module,exports){ var dP = _dereq_(72); var createDesc = _dereq_(92); module.exports = _dereq_(29) ? function (object, key, value) { return dP.f(object, key, createDesc(1, value)); } : function (object, key, value) { object[key] = value; return object; }; },{"29":29,"72":72,"92":92}],43:[function(_dereq_,module,exports){ var document = _dereq_(40).document; module.exports = document && document.documentElement; },{"40":40}],44:[function(_dereq_,module,exports){ module.exports = !_dereq_(29) && !_dereq_(35)(function () { return Object.defineProperty(_dereq_(30)('div'), 'a', { get: function () { return 7; } }).a != 7; }); },{"29":29,"30":30,"35":35}],45:[function(_dereq_,module,exports){ var isObject = _dereq_(51); var setPrototypeOf = _dereq_(99).set; module.exports = function (that, target, C) { var S = target.constructor; var P; if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) { setPrototypeOf(that, P); } return that; }; },{"51":51,"99":99}],46:[function(_dereq_,module,exports){ // fast apply, http://jsperf.lnkit.com/fast-apply/5 module.exports = function (fn, args, that) { var un = that === undefined; switch (args.length) { case 0: return un ? fn() : fn.call(that); case 1: return un ? fn(args[0]) : fn.call(that, args[0]); case 2: return un ? fn(args[0], args[1]) : fn.call(that, args[0], args[1]); case 3: return un ? fn(args[0], args[1], args[2]) : fn.call(that, args[0], args[1], args[2]); case 4: return un ? fn(args[0], args[1], args[2], args[3]) : fn.call(that, args[0], args[1], args[2], args[3]); } return fn.apply(that, args); }; },{}],47:[function(_dereq_,module,exports){ // fallback for non-array-like ES3 and non-enumerable old V8 strings var cof = _dereq_(18); // eslint-disable-next-line no-prototype-builtins module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { return cof(it) == 'String' ? it.split('') : Object(it); }; },{"18":18}],48:[function(_dereq_,module,exports){ // check on default Array iterator var Iterators = _dereq_(58); var ITERATOR = _dereq_(128)('iterator'); var ArrayProto = Array.prototype; module.exports = function (it) { return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); }; },{"128":128,"58":58}],49:[function(_dereq_,module,exports){ // 7.2.2 IsArray(argument) var cof = _dereq_(18); module.exports = Array.isArray || function isArray(arg) { return cof(arg) == 'Array'; }; },{"18":18}],50:[function(_dereq_,module,exports){ // 20.1.2.3 Number.isInteger(number) var isObject = _dereq_(51); var floor = Math.floor; module.exports = function isInteger(it) { return !isObject(it) && isFinite(it) && floor(it) === it; }; },{"51":51}],51:[function(_dereq_,module,exports){ module.exports = function (it) { return typeof it === 'object' ? it !== null : typeof it === 'function'; }; },{}],52:[function(_dereq_,module,exports){ // 7.2.8 IsRegExp(argument) var isObject = _dereq_(51); var cof = _dereq_(18); var MATCH = _dereq_(128)('match'); module.exports = function (it) { var isRegExp; return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp'); }; },{"128":128,"18":18,"51":51}],53:[function(_dereq_,module,exports){ // call something on iterator step with safe closing on error var anObject = _dereq_(7); module.exports = function (iterator, fn, value, entries) { try { return entries ? fn(anObject(value)[0], value[1]) : fn(value); // 7.4.6 IteratorClose(iterator, completion) } catch (e) { var ret = iterator['return']; if (ret !== undefined) anObject(ret.call(iterator)); throw e; } }; },{"7":7}],54:[function(_dereq_,module,exports){ 'use strict'; var create = _dereq_(71); var descriptor = _dereq_(92); var setToStringTag = _dereq_(101); var IteratorPrototype = {}; // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() _dereq_(42)(IteratorPrototype, _dereq_(128)('iterator'), function () { return this; }); module.exports = function (Constructor, NAME, next) { Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); setToStringTag(Constructor, NAME + ' Iterator'); }; },{"101":101,"128":128,"42":42,"71":71,"92":92}],55:[function(_dereq_,module,exports){ 'use strict'; var LIBRARY = _dereq_(60); var $export = _dereq_(33); var redefine = _dereq_(94); var hide = _dereq_(42); var has = _dereq_(41); var Iterators = _dereq_(58); var $iterCreate = _dereq_(54); var setToStringTag = _dereq_(101); var getPrototypeOf = _dereq_(79); var ITERATOR = _dereq_(128)('iterator'); var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` var FF_ITERATOR = '@@iterator'; var KEYS = 'keys'; var VALUES = 'values'; var returnThis = function () { return this; }; module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { $iterCreate(Constructor, NAME, next); var getMethod = function (kind) { if (!BUGGY && kind in proto) return proto[kind]; switch (kind) { case KEYS: return function keys() { return new Constructor(this, kind); }; case VALUES: return function values() { return new Constructor(this, kind); }; } return function entries() { return new Constructor(this, kind); }; }; var TAG = NAME + ' Iterator'; var DEF_VALUES = DEFAULT == VALUES; var VALUES_BUG = false; var proto = Base.prototype; var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; var $default = $native || getMethod(DEFAULT); var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; var methods, key, IteratorPrototype; // Fix native if ($anyNative) { IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { // Set @@toStringTag to native iterators setToStringTag(IteratorPrototype, TAG, true); // fix for some old engines if (!LIBRARY && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis); } } // fix Array#{values, @@iterator}.name in V8 / FF if (DEF_VALUES && $native && $native.name !== VALUES) { VALUES_BUG = true; $default = function values() { return $native.call(this); }; } // Define iterator if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { hide(proto, ITERATOR, $default); } // Plug for library Iterators[NAME] = $default; Iterators[TAG] = returnThis; if (DEFAULT) { methods = { values: DEF_VALUES ? $default : getMethod(VALUES), keys: IS_SET ? $default : getMethod(KEYS), entries: $entries }; if (FORCED) for (key in methods) { if (!(key in proto)) redefine(proto, key, methods[key]); } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); } return methods; }; },{"101":101,"128":128,"33":33,"41":41,"42":42,"54":54,"58":58,"60":60,"79":79,"94":94}],56:[function(_dereq_,module,exports){ var ITERATOR = _dereq_(128)('iterator'); var SAFE_CLOSING = false; try { var riter = [7][ITERATOR](); riter['return'] = function () { SAFE_CLOSING = true; }; // eslint-disable-next-line no-throw-literal Array.from(riter, function () { throw 2; }); } catch (e) { /* empty */ } module.exports = function (exec, skipClosing) { if (!skipClosing && !SAFE_CLOSING) return false; var safe = false; try { var arr = [7]; var iter = arr[ITERATOR](); iter.next = function () { return { done: safe = true }; }; arr[ITERATOR] = function () { return iter; }; exec(arr); } catch (e) { /* empty */ } return safe; }; },{"128":128}],57:[function(_dereq_,module,exports){ module.exports = function (done, value) { return { value: value, done: !!done }; }; },{}],58:[function(_dereq_,module,exports){ module.exports = {}; },{}],59:[function(_dereq_,module,exports){ var getKeys = _dereq_(81); var toIObject = _dereq_(117); module.exports = function (object, el) { var O = toIObject(object); var keys = getKeys(O); var length = keys.length; var index = 0; var key; while (length > index) if (O[key = keys[index++]] === el) return key; }; },{"117":117,"81":81}],60:[function(_dereq_,module,exports){ module.exports = false; },{}],61:[function(_dereq_,module,exports){ // 20.2.2.14 Math.expm1(x) var $expm1 = Math.expm1; module.exports = (!$expm1 // Old FF bug || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168 // Tor Browser bug || $expm1(-2e-17) != -2e-17 ) ? function expm1(x) { return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1; } : $expm1; },{}],62:[function(_dereq_,module,exports){ // 20.2.2.16 Math.fround(x) var sign = _dereq_(65); var pow = Math.pow; var EPSILON = pow(2, -52); var EPSILON32 = pow(2, -23); var MAX32 = pow(2, 127) * (2 - EPSILON32); var MIN32 = pow(2, -126); var roundTiesToEven = function (n) { return n + 1 / EPSILON - 1 / EPSILON; }; module.exports = Math.fround || function fround(x) { var $abs = Math.abs(x); var $sign = sign(x); var a, result; if ($abs < MIN32) return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32; a = (1 + EPSILON32 / EPSILON) * $abs; result = a - (a - $abs); // eslint-disable-next-line no-self-compare if (result > MAX32 || result != result) return $sign * Infinity; return $sign * result; }; },{"65":65}],63:[function(_dereq_,module,exports){ // 20.2.2.20 Math.log1p(x) module.exports = Math.log1p || function log1p(x) { return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x); }; },{}],64:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ module.exports = Math.scale || function scale(x, inLow, inHigh, outLow, outHigh) { if ( arguments.length === 0 // eslint-disable-next-line no-self-compare || x != x // eslint-disable-next-line no-self-compare || inLow != inLow // eslint-disable-next-line no-self-compare || inHigh != inHigh // eslint-disable-next-line no-self-compare || outLow != outLow // eslint-disable-next-line no-self-compare || outHigh != outHigh ) return NaN; if (x === Infinity || x === -Infinity) return x; return (x - inLow) * (outHigh - outLow) / (inHigh - inLow) + outLow; }; },{}],65:[function(_dereq_,module,exports){ // 20.2.2.28 Math.sign(x) module.exports = Math.sign || function sign(x) { // eslint-disable-next-line no-self-compare return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1; }; },{}],66:[function(_dereq_,module,exports){ var META = _dereq_(124)('meta'); var isObject = _dereq_(51); var has = _dereq_(41); var setDesc = _dereq_(72).f; var id = 0; var isExtensible = Object.isExtensible || function () { return true; }; var FREEZE = !_dereq_(35)(function () { return isExtensible(Object.preventExtensions({})); }); var setMeta = function (it) { setDesc(it, META, { value: { i: 'O' + ++id, // object ID w: {} // weak collections IDs } }); }; var fastKey = function (it, create) { // return primitive with prefix if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; if (!has(it, META)) { // can't set metadata to uncaught frozen object if (!isExtensible(it)) return 'F'; // not necessary to add metadata if (!create) return 'E'; // add missing metadata setMeta(it); // return object ID } return it[META].i; }; var getWeak = function (it, create) { if (!has(it, META)) { // can't set metadata to uncaught frozen object if (!isExtensible(it)) return true; // not necessary to add metadata if (!create) return false; // add missing metadata setMeta(it); // return hash weak collections IDs } return it[META].w; }; // add metadata on freeze-family methods calling var onFreeze = function (it) { if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it); return it; }; var meta = module.exports = { KEY: META, NEED: false, fastKey: fastKey, getWeak: getWeak, onFreeze: onFreeze }; },{"124":124,"35":35,"41":41,"51":51,"72":72}],67:[function(_dereq_,module,exports){ var Map = _dereq_(160); var $export = _dereq_(33); var shared = _dereq_(103)('metadata'); var store = shared.store || (shared.store = new (_dereq_(266))()); var getOrCreateMetadataMap = function (target, targetKey, create) { var targetMetadata = store.get(target); if (!targetMetadata) { if (!create) return undefined; store.set(target, targetMetadata = new Map()); } var keyMetadata = targetMetadata.get(targetKey); if (!keyMetadata) { if (!create) return undefined; targetMetadata.set(targetKey, keyMetadata = new Map()); } return keyMetadata; }; var ordinaryHasOwnMetadata = function (MetadataKey, O, P) { var metadataMap = getOrCreateMetadataMap(O, P, false); return metadataMap === undefined ? false : metadataMap.has(MetadataKey); }; var ordinaryGetOwnMetadata = function (MetadataKey, O, P) { var metadataMap = getOrCreateMetadataMap(O, P, false); return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey); }; var ordinaryDefineOwnMetadata = function (MetadataKey, MetadataValue, O, P) { getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue); }; var ordinaryOwnMetadataKeys = function (target, targetKey) { var metadataMap = getOrCreateMetadataMap(target, targetKey, false); var keys = []; if (metadataMap) metadataMap.forEach(function (_, key) { keys.push(key); }); return keys; }; var toMetaKey = function (it) { return it === undefined || typeof it == 'symbol' ? it : String(it); }; var exp = function (O) { $export($export.S, 'Reflect', O); }; module.exports = { store: store, map: getOrCreateMetadataMap, has: ordinaryHasOwnMetadata, get: ordinaryGetOwnMetadata, set: ordinaryDefineOwnMetadata, keys: ordinaryOwnMetadataKeys, key: toMetaKey, exp: exp }; },{"103":103,"160":160,"266":266,"33":33}],68:[function(_dereq_,module,exports){ var global = _dereq_(40); var macrotask = _dereq_(113).set; var Observer = global.MutationObserver || global.WebKitMutationObserver; var process = global.process; var Promise = global.Promise; var isNode = _dereq_(18)(process) == 'process'; module.exports = function () { var head, last, notify; var flush = function () { var parent, fn; if (isNode && (parent = process.domain)) parent.exit(); while (head) { fn = head.fn; head = head.next; try { fn(); } catch (e) { if (head) notify(); else last = undefined; throw e; } } last = undefined; if (parent) parent.enter(); }; // Node.js if (isNode) { notify = function () { process.nextTick(flush); }; // browsers with MutationObserver } else if (Observer) { var toggle = true; var node = document.createTextNode(''); new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new notify = function () { node.data = toggle = !toggle; }; // environments with maybe non-completely correct, but existent Promise } else if (Promise && Promise.resolve) { var promise = Promise.resolve(); notify = function () { promise.then(flush); }; // for other environments - macrotask based on: // - setImmediate // - MessageChannel // - window.postMessag // - onreadystatechange // - setTimeout } else { notify = function () { // strange IE + webpack dev server bug - use .call(global) macrotask.call(global, flush); }; } return function (fn) { var task = { fn: fn, next: undefined }; if (last) last.next = task; if (!head) { head = task; notify(); } last = task; }; }; },{"113":113,"18":18,"40":40}],69:[function(_dereq_,module,exports){ 'use strict'; // 25.4.1.5 NewPromiseCapability(C) var aFunction = _dereq_(3); function PromiseCapability(C) { var resolve, reject; this.promise = new C(function ($$resolve, $$reject) { if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); resolve = $$resolve; reject = $$reject; }); this.resolve = aFunction(resolve); this.reject = aFunction(reject); } module.exports.f = function (C) { return new PromiseCapability(C); }; },{"3":3}],70:[function(_dereq_,module,exports){ 'use strict'; // 19.1.2.1 Object.assign(target, source, ...) var getKeys = _dereq_(81); var gOPS = _dereq_(78); var pIE = _dereq_(82); var toObject = _dereq_(119); var IObject = _dereq_(47); var $assign = Object.assign; // should work with symbols and should have deterministic property order (V8 bug) module.exports = !$assign || _dereq_(35)(function () { var A = {}; var B = {}; // eslint-disable-next-line no-undef var S = Symbol(); var K = 'abcdefghijklmnopqrst'; A[S] = 7; K.split('').forEach(function (k) { B[k] = k; }); return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; }) ? function assign(target, source) { // eslint-disable-line no-unused-vars var T = toObject(target); var aLen = arguments.length; var index = 1; var getSymbols = gOPS.f; var isEnum = pIE.f; while (aLen > index) { var S = IObject(arguments[index++]); var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S); var length = keys.length; var j = 0; var key; while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key]; } return T; } : $assign; },{"119":119,"35":35,"47":47,"78":78,"81":81,"82":82}],71:[function(_dereq_,module,exports){ // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) var anObject = _dereq_(7); var dPs = _dereq_(73); var enumBugKeys = _dereq_(31); var IE_PROTO = _dereq_(102)('IE_PROTO'); var Empty = function () { /* empty */ }; var PROTOTYPE = 'prototype'; // Create object with fake `null` prototype: use iframe Object with cleared prototype var createDict = function () { // Thrash, waste and sodomy: IE GC bug var iframe = _dereq_(30)('iframe'); var i = enumBugKeys.length; var lt = '<'; var gt = '>'; var iframeDocument; iframe.style.display = 'none'; _dereq_(43).appendChild(iframe); iframe.src = 'javascript:'; // eslint-disable-line no-script-url // createDict = iframe.contentWindow.Object; // html.removeChild(iframe); iframeDocument = iframe.contentWindow.document; iframeDocument.open(); iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); iframeDocument.close(); createDict = iframeDocument.F; while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; return createDict(); }; module.exports = Object.create || function create(O, Properties) { var result; if (O !== null) { Empty[PROTOTYPE] = anObject(O); result = new Empty(); Empty[PROTOTYPE] = null; // add "__proto__" for Object.getPrototypeOf polyfill result[IE_PROTO] = O; } else result = createDict(); return Properties === undefined ? result : dPs(result, Properties); }; },{"102":102,"30":30,"31":31,"43":43,"7":7,"73":73}],72:[function(_dereq_,module,exports){ var anObject = _dereq_(7); var IE8_DOM_DEFINE = _dereq_(44); var toPrimitive = _dereq_(120); var dP = Object.defineProperty; exports.f = _dereq_(29) ? Object.defineProperty : function defineProperty(O, P, Attributes) { anObject(O); P = toPrimitive(P, true); anObject(Attributes); if (IE8_DOM_DEFINE) try { return dP(O, P, Attributes); } catch (e) { /* empty */ } if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); if ('value' in Attributes) O[P] = Attributes.value; return O; }; },{"120":120,"29":29,"44":44,"7":7}],73:[function(_dereq_,module,exports){ var dP = _dereq_(72); var anObject = _dereq_(7); var getKeys = _dereq_(81); module.exports = _dereq_(29) ? Object.defineProperties : function defineProperties(O, Properties) { anObject(O); var keys = getKeys(Properties); var length = keys.length; var i = 0; var P; while (length > i) dP.f(O, P = keys[i++], Properties[P]); return O; }; },{"29":29,"7":7,"72":72,"81":81}],74:[function(_dereq_,module,exports){ 'use strict'; // Forced replacement prototype accessors methods module.exports = _dereq_(60) || !_dereq_(35)(function () { var K = Math.random(); // In FF throws only define methods // eslint-disable-next-line no-undef, no-useless-call __defineSetter__.call(null, K, function () { /* empty */ }); delete _dereq_(40)[K]; }); },{"35":35,"40":40,"60":60}],75:[function(_dereq_,module,exports){ var pIE = _dereq_(82); var createDesc = _dereq_(92); var toIObject = _dereq_(117); var toPrimitive = _dereq_(120); var has = _dereq_(41); var IE8_DOM_DEFINE = _dereq_(44); var gOPD = Object.getOwnPropertyDescriptor; exports.f = _dereq_(29) ? gOPD : function getOwnPropertyDescriptor(O, P) { O = toIObject(O); P = toPrimitive(P, true); if (IE8_DOM_DEFINE) try { return gOPD(O, P); } catch (e) { /* empty */ } if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]); }; },{"117":117,"120":120,"29":29,"41":41,"44":44,"82":82,"92":92}],76:[function(_dereq_,module,exports){ // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window var toIObject = _dereq_(117); var gOPN = _dereq_(77).f; var toString = {}.toString; var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : []; var getWindowNames = function (it) { try { return gOPN(it); } catch (e) { return windowNames.slice(); } }; module.exports.f = function getOwnPropertyNames(it) { return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it)); }; },{"117":117,"77":77}],77:[function(_dereq_,module,exports){ // 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) var $keys = _dereq_(80); var hiddenKeys = _dereq_(31).concat('length', 'prototype'); exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { return $keys(O, hiddenKeys); }; },{"31":31,"80":80}],78:[function(_dereq_,module,exports){ exports.f = Object.getOwnPropertySymbols; },{}],79:[function(_dereq_,module,exports){ // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) var has = _dereq_(41); var toObject = _dereq_(119); var IE_PROTO = _dereq_(102)('IE_PROTO'); var ObjectProto = Object.prototype; module.exports = Object.getPrototypeOf || function (O) { O = toObject(O); if (has(O, IE_PROTO)) return O[IE_PROTO]; if (typeof O.constructor == 'function' && O instanceof O.constructor) { return O.constructor.prototype; } return O instanceof Object ? ObjectProto : null; }; },{"102":102,"119":119,"41":41}],80:[function(_dereq_,module,exports){ var has = _dereq_(41); var toIObject = _dereq_(117); var arrayIndexOf = _dereq_(11)(false); var IE_PROTO = _dereq_(102)('IE_PROTO'); module.exports = function (object, names) { var O = toIObject(object); var i = 0; var result = []; var key; for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); // Don't enum bug & hidden keys while (names.length > i) if (has(O, key = names[i++])) { ~arrayIndexOf(result, key) || result.push(key); } return result; }; },{"102":102,"11":11,"117":117,"41":41}],81:[function(_dereq_,module,exports){ // 19.1.2.14 / 15.2.3.14 Object.keys(O) var $keys = _dereq_(80); var enumBugKeys = _dereq_(31); module.exports = Object.keys || function keys(O) { return $keys(O, enumBugKeys); }; },{"31":31,"80":80}],82:[function(_dereq_,module,exports){ exports.f = {}.propertyIsEnumerable; },{}],83:[function(_dereq_,module,exports){ // most Object methods by ES6 should accept primitives var $export = _dereq_(33); var core = _dereq_(23); var fails = _dereq_(35); module.exports = function (KEY, exec) { var fn = (core.Object || {})[KEY] || Object[KEY]; var exp = {}; exp[KEY] = exec(fn); $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp); }; },{"23":23,"33":33,"35":35}],84:[function(_dereq_,module,exports){ var getKeys = _dereq_(81); var toIObject = _dereq_(117); var isEnum = _dereq_(82).f; module.exports = function (isEntries) { return function (it) { var O = toIObject(it); var keys = getKeys(O); var length = keys.length; var i = 0; var result = []; var key; while (length > i) if (isEnum.call(O, key = keys[i++])) { result.push(isEntries ? [key, O[key]] : O[key]); } return result; }; }; },{"117":117,"81":81,"82":82}],85:[function(_dereq_,module,exports){ // all object keys, includes non-enumerable and symbols var gOPN = _dereq_(77); var gOPS = _dereq_(78); var anObject = _dereq_(7); var Reflect = _dereq_(40).Reflect; module.exports = Reflect && Reflect.ownKeys || function ownKeys(it) { var keys = gOPN.f(anObject(it)); var getSymbols = gOPS.f; return getSymbols ? keys.concat(getSymbols(it)) : keys; }; },{"40":40,"7":7,"77":77,"78":78}],86:[function(_dereq_,module,exports){ var $parseFloat = _dereq_(40).parseFloat; var $trim = _dereq_(111).trim; module.exports = 1 / $parseFloat(_dereq_(112) + '-0') !== -Infinity ? function parseFloat(str) { var string = $trim(String(str), 3); var result = $parseFloat(string); return result === 0 && string.charAt(0) == '-' ? -0 : result; } : $parseFloat; },{"111":111,"112":112,"40":40}],87:[function(_dereq_,module,exports){ var $parseInt = _dereq_(40).parseInt; var $trim = _dereq_(111).trim; var ws = _dereq_(112); var hex = /^[-+]?0[xX]/; module.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) { var string = $trim(String(str), 3); return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10)); } : $parseInt; },{"111":111,"112":112,"40":40}],88:[function(_dereq_,module,exports){ 'use strict'; var path = _dereq_(89); var invoke = _dereq_(46); var aFunction = _dereq_(3); module.exports = function (/* ...pargs */) { var fn = aFunction(this); var length = arguments.length; var pargs = Array(length); var i = 0; var _ = path._; var holder = false; while (length > i) if ((pargs[i] = arguments[i++]) === _) holder = true; return function (/* ...args */) { var that = this; var aLen = arguments.length; var j = 0; var k = 0; var args; if (!holder && !aLen) return invoke(fn, pargs, that); args = pargs.slice(); if (holder) for (;length > j; j++) if (args[j] === _) args[j] = arguments[k++]; while (aLen > k) args.push(arguments[k++]); return invoke(fn, args, that); }; }; },{"3":3,"46":46,"89":89}],89:[function(_dereq_,module,exports){ module.exports = _dereq_(40); },{"40":40}],90:[function(_dereq_,module,exports){ module.exports = function (exec) { try { return { e: false, v: exec() }; } catch (e) { return { e: true, v: e }; } }; },{}],91:[function(_dereq_,module,exports){ var newPromiseCapability = _dereq_(69); module.exports = function (C, x) { var promiseCapability = newPromiseCapability.f(C); var resolve = promiseCapability.resolve; resolve(x); return promiseCapability.promise; }; },{"69":69}],92:[function(_dereq_,module,exports){ module.exports = function (bitmap, value) { return { enumerable: !(bitmap & 1), configurable: !(bitmap & 2), writable: !(bitmap & 4), value: value }; }; },{}],93:[function(_dereq_,module,exports){ var redefine = _dereq_(94); module.exports = function (target, src, safe) { for (var key in src) redefine(target, key, src[key], safe); return target; }; },{"94":94}],94:[function(_dereq_,module,exports){ var global = _dereq_(40); var hide = _dereq_(42); var has = _dereq_(41); var SRC = _dereq_(124)('src'); var TO_STRING = 'toString'; var $toString = Function[TO_STRING]; var TPL = ('' + $toString).split(TO_STRING); _dereq_(23).inspectSource = function (it) { return $toString.call(it); }; (module.exports = function (O, key, val, safe) { var isFunction = typeof val == 'function'; if (isFunction) has(val, 'name') || hide(val, 'name', key); if (O[key] === val) return; if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); if (O === global) { O[key] = val; } else if (!safe) { delete O[key]; hide(O, key, val); } else if (O[key]) { O[key] = val; } else { hide(O, key, val); } // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative })(Function.prototype, TO_STRING, function toString() { return typeof this == 'function' && this[SRC] || $toString.call(this); }); },{"124":124,"23":23,"40":40,"41":41,"42":42}],95:[function(_dereq_,module,exports){ module.exports = function (regExp, replace) { var replacer = replace === Object(replace) ? function (part) { return replace[part]; } : replace; return function (it) { return String(it).replace(regExp, replacer); }; }; },{}],96:[function(_dereq_,module,exports){ // 7.2.9 SameValue(x, y) module.exports = Object.is || function is(x, y) { // eslint-disable-next-line no-self-compare return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; }; },{}],97:[function(_dereq_,module,exports){ 'use strict'; // https://tc39.github.io/proposal-setmap-offrom/ var $export = _dereq_(33); var aFunction = _dereq_(3); var ctx = _dereq_(25); var forOf = _dereq_(39); module.exports = function (COLLECTION) { $export($export.S, COLLECTION, { from: function from(source /* , mapFn, thisArg */) { var mapFn = arguments[1]; var mapping, A, n, cb; aFunction(this); mapping = mapFn !== undefined; if (mapping) aFunction(mapFn); if (source == undefined) return new this(); A = []; if (mapping) { n = 0; cb = ctx(mapFn, arguments[2], 2); forOf(source, false, function (nextItem) { A.push(cb(nextItem, n++)); }); } else { forOf(source, false, A.push, A); } return new this(A); } }); }; },{"25":25,"3":3,"33":33,"39":39}],98:[function(_dereq_,module,exports){ 'use strict'; // https://tc39.github.io/proposal-setmap-offrom/ var $export = _dereq_(33); module.exports = function (COLLECTION) { $export($export.S, COLLECTION, { of: function of() { var length = arguments.length; var A = Array(length); while (length--) A[length] = arguments[length]; return new this(A); } }); }; },{"33":33}],99:[function(_dereq_,module,exports){ // Works with __proto__ only. Old v8 can't work with null proto objects. /* eslint-disable no-proto */ var isObject = _dereq_(51); var anObject = _dereq_(7); var check = function (O, proto) { anObject(O); if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!"); }; module.exports = { set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line function (test, buggy, set) { try { set = _dereq_(25)(Function.call, _dereq_(75).f(Object.prototype, '__proto__').set, 2); set(test, []); buggy = !(test instanceof Array); } catch (e) { buggy = true; } return function setPrototypeOf(O, proto) { check(O, proto); if (buggy) O.__proto__ = proto; else set(O, proto); return O; }; }({}, false) : undefined), check: check }; },{"25":25,"51":51,"7":7,"75":75}],100:[function(_dereq_,module,exports){ 'use strict'; var global = _dereq_(40); var dP = _dereq_(72); var DESCRIPTORS = _dereq_(29); var SPECIES = _dereq_(128)('species'); module.exports = function (KEY) { var C = global[KEY]; if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { configurable: true, get: function () { return this; } }); }; },{"128":128,"29":29,"40":40,"72":72}],101:[function(_dereq_,module,exports){ var def = _dereq_(72).f; var has = _dereq_(41); var TAG = _dereq_(128)('toStringTag'); module.exports = function (it, tag, stat) { if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); }; },{"128":128,"41":41,"72":72}],102:[function(_dereq_,module,exports){ var shared = _dereq_(103)('keys'); var uid = _dereq_(124); module.exports = function (key) { return shared[key] || (shared[key] = uid(key)); }; },{"103":103,"124":124}],103:[function(_dereq_,module,exports){ var global = _dereq_(40); var SHARED = '__core-js_shared__'; var store = global[SHARED] || (global[SHARED] = {}); module.exports = function (key) { return store[key] || (store[key] = {}); }; },{"40":40}],104:[function(_dereq_,module,exports){ // 7.3.20 SpeciesConstructor(O, defaultConstructor) var anObject = _dereq_(7); var aFunction = _dereq_(3); var SPECIES = _dereq_(128)('species'); module.exports = function (O, D) { var C = anObject(O).constructor; var S; return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); }; },{"128":128,"3":3,"7":7}],105:[function(_dereq_,module,exports){ 'use strict'; var fails = _dereq_(35); module.exports = function (method, arg) { return !!method && fails(function () { // eslint-disable-next-line no-useless-call arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null); }); }; },{"35":35}],106:[function(_dereq_,module,exports){ var toInteger = _dereq_(116); var defined = _dereq_(28); // true -> String#at // false -> String#codePointAt module.exports = function (TO_STRING) { return function (that, pos) { var s = String(defined(that)); var i = toInteger(pos); var l = s.length; var a, b; if (i < 0 || i >= l) return TO_STRING ? '' : undefined; a = s.charCodeAt(i); return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; }; }; },{"116":116,"28":28}],107:[function(_dereq_,module,exports){ // helper for String#{startsWith, endsWith, includes} var isRegExp = _dereq_(52); var defined = _dereq_(28); module.exports = function (that, searchString, NAME) { if (isRegExp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!"); return String(defined(that)); }; },{"28":28,"52":52}],108:[function(_dereq_,module,exports){ var $export = _dereq_(33); var fails = _dereq_(35); var defined = _dereq_(28); var quot = /"/g; // B.2.3.2.1 CreateHTML(string, tag, attribute, value) var createHTML = function (string, tag, attribute, value) { var S = String(defined(string)); var p1 = '<' + tag; if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '"') + '"'; return p1 + '>' + S + ''; }; module.exports = function (NAME, exec) { var O = {}; O[NAME] = exec(createHTML); $export($export.P + $export.F * fails(function () { var test = ''[NAME]('"'); return test !== test.toLowerCase() || test.split('"').length > 3; }), 'String', O); }; },{"28":28,"33":33,"35":35}],109:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-string-pad-start-end var toLength = _dereq_(118); var repeat = _dereq_(110); var defined = _dereq_(28); module.exports = function (that, maxLength, fillString, left) { var S = String(defined(that)); var stringLength = S.length; var fillStr = fillString === undefined ? ' ' : String(fillString); var intMaxLength = toLength(maxLength); if (intMaxLength <= stringLength || fillStr == '') return S; var fillLen = intMaxLength - stringLength; var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length)); if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen); return left ? stringFiller + S : S + stringFiller; }; },{"110":110,"118":118,"28":28}],110:[function(_dereq_,module,exports){ 'use strict'; var toInteger = _dereq_(116); var defined = _dereq_(28); module.exports = function repeat(count) { var str = String(defined(this)); var res = ''; var n = toInteger(count); if (n < 0 || n == Infinity) throw RangeError("Count can't be negative"); for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str; return res; }; },{"116":116,"28":28}],111:[function(_dereq_,module,exports){ var $export = _dereq_(33); var defined = _dereq_(28); var fails = _dereq_(35); var spaces = _dereq_(112); var space = '[' + spaces + ']'; var non = '\u200b\u0085'; var ltrim = RegExp('^' + space + space + '*'); var rtrim = RegExp(space + space + '*$'); var exporter = function (KEY, exec, ALIAS) { var exp = {}; var FORCE = fails(function () { return !!spaces[KEY]() || non[KEY]() != non; }); var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY]; if (ALIAS) exp[ALIAS] = fn; $export($export.P + $export.F * FORCE, 'String', exp); }; // 1 -> String#trimLeft // 2 -> String#trimRight // 3 -> String#trim var trim = exporter.trim = function (string, TYPE) { string = String(defined(string)); if (TYPE & 1) string = string.replace(ltrim, ''); if (TYPE & 2) string = string.replace(rtrim, ''); return string; }; module.exports = exporter; },{"112":112,"28":28,"33":33,"35":35}],112:[function(_dereq_,module,exports){ module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; },{}],113:[function(_dereq_,module,exports){ var ctx = _dereq_(25); var invoke = _dereq_(46); var html = _dereq_(43); var cel = _dereq_(30); var global = _dereq_(40); var process = global.process; var setTask = global.setImmediate; var clearTask = global.clearImmediate; var MessageChannel = global.MessageChannel; var Dispatch = global.Dispatch; var counter = 0; var queue = {}; var ONREADYSTATECHANGE = 'onreadystatechange'; var defer, channel, port; var run = function () { var id = +this; // eslint-disable-next-line no-prototype-builtins if (queue.hasOwnProperty(id)) { var fn = queue[id]; delete queue[id]; fn(); } }; var listener = function (event) { run.call(event.data); }; // Node.js 0.9+ & IE10+ has setImmediate, otherwise: if (!setTask || !clearTask) { setTask = function setImmediate(fn) { var args = []; var i = 1; while (arguments.length > i) args.push(arguments[i++]); queue[++counter] = function () { // eslint-disable-next-line no-new-func invoke(typeof fn == 'function' ? fn : Function(fn), args); }; defer(counter); return counter; }; clearTask = function clearImmediate(id) { delete queue[id]; }; // Node.js 0.8- if (_dereq_(18)(process) == 'process') { defer = function (id) { process.nextTick(ctx(run, id, 1)); }; // Sphere (JS game engine) Dispatch API } else if (Dispatch && Dispatch.now) { defer = function (id) { Dispatch.now(ctx(run, id, 1)); }; // Browsers with MessageChannel, includes WebWorkers } else if (MessageChannel) { channel = new MessageChannel(); port = channel.port2; channel.port1.onmessage = listener; defer = ctx(port.postMessage, port, 1); // Browsers with postMessage, skip WebWorkers // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { defer = function (id) { global.postMessage(id + '', '*'); }; global.addEventListener('message', listener, false); // IE8- } else if (ONREADYSTATECHANGE in cel('script')) { defer = function (id) { html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { html.removeChild(this); run.call(id); }; }; // Rest old browsers } else { defer = function (id) { setTimeout(ctx(run, id, 1), 0); }; } } module.exports = { set: setTask, clear: clearTask }; },{"18":18,"25":25,"30":30,"40":40,"43":43,"46":46}],114:[function(_dereq_,module,exports){ var toInteger = _dereq_(116); var max = Math.max; var min = Math.min; module.exports = function (index, length) { index = toInteger(index); return index < 0 ? max(index + length, 0) : min(index, length); }; },{"116":116}],115:[function(_dereq_,module,exports){ // https://tc39.github.io/ecma262/#sec-toindex var toInteger = _dereq_(116); var toLength = _dereq_(118); module.exports = function (it) { if (it === undefined) return 0; var number = toInteger(it); var length = toLength(number); if (number !== length) throw RangeError('Wrong length!'); return length; }; },{"116":116,"118":118}],116:[function(_dereq_,module,exports){ // 7.1.4 ToInteger var ceil = Math.ceil; var floor = Math.floor; module.exports = function (it) { return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); }; },{}],117:[function(_dereq_,module,exports){ // to indexed object, toObject with fallback for non-array-like ES3 strings var IObject = _dereq_(47); var defined = _dereq_(28); module.exports = function (it) { return IObject(defined(it)); }; },{"28":28,"47":47}],118:[function(_dereq_,module,exports){ // 7.1.15 ToLength var toInteger = _dereq_(116); var min = Math.min; module.exports = function (it) { return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 }; },{"116":116}],119:[function(_dereq_,module,exports){ // 7.1.13 ToObject(argument) var defined = _dereq_(28); module.exports = function (it) { return Object(defined(it)); }; },{"28":28}],120:[function(_dereq_,module,exports){ // 7.1.1 ToPrimitive(input [, PreferredType]) var isObject = _dereq_(51); // instead of the ES6 spec version, we didn't implement @@toPrimitive case // and the second argument - flag - preferred type is a string module.exports = function (it, S) { if (!isObject(it)) return it; var fn, val; if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; throw TypeError("Can't convert object to primitive value"); }; },{"51":51}],121:[function(_dereq_,module,exports){ 'use strict'; if (_dereq_(29)) { var LIBRARY = _dereq_(60); var global = _dereq_(40); var fails = _dereq_(35); var $export = _dereq_(33); var $typed = _dereq_(123); var $buffer = _dereq_(122); var ctx = _dereq_(25); var anInstance = _dereq_(6); var propertyDesc = _dereq_(92); var hide = _dereq_(42); var redefineAll = _dereq_(93); var toInteger = _dereq_(116); var toLength = _dereq_(118); var toIndex = _dereq_(115); var toAbsoluteIndex = _dereq_(114); var toPrimitive = _dereq_(120); var has = _dereq_(41); var classof = _dereq_(17); var isObject = _dereq_(51); var toObject = _dereq_(119); var isArrayIter = _dereq_(48); var create = _dereq_(71); var getPrototypeOf = _dereq_(79); var gOPN = _dereq_(77).f; var getIterFn = _dereq_(129); var uid = _dereq_(124); var wks = _dereq_(128); var createArrayMethod = _dereq_(12); var createArrayIncludes = _dereq_(11); var speciesConstructor = _dereq_(104); var ArrayIterators = _dereq_(141); var Iterators = _dereq_(58); var $iterDetect = _dereq_(56); var setSpecies = _dereq_(100); var arrayFill = _dereq_(9); var arrayCopyWithin = _dereq_(8); var $DP = _dereq_(72); var $GOPD = _dereq_(75); var dP = $DP.f; var gOPD = $GOPD.f; var RangeError = global.RangeError; var TypeError = global.TypeError; var Uint8Array = global.Uint8Array; var ARRAY_BUFFER = 'ArrayBuffer'; var SHARED_BUFFER = 'Shared' + ARRAY_BUFFER; var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT'; var PROTOTYPE = 'prototype'; var ArrayProto = Array[PROTOTYPE]; var $ArrayBuffer = $buffer.ArrayBuffer; var $DataView = $buffer.DataView; var arrayForEach = createArrayMethod(0); var arrayFilter = createArrayMethod(2); var arraySome = createArrayMethod(3); var arrayEvery = createArrayMethod(4); var arrayFind = createArrayMethod(5); var arrayFindIndex = createArrayMethod(6); var arrayIncludes = createArrayIncludes(true); var arrayIndexOf = createArrayIncludes(false); var arrayValues = ArrayIterators.values; var arrayKeys = ArrayIterators.keys; var arrayEntries = ArrayIterators.entries; var arrayLastIndexOf = ArrayProto.lastIndexOf; var arrayReduce = ArrayProto.reduce; var arrayReduceRight = ArrayProto.reduceRight; var arrayJoin = ArrayProto.join; var arraySort = ArrayProto.sort; var arraySlice = ArrayProto.slice; var arrayToString = ArrayProto.toString; var arrayToLocaleString = ArrayProto.toLocaleString; var ITERATOR = wks('iterator'); var TAG = wks('toStringTag'); var TYPED_CONSTRUCTOR = uid('typed_constructor'); var DEF_CONSTRUCTOR = uid('def_constructor'); var ALL_CONSTRUCTORS = $typed.CONSTR; var TYPED_ARRAY = $typed.TYPED; var VIEW = $typed.VIEW; var WRONG_LENGTH = 'Wrong length!'; var $map = createArrayMethod(1, function (O, length) { return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length); }); var LITTLE_ENDIAN = fails(function () { // eslint-disable-next-line no-undef return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1; }); var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function () { new Uint8Array(1).set({}); }); var toOffset = function (it, BYTES) { var offset = toInteger(it); if (offset < 0 || offset % BYTES) throw RangeError('Wrong offset!'); return offset; }; var validate = function (it) { if (isObject(it) && TYPED_ARRAY in it) return it; throw TypeError(it + ' is not a typed array!'); }; var allocate = function (C, length) { if (!(isObject(C) && TYPED_CONSTRUCTOR in C)) { throw TypeError('It is not a typed array constructor!'); } return new C(length); }; var speciesFromList = function (O, list) { return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list); }; var fromList = function (C, list) { var index = 0; var length = list.length; var result = allocate(C, length); while (length > index) result[index] = list[index++]; return result; }; var addGetter = function (it, key, internal) { dP(it, key, { get: function () { return this._d[internal]; } }); }; var $from = function from(source /* , mapfn, thisArg */) { var O = toObject(source); var aLen = arguments.length; var mapfn = aLen > 1 ? arguments[1] : undefined; var mapping = mapfn !== undefined; var iterFn = getIterFn(O); var i, length, values, result, step, iterator; if (iterFn != undefined && !isArrayIter(iterFn)) { for (iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++) { values.push(step.value); } O = values; } if (mapping && aLen > 2) mapfn = ctx(mapfn, arguments[2], 2); for (i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++) { result[i] = mapping ? mapfn(O[i], i) : O[i]; } return result; }; var $of = function of(/* ...items */) { var index = 0; var length = arguments.length; var result = allocate(this, length); while (length > index) result[index] = arguments[index++]; return result; }; // iOS Safari 6.x fails here var TO_LOCALE_BUG = !!Uint8Array && fails(function () { arrayToLocaleString.call(new Uint8Array(1)); }); var $toLocaleString = function toLocaleString() { return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments); }; var proto = { copyWithin: function copyWithin(target, start /* , end */) { return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined); }, every: function every(callbackfn /* , thisArg */) { return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined); }, fill: function fill(value /* , start, end */) { // eslint-disable-line no-unused-vars return arrayFill.apply(validate(this), arguments); }, filter: function filter(callbackfn /* , thisArg */) { return speciesFromList(this, arrayFilter(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined)); }, find: function find(predicate /* , thisArg */) { return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined); }, findIndex: function findIndex(predicate /* , thisArg */) { return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined); }, forEach: function forEach(callbackfn /* , thisArg */) { arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined); }, indexOf: function indexOf(searchElement /* , fromIndex */) { return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined); }, includes: function includes(searchElement /* , fromIndex */) { return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined); }, join: function join(separator) { // eslint-disable-line no-unused-vars return arrayJoin.apply(validate(this), arguments); }, lastIndexOf: function lastIndexOf(searchElement /* , fromIndex */) { // eslint-disable-line no-unused-vars return arrayLastIndexOf.apply(validate(this), arguments); }, map: function map(mapfn /* , thisArg */) { return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined); }, reduce: function reduce(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars return arrayReduce.apply(validate(this), arguments); }, reduceRight: function reduceRight(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars return arrayReduceRight.apply(validate(this), arguments); }, reverse: function reverse() { var that = this; var length = validate(that).length; var middle = Math.floor(length / 2); var index = 0; var value; while (index < middle) { value = that[index]; that[index++] = that[--length]; that[length] = value; } return that; }, some: function some(callbackfn /* , thisArg */) { return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined); }, sort: function sort(comparefn) { return arraySort.call(validate(this), comparefn); }, subarray: function subarray(begin, end) { var O = validate(this); var length = O.length; var $begin = toAbsoluteIndex(begin, length); return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))( O.buffer, O.byteOffset + $begin * O.BYTES_PER_ELEMENT, toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - $begin) ); } }; var $slice = function slice(start, end) { return speciesFromList(this, arraySlice.call(validate(this), start, end)); }; var $set = function set(arrayLike /* , offset */) { validate(this); var offset = toOffset(arguments[1], 1); var length = this.length; var src = toObject(arrayLike); var len = toLength(src.length); var index = 0; if (len + offset > length) throw RangeError(WRONG_LENGTH); while (index < len) this[offset + index] = src[index++]; }; var $iterators = { entries: function entries() { return arrayEntries.call(validate(this)); }, keys: function keys() { return arrayKeys.call(validate(this)); }, values: function values() { return arrayValues.call(validate(this)); } }; var isTAIndex = function (target, key) { return isObject(target) && target[TYPED_ARRAY] && typeof key != 'symbol' && key in target && String(+key) == String(key); }; var $getDesc = function getOwnPropertyDescriptor(target, key) { return isTAIndex(target, key = toPrimitive(key, true)) ? propertyDesc(2, target[key]) : gOPD(target, key); }; var $setDesc = function defineProperty(target, key, desc) { if (isTAIndex(target, key = toPrimitive(key, true)) && isObject(desc) && has(desc, 'value') && !has(desc, 'get') && !has(desc, 'set') // TODO: add validation descriptor w/o calling accessors && !desc.configurable && (!has(desc, 'writable') || desc.writable) && (!has(desc, 'enumerable') || desc.enumerable) ) { target[key] = desc.value; return target; } return dP(target, key, desc); }; if (!ALL_CONSTRUCTORS) { $GOPD.f = $getDesc; $DP.f = $setDesc; } $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', { getOwnPropertyDescriptor: $getDesc, defineProperty: $setDesc }); if (fails(function () { arrayToString.call({}); })) { arrayToString = arrayToLocaleString = function toString() { return arrayJoin.call(this); }; } var $TypedArrayPrototype$ = redefineAll({}, proto); redefineAll($TypedArrayPrototype$, $iterators); hide($TypedArrayPrototype$, ITERATOR, $iterators.values); redefineAll($TypedArrayPrototype$, { slice: $slice, set: $set, constructor: function () { /* noop */ }, toString: arrayToString, toLocaleString: $toLocaleString }); addGetter($TypedArrayPrototype$, 'buffer', 'b'); addGetter($TypedArrayPrototype$, 'byteOffset', 'o'); addGetter($TypedArrayPrototype$, 'byteLength', 'l'); addGetter($TypedArrayPrototype$, 'length', 'e'); dP($TypedArrayPrototype$, TAG, { get: function () { return this[TYPED_ARRAY]; } }); // eslint-disable-next-line max-statements module.exports = function (KEY, BYTES, wrapper, CLAMPED) { CLAMPED = !!CLAMPED; var NAME = KEY + (CLAMPED ? 'Clamped' : '') + 'Array'; var GETTER = 'get' + KEY; var SETTER = 'set' + KEY; var TypedArray = global[NAME]; var Base = TypedArray || {}; var TAC = TypedArray && getPrototypeOf(TypedArray); var FORCED = !TypedArray || !$typed.ABV; var O = {}; var TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE]; var getter = function (that, index) { var data = that._d; return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN); }; var setter = function (that, index, value) { var data = that._d; if (CLAMPED) value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff; data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN); }; var addElement = function (that, index) { dP(that, index, { get: function () { return getter(this, index); }, set: function (value) { return setter(this, index, value); }, enumerable: true }); }; if (FORCED) { TypedArray = wrapper(function (that, data, $offset, $length) { anInstance(that, TypedArray, NAME, '_d'); var index = 0; var offset = 0; var buffer, byteLength, length, klass; if (!isObject(data)) { length = toIndex(data); byteLength = length * BYTES; buffer = new $ArrayBuffer(byteLength); } else if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) { buffer = data; offset = toOffset($offset, BYTES); var $len = data.byteLength; if ($length === undefined) { if ($len % BYTES) throw RangeError(WRONG_LENGTH); byteLength = $len - offset; if (byteLength < 0) throw RangeError(WRONG_LENGTH); } else { byteLength = toLength($length) * BYTES; if (byteLength + offset > $len) throw RangeError(WRONG_LENGTH); } length = byteLength / BYTES; } else if (TYPED_ARRAY in data) { return fromList(TypedArray, data); } else { return $from.call(TypedArray, data); } hide(that, '_d', { b: buffer, o: offset, l: byteLength, e: length, v: new $DataView(buffer) }); while (index < length) addElement(that, index++); }); TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$); hide(TypedArrayPrototype, 'constructor', TypedArray); } else if (!fails(function () { TypedArray(1); }) || !fails(function () { new TypedArray(-1); // eslint-disable-line no-new }) || !$iterDetect(function (iter) { new TypedArray(); // eslint-disable-line no-new new TypedArray(null); // eslint-disable-line no-new new TypedArray(1.5); // eslint-disable-line no-new new TypedArray(iter); // eslint-disable-line no-new }, true)) { TypedArray = wrapper(function (that, data, $offset, $length) { anInstance(that, TypedArray, NAME); var klass; // `ws` module bug, temporarily remove validation length for Uint8Array // https://github.com/websockets/ws/pull/645 if (!isObject(data)) return new Base(toIndex(data)); if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) { return $length !== undefined ? new Base(data, toOffset($offset, BYTES), $length) : $offset !== undefined ? new Base(data, toOffset($offset, BYTES)) : new Base(data); } if (TYPED_ARRAY in data) return fromList(TypedArray, data); return $from.call(TypedArray, data); }); arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function (key) { if (!(key in TypedArray)) hide(TypedArray, key, Base[key]); }); TypedArray[PROTOTYPE] = TypedArrayPrototype; if (!LIBRARY) TypedArrayPrototype.constructor = TypedArray; } var $nativeIterator = TypedArrayPrototype[ITERATOR]; var CORRECT_ITER_NAME = !!$nativeIterator && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined); var $iterator = $iterators.values; hide(TypedArray, TYPED_CONSTRUCTOR, true); hide(TypedArrayPrototype, TYPED_ARRAY, NAME); hide(TypedArrayPrototype, VIEW, true); hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray); if (CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)) { dP(TypedArrayPrototype, TAG, { get: function () { return NAME; } }); } O[NAME] = TypedArray; $export($export.G + $export.W + $export.F * (TypedArray != Base), O); $export($export.S, NAME, { BYTES_PER_ELEMENT: BYTES }); $export($export.S + $export.F * fails(function () { Base.of.call(TypedArray, 1); }), NAME, { from: $from, of: $of }); if (!(BYTES_PER_ELEMENT in TypedArrayPrototype)) hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES); $export($export.P, NAME, proto); setSpecies(NAME); $export($export.P + $export.F * FORCED_SET, NAME, { set: $set }); $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators); if (!LIBRARY && TypedArrayPrototype.toString != arrayToString) TypedArrayPrototype.toString = arrayToString; $export($export.P + $export.F * fails(function () { new TypedArray(1).slice(); }), NAME, { slice: $slice }); $export($export.P + $export.F * (fails(function () { return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString(); }) || !fails(function () { TypedArrayPrototype.toLocaleString.call([1, 2]); })), NAME, { toLocaleString: $toLocaleString }); Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator; if (!LIBRARY && !CORRECT_ITER_NAME) hide(TypedArrayPrototype, ITERATOR, $iterator); }; } else module.exports = function () { /* empty */ }; },{"100":100,"104":104,"11":11,"114":114,"115":115,"116":116,"118":118,"119":119,"12":12,"120":120,"122":122,"123":123,"124":124,"128":128,"129":129,"141":141,"17":17,"25":25,"29":29,"33":33,"35":35,"40":40,"41":41,"42":42,"48":48,"51":51,"56":56,"58":58,"6":6,"60":60,"71":71,"72":72,"75":75,"77":77,"79":79,"8":8,"9":9,"92":92,"93":93}],122:[function(_dereq_,module,exports){ 'use strict'; var global = _dereq_(40); var DESCRIPTORS = _dereq_(29); var LIBRARY = _dereq_(60); var $typed = _dereq_(123); var hide = _dereq_(42); var redefineAll = _dereq_(93); var fails = _dereq_(35); var anInstance = _dereq_(6); var toInteger = _dereq_(116); var toLength = _dereq_(118); var toIndex = _dereq_(115); var gOPN = _dereq_(77).f; var dP = _dereq_(72).f; var arrayFill = _dereq_(9); var setToStringTag = _dereq_(101); var ARRAY_BUFFER = 'ArrayBuffer'; var DATA_VIEW = 'DataView'; var PROTOTYPE = 'prototype'; var WRONG_LENGTH = 'Wrong length!'; var WRONG_INDEX = 'Wrong index!'; var $ArrayBuffer = global[ARRAY_BUFFER]; var $DataView = global[DATA_VIEW]; var Math = global.Math; var RangeError = global.RangeError; // eslint-disable-next-line no-shadow-restricted-names var Infinity = global.Infinity; var BaseBuffer = $ArrayBuffer; var abs = Math.abs; var pow = Math.pow; var floor = Math.floor; var log = Math.log; var LN2 = Math.LN2; var BUFFER = 'buffer'; var BYTE_LENGTH = 'byteLength'; var BYTE_OFFSET = 'byteOffset'; var $BUFFER = DESCRIPTORS ? '_b' : BUFFER; var $LENGTH = DESCRIPTORS ? '_l' : BYTE_LENGTH; var $OFFSET = DESCRIPTORS ? '_o' : BYTE_OFFSET; // IEEE754 conversions based on https://github.com/feross/ieee754 function packIEEE754(value, mLen, nBytes) { var buffer = Array(nBytes); var eLen = nBytes * 8 - mLen - 1; var eMax = (1 << eLen) - 1; var eBias = eMax >> 1; var rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0; var i = 0; var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; var e, m, c; value = abs(value); // eslint-disable-next-line no-self-compare if (value != value || value === Infinity) { // eslint-disable-next-line no-self-compare m = value != value ? 1 : 0; e = eMax; } else { e = floor(log(value) / LN2); if (value * (c = pow(2, -e)) < 1) { e--; c *= 2; } if (e + eBias >= 1) { value += rt / c; } else { value += rt * pow(2, 1 - eBias); } if (value * c >= 2) { e++; c /= 2; } if (e + eBias >= eMax) { m = 0; e = eMax; } else if (e + eBias >= 1) { m = (value * c - 1) * pow(2, mLen); e = e + eBias; } else { m = value * pow(2, eBias - 1) * pow(2, mLen); e = 0; } } for (; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8); e = e << mLen | m; eLen += mLen; for (; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8); buffer[--i] |= s * 128; return buffer; } function unpackIEEE754(buffer, mLen, nBytes) { var eLen = nBytes * 8 - mLen - 1; var eMax = (1 << eLen) - 1; var eBias = eMax >> 1; var nBits = eLen - 7; var i = nBytes - 1; var s = buffer[i--]; var e = s & 127; var m; s >>= 7; for (; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8); m = e & (1 << -nBits) - 1; e >>= -nBits; nBits += mLen; for (; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8); if (e === 0) { e = 1 - eBias; } else if (e === eMax) { return m ? NaN : s ? -Infinity : Infinity; } else { m = m + pow(2, mLen); e = e - eBias; } return (s ? -1 : 1) * m * pow(2, e - mLen); } function unpackI32(bytes) { return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0]; } function packI8(it) { return [it & 0xff]; } function packI16(it) { return [it & 0xff, it >> 8 & 0xff]; } function packI32(it) { return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff]; } function packF64(it) { return packIEEE754(it, 52, 8); } function packF32(it) { return packIEEE754(it, 23, 4); } function addGetter(C, key, internal) { dP(C[PROTOTYPE], key, { get: function () { return this[internal]; } }); } function get(view, bytes, index, isLittleEndian) { var numIndex = +index; var intIndex = toIndex(numIndex); if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX); var store = view[$BUFFER]._b; var start = intIndex + view[$OFFSET]; var pack = store.slice(start, start + bytes); return isLittleEndian ? pack : pack.reverse(); } function set(view, bytes, index, conversion, value, isLittleEndian) { var numIndex = +index; var intIndex = toIndex(numIndex); if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX); var store = view[$BUFFER]._b; var start = intIndex + view[$OFFSET]; var pack = conversion(+value); for (var i = 0; i < bytes; i++) store[start + i] = pack[isLittleEndian ? i : bytes - i - 1]; } if (!$typed.ABV) { $ArrayBuffer = function ArrayBuffer(length) { anInstance(this, $ArrayBuffer, ARRAY_BUFFER); var byteLength = toIndex(length); this._b = arrayFill.call(Array(byteLength), 0); this[$LENGTH] = byteLength; }; $DataView = function DataView(buffer, byteOffset, byteLength) { anInstance(this, $DataView, DATA_VIEW); anInstance(buffer, $ArrayBuffer, DATA_VIEW); var bufferLength = buffer[$LENGTH]; var offset = toInteger(byteOffset); if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset!'); byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength); if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH); this[$BUFFER] = buffer; this[$OFFSET] = offset; this[$LENGTH] = byteLength; }; if (DESCRIPTORS) { addGetter($ArrayBuffer, BYTE_LENGTH, '_l'); addGetter($DataView, BUFFER, '_b'); addGetter($DataView, BYTE_LENGTH, '_l'); addGetter($DataView, BYTE_OFFSET, '_o'); } redefineAll($DataView[PROTOTYPE], { getInt8: function getInt8(byteOffset) { return get(this, 1, byteOffset)[0] << 24 >> 24; }, getUint8: function getUint8(byteOffset) { return get(this, 1, byteOffset)[0]; }, getInt16: function getInt16(byteOffset /* , littleEndian */) { var bytes = get(this, 2, byteOffset, arguments[1]); return (bytes[1] << 8 | bytes[0]) << 16 >> 16; }, getUint16: function getUint16(byteOffset /* , littleEndian */) { var bytes = get(this, 2, byteOffset, arguments[1]); return bytes[1] << 8 | bytes[0]; }, getInt32: function getInt32(byteOffset /* , littleEndian */) { return unpackI32(get(this, 4, byteOffset, arguments[1])); }, getUint32: function getUint32(byteOffset /* , littleEndian */) { return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0; }, getFloat32: function getFloat32(byteOffset /* , littleEndian */) { return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4); }, getFloat64: function getFloat64(byteOffset /* , littleEndian */) { return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8); }, setInt8: function setInt8(byteOffset, value) { set(this, 1, byteOffset, packI8, value); }, setUint8: function setUint8(byteOffset, value) { set(this, 1, byteOffset, packI8, value); }, setInt16: function setInt16(byteOffset, value /* , littleEndian */) { set(this, 2, byteOffset, packI16, value, arguments[2]); }, setUint16: function setUint16(byteOffset, value /* , littleEndian */) { set(this, 2, byteOffset, packI16, value, arguments[2]); }, setInt32: function setInt32(byteOffset, value /* , littleEndian */) { set(this, 4, byteOffset, packI32, value, arguments[2]); }, setUint32: function setUint32(byteOffset, value /* , littleEndian */) { set(this, 4, byteOffset, packI32, value, arguments[2]); }, setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) { set(this, 4, byteOffset, packF32, value, arguments[2]); }, setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) { set(this, 8, byteOffset, packF64, value, arguments[2]); } }); } else { if (!fails(function () { $ArrayBuffer(1); }) || !fails(function () { new $ArrayBuffer(-1); // eslint-disable-line no-new }) || fails(function () { new $ArrayBuffer(); // eslint-disable-line no-new new $ArrayBuffer(1.5); // eslint-disable-line no-new new $ArrayBuffer(NaN); // eslint-disable-line no-new return $ArrayBuffer.name != ARRAY_BUFFER; })) { $ArrayBuffer = function ArrayBuffer(length) { anInstance(this, $ArrayBuffer); return new BaseBuffer(toIndex(length)); }; var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE]; for (var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j;) { if (!((key = keys[j++]) in $ArrayBuffer)) hide($ArrayBuffer, key, BaseBuffer[key]); } if (!LIBRARY) ArrayBufferProto.constructor = $ArrayBuffer; } // iOS Safari 7.x bug var view = new $DataView(new $ArrayBuffer(2)); var $setInt8 = $DataView[PROTOTYPE].setInt8; view.setInt8(0, 2147483648); view.setInt8(1, 2147483649); if (view.getInt8(0) || !view.getInt8(1)) redefineAll($DataView[PROTOTYPE], { setInt8: function setInt8(byteOffset, value) { $setInt8.call(this, byteOffset, value << 24 >> 24); }, setUint8: function setUint8(byteOffset, value) { $setInt8.call(this, byteOffset, value << 24 >> 24); } }, true); } setToStringTag($ArrayBuffer, ARRAY_BUFFER); setToStringTag($DataView, DATA_VIEW); hide($DataView[PROTOTYPE], $typed.VIEW, true); exports[ARRAY_BUFFER] = $ArrayBuffer; exports[DATA_VIEW] = $DataView; },{"101":101,"115":115,"116":116,"118":118,"123":123,"29":29,"35":35,"40":40,"42":42,"6":6,"60":60,"72":72,"77":77,"9":9,"93":93}],123:[function(_dereq_,module,exports){ var global = _dereq_(40); var hide = _dereq_(42); var uid = _dereq_(124); var TYPED = uid('typed_array'); var VIEW = uid('view'); var ABV = !!(global.ArrayBuffer && global.DataView); var CONSTR = ABV; var i = 0; var l = 9; var Typed; var TypedArrayConstructors = ( 'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array' ).split(','); while (i < l) { if (Typed = global[TypedArrayConstructors[i++]]) { hide(Typed.prototype, TYPED, true); hide(Typed.prototype, VIEW, true); } else CONSTR = false; } module.exports = { ABV: ABV, CONSTR: CONSTR, TYPED: TYPED, VIEW: VIEW }; },{"124":124,"40":40,"42":42}],124:[function(_dereq_,module,exports){ var id = 0; var px = Math.random(); module.exports = function (key) { return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); }; },{}],125:[function(_dereq_,module,exports){ var isObject = _dereq_(51); module.exports = function (it, TYPE) { if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!'); return it; }; },{"51":51}],126:[function(_dereq_,module,exports){ var global = _dereq_(40); var core = _dereq_(23); var LIBRARY = _dereq_(60); var wksExt = _dereq_(127); var defineProperty = _dereq_(72).f; module.exports = function (name) { var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) }); }; },{"127":127,"23":23,"40":40,"60":60,"72":72}],127:[function(_dereq_,module,exports){ exports.f = _dereq_(128); },{"128":128}],128:[function(_dereq_,module,exports){ var store = _dereq_(103)('wks'); var uid = _dereq_(124); var Symbol = _dereq_(40).Symbol; var USE_SYMBOL = typeof Symbol == 'function'; var $exports = module.exports = function (name) { return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); }; $exports.store = store; },{"103":103,"124":124,"40":40}],129:[function(_dereq_,module,exports){ var classof = _dereq_(17); var ITERATOR = _dereq_(128)('iterator'); var Iterators = _dereq_(58); module.exports = _dereq_(23).getIteratorMethod = function (it) { if (it != undefined) return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)]; }; },{"128":128,"17":17,"23":23,"58":58}],130:[function(_dereq_,module,exports){ // https://github.com/benjamingr/RexExp.escape var $export = _dereq_(33); var $re = _dereq_(95)(/[\\^$*+?.()|[\]{}]/g, '\\$&'); $export($export.S, 'RegExp', { escape: function escape(it) { return $re(it); } }); },{"33":33,"95":95}],131:[function(_dereq_,module,exports){ // 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length) var $export = _dereq_(33); $export($export.P, 'Array', { copyWithin: _dereq_(8) }); _dereq_(5)('copyWithin'); },{"33":33,"5":5,"8":8}],132:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $every = _dereq_(12)(4); $export($export.P + $export.F * !_dereq_(105)([].every, true), 'Array', { // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg]) every: function every(callbackfn /* , thisArg */) { return $every(this, callbackfn, arguments[1]); } }); },{"105":105,"12":12,"33":33}],133:[function(_dereq_,module,exports){ // 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length) var $export = _dereq_(33); $export($export.P, 'Array', { fill: _dereq_(9) }); _dereq_(5)('fill'); },{"33":33,"5":5,"9":9}],134:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $filter = _dereq_(12)(2); $export($export.P + $export.F * !_dereq_(105)([].filter, true), 'Array', { // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg]) filter: function filter(callbackfn /* , thisArg */) { return $filter(this, callbackfn, arguments[1]); } }); },{"105":105,"12":12,"33":33}],135:[function(_dereq_,module,exports){ 'use strict'; // 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined) var $export = _dereq_(33); var $find = _dereq_(12)(6); var KEY = 'findIndex'; var forced = true; // Shouldn't skip holes if (KEY in []) Array(1)[KEY](function () { forced = false; }); $export($export.P + $export.F * forced, 'Array', { findIndex: function findIndex(callbackfn /* , that = undefined */) { return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); _dereq_(5)(KEY); },{"12":12,"33":33,"5":5}],136:[function(_dereq_,module,exports){ 'use strict'; // 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined) var $export = _dereq_(33); var $find = _dereq_(12)(5); var KEY = 'find'; var forced = true; // Shouldn't skip holes if (KEY in []) Array(1)[KEY](function () { forced = false; }); $export($export.P + $export.F * forced, 'Array', { find: function find(callbackfn /* , that = undefined */) { return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); _dereq_(5)(KEY); },{"12":12,"33":33,"5":5}],137:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $forEach = _dereq_(12)(0); var STRICT = _dereq_(105)([].forEach, true); $export($export.P + $export.F * !STRICT, 'Array', { // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg]) forEach: function forEach(callbackfn /* , thisArg */) { return $forEach(this, callbackfn, arguments[1]); } }); },{"105":105,"12":12,"33":33}],138:[function(_dereq_,module,exports){ 'use strict'; var ctx = _dereq_(25); var $export = _dereq_(33); var toObject = _dereq_(119); var call = _dereq_(53); var isArrayIter = _dereq_(48); var toLength = _dereq_(118); var createProperty = _dereq_(24); var getIterFn = _dereq_(129); $export($export.S + $export.F * !_dereq_(56)(function (iter) { Array.from(iter); }), 'Array', { // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { var O = toObject(arrayLike); var C = typeof this == 'function' ? this : Array; var aLen = arguments.length; var mapfn = aLen > 1 ? arguments[1] : undefined; var mapping = mapfn !== undefined; var index = 0; var iterFn = getIterFn(O); var length, result, step, iterator; if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); // if object isn't iterable or it's array with default iterator - use simple case if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) { for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) { createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); } } else { length = toLength(O.length); for (result = new C(length); length > index; index++) { createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); } } result.length = index; return result; } }); },{"118":118,"119":119,"129":129,"24":24,"25":25,"33":33,"48":48,"53":53,"56":56}],139:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $indexOf = _dereq_(11)(false); var $native = [].indexOf; var NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0; $export($export.P + $export.F * (NEGATIVE_ZERO || !_dereq_(105)($native)), 'Array', { // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex]) indexOf: function indexOf(searchElement /* , fromIndex = 0 */) { return NEGATIVE_ZERO // convert -0 to +0 ? $native.apply(this, arguments) || 0 : $indexOf(this, searchElement, arguments[1]); } }); },{"105":105,"11":11,"33":33}],140:[function(_dereq_,module,exports){ // 22.1.2.2 / 15.4.3.2 Array.isArray(arg) var $export = _dereq_(33); $export($export.S, 'Array', { isArray: _dereq_(49) }); },{"33":33,"49":49}],141:[function(_dereq_,module,exports){ 'use strict'; var addToUnscopables = _dereq_(5); var step = _dereq_(57); var Iterators = _dereq_(58); var toIObject = _dereq_(117); // 22.1.3.4 Array.prototype.entries() // 22.1.3.13 Array.prototype.keys() // 22.1.3.29 Array.prototype.values() // 22.1.3.30 Array.prototype[@@iterator]() module.exports = _dereq_(55)(Array, 'Array', function (iterated, kind) { this._t = toIObject(iterated); // target this._i = 0; // next index this._k = kind; // kind // 22.1.5.2.1 %ArrayIteratorPrototype%.next() }, function () { var O = this._t; var kind = this._k; var index = this._i++; if (!O || index >= O.length) { this._t = undefined; return step(1); } if (kind == 'keys') return step(0, index); if (kind == 'values') return step(0, O[index]); return step(0, [index, O[index]]); }, 'values'); // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) Iterators.Arguments = Iterators.Array; addToUnscopables('keys'); addToUnscopables('values'); addToUnscopables('entries'); },{"117":117,"5":5,"55":55,"57":57,"58":58}],142:[function(_dereq_,module,exports){ 'use strict'; // 22.1.3.13 Array.prototype.join(separator) var $export = _dereq_(33); var toIObject = _dereq_(117); var arrayJoin = [].join; // fallback for not array-like strings $export($export.P + $export.F * (_dereq_(47) != Object || !_dereq_(105)(arrayJoin)), 'Array', { join: function join(separator) { return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator); } }); },{"105":105,"117":117,"33":33,"47":47}],143:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toIObject = _dereq_(117); var toInteger = _dereq_(116); var toLength = _dereq_(118); var $native = [].lastIndexOf; var NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0; $export($export.P + $export.F * (NEGATIVE_ZERO || !_dereq_(105)($native)), 'Array', { // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex]) lastIndexOf: function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) { // convert -0 to +0 if (NEGATIVE_ZERO) return $native.apply(this, arguments) || 0; var O = toIObject(this); var length = toLength(O.length); var index = length - 1; if (arguments.length > 1) index = Math.min(index, toInteger(arguments[1])); if (index < 0) index = length + index; for (;index >= 0; index--) if (index in O) if (O[index] === searchElement) return index || 0; return -1; } }); },{"105":105,"116":116,"117":117,"118":118,"33":33}],144:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $map = _dereq_(12)(1); $export($export.P + $export.F * !_dereq_(105)([].map, true), 'Array', { // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg]) map: function map(callbackfn /* , thisArg */) { return $map(this, callbackfn, arguments[1]); } }); },{"105":105,"12":12,"33":33}],145:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var createProperty = _dereq_(24); // WebKit Array.of isn't generic $export($export.S + $export.F * _dereq_(35)(function () { function F() { /* empty */ } return !(Array.of.call(F) instanceof F); }), 'Array', { // 22.1.2.3 Array.of( ...items) of: function of(/* ...args */) { var index = 0; var aLen = arguments.length; var result = new (typeof this == 'function' ? this : Array)(aLen); while (aLen > index) createProperty(result, index, arguments[index++]); result.length = aLen; return result; } }); },{"24":24,"33":33,"35":35}],146:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $reduce = _dereq_(13); $export($export.P + $export.F * !_dereq_(105)([].reduceRight, true), 'Array', { // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue]) reduceRight: function reduceRight(callbackfn /* , initialValue */) { return $reduce(this, callbackfn, arguments.length, arguments[1], true); } }); },{"105":105,"13":13,"33":33}],147:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $reduce = _dereq_(13); $export($export.P + $export.F * !_dereq_(105)([].reduce, true), 'Array', { // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue]) reduce: function reduce(callbackfn /* , initialValue */) { return $reduce(this, callbackfn, arguments.length, arguments[1], false); } }); },{"105":105,"13":13,"33":33}],148:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var html = _dereq_(43); var cof = _dereq_(18); var toAbsoluteIndex = _dereq_(114); var toLength = _dereq_(118); var arraySlice = [].slice; // fallback for not array-like ES3 strings and DOM objects $export($export.P + $export.F * _dereq_(35)(function () { if (html) arraySlice.call(html); }), 'Array', { slice: function slice(begin, end) { var len = toLength(this.length); var klass = cof(this); end = end === undefined ? len : end; if (klass == 'Array') return arraySlice.call(this, begin, end); var start = toAbsoluteIndex(begin, len); var upTo = toAbsoluteIndex(end, len); var size = toLength(upTo - start); var cloned = Array(size); var i = 0; for (; i < size; i++) cloned[i] = klass == 'String' ? this.charAt(start + i) : this[start + i]; return cloned; } }); },{"114":114,"118":118,"18":18,"33":33,"35":35,"43":43}],149:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $some = _dereq_(12)(3); $export($export.P + $export.F * !_dereq_(105)([].some, true), 'Array', { // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg]) some: function some(callbackfn /* , thisArg */) { return $some(this, callbackfn, arguments[1]); } }); },{"105":105,"12":12,"33":33}],150:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var aFunction = _dereq_(3); var toObject = _dereq_(119); var fails = _dereq_(35); var $sort = [].sort; var test = [1, 2, 3]; $export($export.P + $export.F * (fails(function () { // IE8- test.sort(undefined); }) || !fails(function () { // V8 bug test.sort(null); // Old WebKit }) || !_dereq_(105)($sort)), 'Array', { // 22.1.3.25 Array.prototype.sort(comparefn) sort: function sort(comparefn) { return comparefn === undefined ? $sort.call(toObject(this)) : $sort.call(toObject(this), aFunction(comparefn)); } }); },{"105":105,"119":119,"3":3,"33":33,"35":35}],151:[function(_dereq_,module,exports){ _dereq_(100)('Array'); },{"100":100}],152:[function(_dereq_,module,exports){ // 20.3.3.1 / 15.9.4.4 Date.now() var $export = _dereq_(33); $export($export.S, 'Date', { now: function () { return new Date().getTime(); } }); },{"33":33}],153:[function(_dereq_,module,exports){ // 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString() var $export = _dereq_(33); var toISOString = _dereq_(26); // PhantomJS / old WebKit has a broken implementations $export($export.P + $export.F * (Date.prototype.toISOString !== toISOString), 'Date', { toISOString: toISOString }); },{"26":26,"33":33}],154:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toObject = _dereq_(119); var toPrimitive = _dereq_(120); $export($export.P + $export.F * _dereq_(35)(function () { return new Date(NaN).toJSON() !== null || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1; }), 'Date', { // eslint-disable-next-line no-unused-vars toJSON: function toJSON(key) { var O = toObject(this); var pv = toPrimitive(O); return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString(); } }); },{"119":119,"120":120,"33":33,"35":35}],155:[function(_dereq_,module,exports){ var TO_PRIMITIVE = _dereq_(128)('toPrimitive'); var proto = Date.prototype; if (!(TO_PRIMITIVE in proto)) _dereq_(42)(proto, TO_PRIMITIVE, _dereq_(27)); },{"128":128,"27":27,"42":42}],156:[function(_dereq_,module,exports){ var DateProto = Date.prototype; var INVALID_DATE = 'Invalid Date'; var TO_STRING = 'toString'; var $toString = DateProto[TO_STRING]; var getTime = DateProto.getTime; if (new Date(NaN) + '' != INVALID_DATE) { _dereq_(94)(DateProto, TO_STRING, function toString() { var value = getTime.call(this); // eslint-disable-next-line no-self-compare return value === value ? $toString.call(this) : INVALID_DATE; }); } },{"94":94}],157:[function(_dereq_,module,exports){ // 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...) var $export = _dereq_(33); $export($export.P, 'Function', { bind: _dereq_(16) }); },{"16":16,"33":33}],158:[function(_dereq_,module,exports){ 'use strict'; var isObject = _dereq_(51); var getPrototypeOf = _dereq_(79); var HAS_INSTANCE = _dereq_(128)('hasInstance'); var FunctionProto = Function.prototype; // 19.2.3.6 Function.prototype[@@hasInstance](V) if (!(HAS_INSTANCE in FunctionProto)) _dereq_(72).f(FunctionProto, HAS_INSTANCE, { value: function (O) { if (typeof this != 'function' || !isObject(O)) return false; if (!isObject(this.prototype)) return O instanceof this; // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this: while (O = getPrototypeOf(O)) if (this.prototype === O) return true; return false; } }); },{"128":128,"51":51,"72":72,"79":79}],159:[function(_dereq_,module,exports){ var dP = _dereq_(72).f; var FProto = Function.prototype; var nameRE = /^\s*function ([^ (]*)/; var NAME = 'name'; // 19.2.4.2 name NAME in FProto || _dereq_(29) && dP(FProto, NAME, { configurable: true, get: function () { try { return ('' + this).match(nameRE)[1]; } catch (e) { return ''; } } }); },{"29":29,"72":72}],160:[function(_dereq_,module,exports){ 'use strict'; var strong = _dereq_(19); var validate = _dereq_(125); var MAP = 'Map'; // 23.1 Map Objects module.exports = _dereq_(22)(MAP, function (get) { return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; }, { // 23.1.3.6 Map.prototype.get(key) get: function get(key) { var entry = strong.getEntry(validate(this, MAP), key); return entry && entry.v; }, // 23.1.3.9 Map.prototype.set(key, value) set: function set(key, value) { return strong.def(validate(this, MAP), key === 0 ? 0 : key, value); } }, strong, true); },{"125":125,"19":19,"22":22}],161:[function(_dereq_,module,exports){ // 20.2.2.3 Math.acosh(x) var $export = _dereq_(33); var log1p = _dereq_(63); var sqrt = Math.sqrt; var $acosh = Math.acosh; $export($export.S + $export.F * !($acosh // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509 && Math.floor($acosh(Number.MAX_VALUE)) == 710 // Tor Browser bug: Math.acosh(Infinity) -> NaN && $acosh(Infinity) == Infinity ), 'Math', { acosh: function acosh(x) { return (x = +x) < 1 ? NaN : x > 94906265.62425156 ? Math.log(x) + Math.LN2 : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1)); } }); },{"33":33,"63":63}],162:[function(_dereq_,module,exports){ // 20.2.2.5 Math.asinh(x) var $export = _dereq_(33); var $asinh = Math.asinh; function asinh(x) { return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1)); } // Tor Browser bug: Math.asinh(0) -> -0 $export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', { asinh: asinh }); },{"33":33}],163:[function(_dereq_,module,exports){ // 20.2.2.7 Math.atanh(x) var $export = _dereq_(33); var $atanh = Math.atanh; // Tor Browser bug: Math.atanh(-0) -> 0 $export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', { atanh: function atanh(x) { return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2; } }); },{"33":33}],164:[function(_dereq_,module,exports){ // 20.2.2.9 Math.cbrt(x) var $export = _dereq_(33); var sign = _dereq_(65); $export($export.S, 'Math', { cbrt: function cbrt(x) { return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3); } }); },{"33":33,"65":65}],165:[function(_dereq_,module,exports){ // 20.2.2.11 Math.clz32(x) var $export = _dereq_(33); $export($export.S, 'Math', { clz32: function clz32(x) { return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32; } }); },{"33":33}],166:[function(_dereq_,module,exports){ // 20.2.2.12 Math.cosh(x) var $export = _dereq_(33); var exp = Math.exp; $export($export.S, 'Math', { cosh: function cosh(x) { return (exp(x = +x) + exp(-x)) / 2; } }); },{"33":33}],167:[function(_dereq_,module,exports){ // 20.2.2.14 Math.expm1(x) var $export = _dereq_(33); var $expm1 = _dereq_(61); $export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', { expm1: $expm1 }); },{"33":33,"61":61}],168:[function(_dereq_,module,exports){ // 20.2.2.16 Math.fround(x) var $export = _dereq_(33); $export($export.S, 'Math', { fround: _dereq_(62) }); },{"33":33,"62":62}],169:[function(_dereq_,module,exports){ // 20.2.2.17 Math.hypot([value1[, value2[, … ]]]) var $export = _dereq_(33); var abs = Math.abs; $export($export.S, 'Math', { hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars var sum = 0; var i = 0; var aLen = arguments.length; var larg = 0; var arg, div; while (i < aLen) { arg = abs(arguments[i++]); if (larg < arg) { div = larg / arg; sum = sum * div * div + 1; larg = arg; } else if (arg > 0) { div = arg / larg; sum += div * div; } else sum += arg; } return larg === Infinity ? Infinity : larg * Math.sqrt(sum); } }); },{"33":33}],170:[function(_dereq_,module,exports){ // 20.2.2.18 Math.imul(x, y) var $export = _dereq_(33); var $imul = Math.imul; // some WebKit versions fails with big numbers, some has wrong arity $export($export.S + $export.F * _dereq_(35)(function () { return $imul(0xffffffff, 5) != -5 || $imul.length != 2; }), 'Math', { imul: function imul(x, y) { var UINT16 = 0xffff; var xn = +x; var yn = +y; var xl = UINT16 & xn; var yl = UINT16 & yn; return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0); } }); },{"33":33,"35":35}],171:[function(_dereq_,module,exports){ // 20.2.2.21 Math.log10(x) var $export = _dereq_(33); $export($export.S, 'Math', { log10: function log10(x) { return Math.log(x) * Math.LOG10E; } }); },{"33":33}],172:[function(_dereq_,module,exports){ // 20.2.2.20 Math.log1p(x) var $export = _dereq_(33); $export($export.S, 'Math', { log1p: _dereq_(63) }); },{"33":33,"63":63}],173:[function(_dereq_,module,exports){ // 20.2.2.22 Math.log2(x) var $export = _dereq_(33); $export($export.S, 'Math', { log2: function log2(x) { return Math.log(x) / Math.LN2; } }); },{"33":33}],174:[function(_dereq_,module,exports){ // 20.2.2.28 Math.sign(x) var $export = _dereq_(33); $export($export.S, 'Math', { sign: _dereq_(65) }); },{"33":33,"65":65}],175:[function(_dereq_,module,exports){ // 20.2.2.30 Math.sinh(x) var $export = _dereq_(33); var expm1 = _dereq_(61); var exp = Math.exp; // V8 near Chromium 38 has a problem with very small numbers $export($export.S + $export.F * _dereq_(35)(function () { return !Math.sinh(-2e-17) != -2e-17; }), 'Math', { sinh: function sinh(x) { return Math.abs(x = +x) < 1 ? (expm1(x) - expm1(-x)) / 2 : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2); } }); },{"33":33,"35":35,"61":61}],176:[function(_dereq_,module,exports){ // 20.2.2.33 Math.tanh(x) var $export = _dereq_(33); var expm1 = _dereq_(61); var exp = Math.exp; $export($export.S, 'Math', { tanh: function tanh(x) { var a = expm1(x = +x); var b = expm1(-x); return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x)); } }); },{"33":33,"61":61}],177:[function(_dereq_,module,exports){ // 20.2.2.34 Math.trunc(x) var $export = _dereq_(33); $export($export.S, 'Math', { trunc: function trunc(it) { return (it > 0 ? Math.floor : Math.ceil)(it); } }); },{"33":33}],178:[function(_dereq_,module,exports){ 'use strict'; var global = _dereq_(40); var has = _dereq_(41); var cof = _dereq_(18); var inheritIfRequired = _dereq_(45); var toPrimitive = _dereq_(120); var fails = _dereq_(35); var gOPN = _dereq_(77).f; var gOPD = _dereq_(75).f; var dP = _dereq_(72).f; var $trim = _dereq_(111).trim; var NUMBER = 'Number'; var $Number = global[NUMBER]; var Base = $Number; var proto = $Number.prototype; // Opera ~12 has broken Object#toString var BROKEN_COF = cof(_dereq_(71)(proto)) == NUMBER; var TRIM = 'trim' in String.prototype; // 7.1.3 ToNumber(argument) var toNumber = function (argument) { var it = toPrimitive(argument, false); if (typeof it == 'string' && it.length > 2) { it = TRIM ? it.trim() : $trim(it, 3); var first = it.charCodeAt(0); var third, radix, maxCode; if (first === 43 || first === 45) { third = it.charCodeAt(2); if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix } else if (first === 48) { switch (it.charCodeAt(1)) { case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i default: return +it; } for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) { code = digits.charCodeAt(i); // parseInt parses a string to a first unavailable symbol // but ToNumber should return NaN if a string contains unavailable symbols if (code < 48 || code > maxCode) return NaN; } return parseInt(digits, radix); } } return +it; }; if (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) { $Number = function Number(value) { var it = arguments.length < 1 ? 0 : value; var that = this; return that instanceof $Number // check on 1..constructor(foo) case && (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER) ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it); }; for (var keys = _dereq_(29) ? gOPN(Base) : ( // ES3: 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + // ES6 (in case, if modules with ES6 Number statics required before): 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' + 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger' ).split(','), j = 0, key; keys.length > j; j++) { if (has(Base, key = keys[j]) && !has($Number, key)) { dP($Number, key, gOPD(Base, key)); } } $Number.prototype = proto; proto.constructor = $Number; _dereq_(94)(global, NUMBER, $Number); } },{"111":111,"120":120,"18":18,"29":29,"35":35,"40":40,"41":41,"45":45,"71":71,"72":72,"75":75,"77":77,"94":94}],179:[function(_dereq_,module,exports){ // 20.1.2.1 Number.EPSILON var $export = _dereq_(33); $export($export.S, 'Number', { EPSILON: Math.pow(2, -52) }); },{"33":33}],180:[function(_dereq_,module,exports){ // 20.1.2.2 Number.isFinite(number) var $export = _dereq_(33); var _isFinite = _dereq_(40).isFinite; $export($export.S, 'Number', { isFinite: function isFinite(it) { return typeof it == 'number' && _isFinite(it); } }); },{"33":33,"40":40}],181:[function(_dereq_,module,exports){ // 20.1.2.3 Number.isInteger(number) var $export = _dereq_(33); $export($export.S, 'Number', { isInteger: _dereq_(50) }); },{"33":33,"50":50}],182:[function(_dereq_,module,exports){ // 20.1.2.4 Number.isNaN(number) var $export = _dereq_(33); $export($export.S, 'Number', { isNaN: function isNaN(number) { // eslint-disable-next-line no-self-compare return number != number; } }); },{"33":33}],183:[function(_dereq_,module,exports){ // 20.1.2.5 Number.isSafeInteger(number) var $export = _dereq_(33); var isInteger = _dereq_(50); var abs = Math.abs; $export($export.S, 'Number', { isSafeInteger: function isSafeInteger(number) { return isInteger(number) && abs(number) <= 0x1fffffffffffff; } }); },{"33":33,"50":50}],184:[function(_dereq_,module,exports){ // 20.1.2.6 Number.MAX_SAFE_INTEGER var $export = _dereq_(33); $export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff }); },{"33":33}],185:[function(_dereq_,module,exports){ // 20.1.2.10 Number.MIN_SAFE_INTEGER var $export = _dereq_(33); $export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff }); },{"33":33}],186:[function(_dereq_,module,exports){ var $export = _dereq_(33); var $parseFloat = _dereq_(86); // 20.1.2.12 Number.parseFloat(string) $export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', { parseFloat: $parseFloat }); },{"33":33,"86":86}],187:[function(_dereq_,module,exports){ var $export = _dereq_(33); var $parseInt = _dereq_(87); // 20.1.2.13 Number.parseInt(string, radix) $export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', { parseInt: $parseInt }); },{"33":33,"87":87}],188:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toInteger = _dereq_(116); var aNumberValue = _dereq_(4); var repeat = _dereq_(110); var $toFixed = 1.0.toFixed; var floor = Math.floor; var data = [0, 0, 0, 0, 0, 0]; var ERROR = 'Number.toFixed: incorrect invocation!'; var ZERO = '0'; var multiply = function (n, c) { var i = -1; var c2 = c; while (++i < 6) { c2 += n * data[i]; data[i] = c2 % 1e7; c2 = floor(c2 / 1e7); } }; var divide = function (n) { var i = 6; var c = 0; while (--i >= 0) { c += data[i]; data[i] = floor(c / n); c = (c % n) * 1e7; } }; var numToString = function () { var i = 6; var s = ''; while (--i >= 0) { if (s !== '' || i === 0 || data[i] !== 0) { var t = String(data[i]); s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t; } } return s; }; var pow = function (x, n, acc) { return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc); }; var log = function (x) { var n = 0; var x2 = x; while (x2 >= 4096) { n += 12; x2 /= 4096; } while (x2 >= 2) { n += 1; x2 /= 2; } return n; }; $export($export.P + $export.F * (!!$toFixed && ( 0.00008.toFixed(3) !== '0.000' || 0.9.toFixed(0) !== '1' || 1.255.toFixed(2) !== '1.25' || 1000000000000000128.0.toFixed(0) !== '1000000000000000128' ) || !_dereq_(35)(function () { // V8 ~ Android 4.3- $toFixed.call({}); })), 'Number', { toFixed: function toFixed(fractionDigits) { var x = aNumberValue(this, ERROR); var f = toInteger(fractionDigits); var s = ''; var m = ZERO; var e, z, j, k; if (f < 0 || f > 20) throw RangeError(ERROR); // eslint-disable-next-line no-self-compare if (x != x) return 'NaN'; if (x <= -1e21 || x >= 1e21) return String(x); if (x < 0) { s = '-'; x = -x; } if (x > 1e-21) { e = log(x * pow(2, 69, 1)) - 69; z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1); z *= 0x10000000000000; e = 52 - e; if (e > 0) { multiply(0, z); j = f; while (j >= 7) { multiply(1e7, 0); j -= 7; } multiply(pow(10, j, 1), 0); j = e - 1; while (j >= 23) { divide(1 << 23); j -= 23; } divide(1 << j); multiply(1, 1); divide(2); m = numToString(); } else { multiply(0, z); multiply(1 << -e, 0); m = numToString() + repeat.call(ZERO, f); } } if (f > 0) { k = m.length; m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f)); } else { m = s + m; } return m; } }); },{"110":110,"116":116,"33":33,"35":35,"4":4}],189:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $fails = _dereq_(35); var aNumberValue = _dereq_(4); var $toPrecision = 1.0.toPrecision; $export($export.P + $export.F * ($fails(function () { // IE7- return $toPrecision.call(1, undefined) !== '1'; }) || !$fails(function () { // V8 ~ Android 4.3- $toPrecision.call({}); })), 'Number', { toPrecision: function toPrecision(precision) { var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!'); return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision); } }); },{"33":33,"35":35,"4":4}],190:[function(_dereq_,module,exports){ // 19.1.3.1 Object.assign(target, source) var $export = _dereq_(33); $export($export.S + $export.F, 'Object', { assign: _dereq_(70) }); },{"33":33,"70":70}],191:[function(_dereq_,module,exports){ var $export = _dereq_(33); // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) $export($export.S, 'Object', { create: _dereq_(71) }); },{"33":33,"71":71}],192:[function(_dereq_,module,exports){ var $export = _dereq_(33); // 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties) $export($export.S + $export.F * !_dereq_(29), 'Object', { defineProperties: _dereq_(73) }); },{"29":29,"33":33,"73":73}],193:[function(_dereq_,module,exports){ var $export = _dereq_(33); // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) $export($export.S + $export.F * !_dereq_(29), 'Object', { defineProperty: _dereq_(72).f }); },{"29":29,"33":33,"72":72}],194:[function(_dereq_,module,exports){ // 19.1.2.5 Object.freeze(O) var isObject = _dereq_(51); var meta = _dereq_(66).onFreeze; _dereq_(83)('freeze', function ($freeze) { return function freeze(it) { return $freeze && isObject(it) ? $freeze(meta(it)) : it; }; }); },{"51":51,"66":66,"83":83}],195:[function(_dereq_,module,exports){ // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) var toIObject = _dereq_(117); var $getOwnPropertyDescriptor = _dereq_(75).f; _dereq_(83)('getOwnPropertyDescriptor', function () { return function getOwnPropertyDescriptor(it, key) { return $getOwnPropertyDescriptor(toIObject(it), key); }; }); },{"117":117,"75":75,"83":83}],196:[function(_dereq_,module,exports){ // 19.1.2.7 Object.getOwnPropertyNames(O) _dereq_(83)('getOwnPropertyNames', function () { return _dereq_(76).f; }); },{"76":76,"83":83}],197:[function(_dereq_,module,exports){ // 19.1.2.9 Object.getPrototypeOf(O) var toObject = _dereq_(119); var $getPrototypeOf = _dereq_(79); _dereq_(83)('getPrototypeOf', function () { return function getPrototypeOf(it) { return $getPrototypeOf(toObject(it)); }; }); },{"119":119,"79":79,"83":83}],198:[function(_dereq_,module,exports){ // 19.1.2.11 Object.isExtensible(O) var isObject = _dereq_(51); _dereq_(83)('isExtensible', function ($isExtensible) { return function isExtensible(it) { return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false; }; }); },{"51":51,"83":83}],199:[function(_dereq_,module,exports){ // 19.1.2.12 Object.isFrozen(O) var isObject = _dereq_(51); _dereq_(83)('isFrozen', function ($isFrozen) { return function isFrozen(it) { return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true; }; }); },{"51":51,"83":83}],200:[function(_dereq_,module,exports){ // 19.1.2.13 Object.isSealed(O) var isObject = _dereq_(51); _dereq_(83)('isSealed', function ($isSealed) { return function isSealed(it) { return isObject(it) ? $isSealed ? $isSealed(it) : false : true; }; }); },{"51":51,"83":83}],201:[function(_dereq_,module,exports){ // 19.1.3.10 Object.is(value1, value2) var $export = _dereq_(33); $export($export.S, 'Object', { is: _dereq_(96) }); },{"33":33,"96":96}],202:[function(_dereq_,module,exports){ // 19.1.2.14 Object.keys(O) var toObject = _dereq_(119); var $keys = _dereq_(81); _dereq_(83)('keys', function () { return function keys(it) { return $keys(toObject(it)); }; }); },{"119":119,"81":81,"83":83}],203:[function(_dereq_,module,exports){ // 19.1.2.15 Object.preventExtensions(O) var isObject = _dereq_(51); var meta = _dereq_(66).onFreeze; _dereq_(83)('preventExtensions', function ($preventExtensions) { return function preventExtensions(it) { return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it; }; }); },{"51":51,"66":66,"83":83}],204:[function(_dereq_,module,exports){ // 19.1.2.17 Object.seal(O) var isObject = _dereq_(51); var meta = _dereq_(66).onFreeze; _dereq_(83)('seal', function ($seal) { return function seal(it) { return $seal && isObject(it) ? $seal(meta(it)) : it; }; }); },{"51":51,"66":66,"83":83}],205:[function(_dereq_,module,exports){ // 19.1.3.19 Object.setPrototypeOf(O, proto) var $export = _dereq_(33); $export($export.S, 'Object', { setPrototypeOf: _dereq_(99).set }); },{"33":33,"99":99}],206:[function(_dereq_,module,exports){ 'use strict'; // 19.1.3.6 Object.prototype.toString() var classof = _dereq_(17); var test = {}; test[_dereq_(128)('toStringTag')] = 'z'; if (test + '' != '[object z]') { _dereq_(94)(Object.prototype, 'toString', function toString() { return '[object ' + classof(this) + ']'; }, true); } },{"128":128,"17":17,"94":94}],207:[function(_dereq_,module,exports){ var $export = _dereq_(33); var $parseFloat = _dereq_(86); // 18.2.4 parseFloat(string) $export($export.G + $export.F * (parseFloat != $parseFloat), { parseFloat: $parseFloat }); },{"33":33,"86":86}],208:[function(_dereq_,module,exports){ var $export = _dereq_(33); var $parseInt = _dereq_(87); // 18.2.5 parseInt(string, radix) $export($export.G + $export.F * (parseInt != $parseInt), { parseInt: $parseInt }); },{"33":33,"87":87}],209:[function(_dereq_,module,exports){ 'use strict'; var LIBRARY = _dereq_(60); var global = _dereq_(40); var ctx = _dereq_(25); var classof = _dereq_(17); var $export = _dereq_(33); var isObject = _dereq_(51); var aFunction = _dereq_(3); var anInstance = _dereq_(6); var forOf = _dereq_(39); var speciesConstructor = _dereq_(104); var task = _dereq_(113).set; var microtask = _dereq_(68)(); var newPromiseCapabilityModule = _dereq_(69); var perform = _dereq_(90); var promiseResolve = _dereq_(91); var PROMISE = 'Promise'; var TypeError = global.TypeError; var process = global.process; var $Promise = global[PROMISE]; var isNode = classof(process) == 'process'; var empty = function () { /* empty */ }; var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; var USE_NATIVE = !!function () { try { // correct subclassing with @@species support var promise = $Promise.resolve(1); var FakePromise = (promise.constructor = {})[_dereq_(128)('species')] = function (exec) { exec(empty, empty); }; // unhandled rejections tracking support, NodeJS Promise without it fails @@species test return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise; } catch (e) { /* empty */ } }(); // helpers var sameConstructor = LIBRARY ? function (a, b) { // with library wrapper special case return a === b || a === $Promise && b === Wrapper; } : function (a, b) { return a === b; }; var isThenable = function (it) { var then; return isObject(it) && typeof (then = it.then) == 'function' ? then : false; }; var notify = function (promise, isReject) { if (promise._n) return; promise._n = true; var chain = promise._c; microtask(function () { var value = promise._v; var ok = promise._s == 1; var i = 0; var run = function (reaction) { var handler = ok ? reaction.ok : reaction.fail; var resolve = reaction.resolve; var reject = reaction.reject; var domain = reaction.domain; var result, then; try { if (handler) { if (!ok) { if (promise._h == 2) onHandleUnhandled(promise); promise._h = 1; } if (handler === true) result = value; else { if (domain) domain.enter(); result = handler(value); if (domain) domain.exit(); } if (result === reaction.promise) { reject(TypeError('Promise-chain cycle')); } else if (then = isThenable(result)) { then.call(result, resolve, reject); } else resolve(result); } else reject(value); } catch (e) { reject(e); } }; while (chain.length > i) run(chain[i++]); // variable length - can't use forEach promise._c = []; promise._n = false; if (isReject && !promise._h) onUnhandled(promise); }); }; var onUnhandled = function (promise) { task.call(global, function () { var value = promise._v; var unhandled = isUnhandled(promise); var result, handler, console; if (unhandled) { result = perform(function () { if (isNode) { process.emit('unhandledRejection', value, promise); } else if (handler = global.onunhandledrejection) { handler({ promise: promise, reason: value }); } else if ((console = global.console) && console.error) { console.error('Unhandled promise rejection', value); } }); // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should promise._h = isNode || isUnhandled(promise) ? 2 : 1; } promise._a = undefined; if (unhandled && result.e) throw result.v; }); }; var isUnhandled = function (promise) { if (promise._h == 1) return false; var chain = promise._a || promise._c; var i = 0; var reaction; while (chain.length > i) { reaction = chain[i++]; if (reaction.fail || !isUnhandled(reaction.promise)) return false; } return true; }; var onHandleUnhandled = function (promise) { task.call(global, function () { var handler; if (isNode) { process.emit('rejectionHandled', promise); } else if (handler = global.onrejectionhandled) { handler({ promise: promise, reason: promise._v }); } }); }; var $reject = function (value) { var promise = this; if (promise._d) return; promise._d = true; promise = promise._w || promise; // unwrap promise._v = value; promise._s = 2; if (!promise._a) promise._a = promise._c.slice(); notify(promise, true); }; var $resolve = function (value) { var promise = this; var then; if (promise._d) return; promise._d = true; promise = promise._w || promise; // unwrap try { if (promise === value) throw TypeError("Promise can't be resolved itself"); if (then = isThenable(value)) { microtask(function () { var wrapper = { _w: promise, _d: false }; // wrap try { then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); } catch (e) { $reject.call(wrapper, e); } }); } else { promise._v = value; promise._s = 1; notify(promise, false); } } catch (e) { $reject.call({ _w: promise, _d: false }, e); // wrap } }; // constructor polyfill if (!USE_NATIVE) { // 25.4.3.1 Promise(executor) $Promise = function Promise(executor) { anInstance(this, $Promise, PROMISE, '_h'); aFunction(executor); Internal.call(this); try { executor(ctx($resolve, this, 1), ctx($reject, this, 1)); } catch (err) { $reject.call(this, err); } }; // eslint-disable-next-line no-unused-vars Internal = function Promise(executor) { this._c = []; // <- awaiting reactions this._a = undefined; // <- checked in isUnhandled reactions this._s = 0; // <- state this._d = false; // <- done this._v = undefined; // <- value this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled this._n = false; // <- notify }; Internal.prototype = _dereq_(93)($Promise.prototype, { // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) then: function then(onFulfilled, onRejected) { var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; reaction.fail = typeof onRejected == 'function' && onRejected; reaction.domain = isNode ? process.domain : undefined; this._c.push(reaction); if (this._a) this._a.push(reaction); if (this._s) notify(this, false); return reaction.promise; }, // 25.4.5.1 Promise.prototype.catch(onRejected) 'catch': function (onRejected) { return this.then(undefined, onRejected); } }); OwnPromiseCapability = function () { var promise = new Internal(); this.promise = promise; this.resolve = ctx($resolve, promise, 1); this.reject = ctx($reject, promise, 1); }; newPromiseCapabilityModule.f = newPromiseCapability = function (C) { return sameConstructor($Promise, C) ? new OwnPromiseCapability(C) : newGenericPromiseCapability(C); }; } $export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise }); _dereq_(101)($Promise, PROMISE); _dereq_(100)(PROMISE); Wrapper = _dereq_(23)[PROMISE]; // statics $export($export.S + $export.F * !USE_NATIVE, PROMISE, { // 25.4.4.5 Promise.reject(r) reject: function reject(r) { var capability = newPromiseCapability(this); var $$reject = capability.reject; $$reject(r); return capability.promise; } }); $export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { // 25.4.4.6 Promise.resolve(x) resolve: function resolve(x) { // instanceof instead of internal slot check because we should fix it without replacement native Promise core if (x instanceof $Promise && sameConstructor(x.constructor, this)) return x; return promiseResolve(this, x); } }); $export($export.S + $export.F * !(USE_NATIVE && _dereq_(56)(function (iter) { $Promise.all(iter)['catch'](empty); })), PROMISE, { // 25.4.4.1 Promise.all(iterable) all: function all(iterable) { var C = this; var capability = newPromiseCapability(C); var resolve = capability.resolve; var reject = capability.reject; var result = perform(function () { var values = []; var index = 0; var remaining = 1; forOf(iterable, false, function (promise) { var $index = index++; var alreadyCalled = false; values.push(undefined); remaining++; C.resolve(promise).then(function (value) { if (alreadyCalled) return; alreadyCalled = true; values[$index] = value; --remaining || resolve(values); }, reject); }); --remaining || resolve(values); }); if (result.e) reject(result.v); return capability.promise; }, // 25.4.4.4 Promise.race(iterable) race: function race(iterable) { var C = this; var capability = newPromiseCapability(C); var reject = capability.reject; var result = perform(function () { forOf(iterable, false, function (promise) { C.resolve(promise).then(capability.resolve, reject); }); }); if (result.e) reject(result.v); return capability.promise; } }); },{"100":100,"101":101,"104":104,"113":113,"128":128,"17":17,"23":23,"25":25,"3":3,"33":33,"39":39,"40":40,"51":51,"56":56,"6":6,"60":60,"68":68,"69":69,"90":90,"91":91,"93":93}],210:[function(_dereq_,module,exports){ // 26.1.1 Reflect.apply(target, thisArgument, argumentsList) var $export = _dereq_(33); var aFunction = _dereq_(3); var anObject = _dereq_(7); var rApply = (_dereq_(40).Reflect || {}).apply; var fApply = Function.apply; // MS Edge argumentsList argument is optional $export($export.S + $export.F * !_dereq_(35)(function () { rApply(function () { /* empty */ }); }), 'Reflect', { apply: function apply(target, thisArgument, argumentsList) { var T = aFunction(target); var L = anObject(argumentsList); return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L); } }); },{"3":3,"33":33,"35":35,"40":40,"7":7}],211:[function(_dereq_,module,exports){ // 26.1.2 Reflect.construct(target, argumentsList [, newTarget]) var $export = _dereq_(33); var create = _dereq_(71); var aFunction = _dereq_(3); var anObject = _dereq_(7); var isObject = _dereq_(51); var fails = _dereq_(35); var bind = _dereq_(16); var rConstruct = (_dereq_(40).Reflect || {}).construct; // MS Edge supports only 2 arguments and argumentsList argument is optional // FF Nightly sets third argument as `new.target`, but does not create `this` from it var NEW_TARGET_BUG = fails(function () { function F() { /* empty */ } return !(rConstruct(function () { /* empty */ }, [], F) instanceof F); }); var ARGS_BUG = !fails(function () { rConstruct(function () { /* empty */ }); }); $export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', { construct: function construct(Target, args /* , newTarget */) { aFunction(Target); anObject(args); var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]); if (ARGS_BUG && !NEW_TARGET_BUG) return rConstruct(Target, args, newTarget); if (Target == newTarget) { // w/o altered newTarget, optimization for 0-4 arguments switch (args.length) { case 0: return new Target(); case 1: return new Target(args[0]); case 2: return new Target(args[0], args[1]); case 3: return new Target(args[0], args[1], args[2]); case 4: return new Target(args[0], args[1], args[2], args[3]); } // w/o altered newTarget, lot of arguments case var $args = [null]; $args.push.apply($args, args); return new (bind.apply(Target, $args))(); } // with altered newTarget, not support built-in constructors var proto = newTarget.prototype; var instance = create(isObject(proto) ? proto : Object.prototype); var result = Function.apply.call(Target, instance, args); return isObject(result) ? result : instance; } }); },{"16":16,"3":3,"33":33,"35":35,"40":40,"51":51,"7":7,"71":71}],212:[function(_dereq_,module,exports){ // 26.1.3 Reflect.defineProperty(target, propertyKey, attributes) var dP = _dereq_(72); var $export = _dereq_(33); var anObject = _dereq_(7); var toPrimitive = _dereq_(120); // MS Edge has broken Reflect.defineProperty - throwing instead of returning false $export($export.S + $export.F * _dereq_(35)(function () { // eslint-disable-next-line no-undef Reflect.defineProperty(dP.f({}, 1, { value: 1 }), 1, { value: 2 }); }), 'Reflect', { defineProperty: function defineProperty(target, propertyKey, attributes) { anObject(target); propertyKey = toPrimitive(propertyKey, true); anObject(attributes); try { dP.f(target, propertyKey, attributes); return true; } catch (e) { return false; } } }); },{"120":120,"33":33,"35":35,"7":7,"72":72}],213:[function(_dereq_,module,exports){ // 26.1.4 Reflect.deleteProperty(target, propertyKey) var $export = _dereq_(33); var gOPD = _dereq_(75).f; var anObject = _dereq_(7); $export($export.S, 'Reflect', { deleteProperty: function deleteProperty(target, propertyKey) { var desc = gOPD(anObject(target), propertyKey); return desc && !desc.configurable ? false : delete target[propertyKey]; } }); },{"33":33,"7":7,"75":75}],214:[function(_dereq_,module,exports){ 'use strict'; // 26.1.5 Reflect.enumerate(target) var $export = _dereq_(33); var anObject = _dereq_(7); var Enumerate = function (iterated) { this._t = anObject(iterated); // target this._i = 0; // next index var keys = this._k = []; // keys var key; for (key in iterated) keys.push(key); }; _dereq_(54)(Enumerate, 'Object', function () { var that = this; var keys = that._k; var key; do { if (that._i >= keys.length) return { value: undefined, done: true }; } while (!((key = keys[that._i++]) in that._t)); return { value: key, done: false }; }); $export($export.S, 'Reflect', { enumerate: function enumerate(target) { return new Enumerate(target); } }); },{"33":33,"54":54,"7":7}],215:[function(_dereq_,module,exports){ // 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey) var gOPD = _dereq_(75); var $export = _dereq_(33); var anObject = _dereq_(7); $export($export.S, 'Reflect', { getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey) { return gOPD.f(anObject(target), propertyKey); } }); },{"33":33,"7":7,"75":75}],216:[function(_dereq_,module,exports){ // 26.1.8 Reflect.getPrototypeOf(target) var $export = _dereq_(33); var getProto = _dereq_(79); var anObject = _dereq_(7); $export($export.S, 'Reflect', { getPrototypeOf: function getPrototypeOf(target) { return getProto(anObject(target)); } }); },{"33":33,"7":7,"79":79}],217:[function(_dereq_,module,exports){ // 26.1.6 Reflect.get(target, propertyKey [, receiver]) var gOPD = _dereq_(75); var getPrototypeOf = _dereq_(79); var has = _dereq_(41); var $export = _dereq_(33); var isObject = _dereq_(51); var anObject = _dereq_(7); function get(target, propertyKey /* , receiver */) { var receiver = arguments.length < 3 ? target : arguments[2]; var desc, proto; if (anObject(target) === receiver) return target[propertyKey]; if (desc = gOPD.f(target, propertyKey)) return has(desc, 'value') ? desc.value : desc.get !== undefined ? desc.get.call(receiver) : undefined; if (isObject(proto = getPrototypeOf(target))) return get(proto, propertyKey, receiver); } $export($export.S, 'Reflect', { get: get }); },{"33":33,"41":41,"51":51,"7":7,"75":75,"79":79}],218:[function(_dereq_,module,exports){ // 26.1.9 Reflect.has(target, propertyKey) var $export = _dereq_(33); $export($export.S, 'Reflect', { has: function has(target, propertyKey) { return propertyKey in target; } }); },{"33":33}],219:[function(_dereq_,module,exports){ // 26.1.10 Reflect.isExtensible(target) var $export = _dereq_(33); var anObject = _dereq_(7); var $isExtensible = Object.isExtensible; $export($export.S, 'Reflect', { isExtensible: function isExtensible(target) { anObject(target); return $isExtensible ? $isExtensible(target) : true; } }); },{"33":33,"7":7}],220:[function(_dereq_,module,exports){ // 26.1.11 Reflect.ownKeys(target) var $export = _dereq_(33); $export($export.S, 'Reflect', { ownKeys: _dereq_(85) }); },{"33":33,"85":85}],221:[function(_dereq_,module,exports){ // 26.1.12 Reflect.preventExtensions(target) var $export = _dereq_(33); var anObject = _dereq_(7); var $preventExtensions = Object.preventExtensions; $export($export.S, 'Reflect', { preventExtensions: function preventExtensions(target) { anObject(target); try { if ($preventExtensions) $preventExtensions(target); return true; } catch (e) { return false; } } }); },{"33":33,"7":7}],222:[function(_dereq_,module,exports){ // 26.1.14 Reflect.setPrototypeOf(target, proto) var $export = _dereq_(33); var setProto = _dereq_(99); if (setProto) $export($export.S, 'Reflect', { setPrototypeOf: function setPrototypeOf(target, proto) { setProto.check(target, proto); try { setProto.set(target, proto); return true; } catch (e) { return false; } } }); },{"33":33,"99":99}],223:[function(_dereq_,module,exports){ // 26.1.13 Reflect.set(target, propertyKey, V [, receiver]) var dP = _dereq_(72); var gOPD = _dereq_(75); var getPrototypeOf = _dereq_(79); var has = _dereq_(41); var $export = _dereq_(33); var createDesc = _dereq_(92); var anObject = _dereq_(7); var isObject = _dereq_(51); function set(target, propertyKey, V /* , receiver */) { var receiver = arguments.length < 4 ? target : arguments[3]; var ownDesc = gOPD.f(anObject(target), propertyKey); var existingDescriptor, proto; if (!ownDesc) { if (isObject(proto = getPrototypeOf(target))) { return set(proto, propertyKey, V, receiver); } ownDesc = createDesc(0); } if (has(ownDesc, 'value')) { if (ownDesc.writable === false || !isObject(receiver)) return false; existingDescriptor = gOPD.f(receiver, propertyKey) || createDesc(0); existingDescriptor.value = V; dP.f(receiver, propertyKey, existingDescriptor); return true; } return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true); } $export($export.S, 'Reflect', { set: set }); },{"33":33,"41":41,"51":51,"7":7,"72":72,"75":75,"79":79,"92":92}],224:[function(_dereq_,module,exports){ var global = _dereq_(40); var inheritIfRequired = _dereq_(45); var dP = _dereq_(72).f; var gOPN = _dereq_(77).f; var isRegExp = _dereq_(52); var $flags = _dereq_(37); var $RegExp = global.RegExp; var Base = $RegExp; var proto = $RegExp.prototype; var re1 = /a/g; var re2 = /a/g; // "new" creates a new object, old webkit buggy here var CORRECT_NEW = new $RegExp(re1) !== re1; if (_dereq_(29) && (!CORRECT_NEW || _dereq_(35)(function () { re2[_dereq_(128)('match')] = false; // RegExp constructor can alter flags and IsRegExp works correct with @@match return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i'; }))) { $RegExp = function RegExp(p, f) { var tiRE = this instanceof $RegExp; var piRE = isRegExp(p); var fiU = f === undefined; return !tiRE && piRE && p.constructor === $RegExp && fiU ? p : inheritIfRequired(CORRECT_NEW ? new Base(piRE && !fiU ? p.source : p, f) : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f) , tiRE ? this : proto, $RegExp); }; var proxy = function (key) { key in $RegExp || dP($RegExp, key, { configurable: true, get: function () { return Base[key]; }, set: function (it) { Base[key] = it; } }); }; for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]); proto.constructor = $RegExp; $RegExp.prototype = proto; _dereq_(94)(global, 'RegExp', $RegExp); } _dereq_(100)('RegExp'); },{"100":100,"128":128,"29":29,"35":35,"37":37,"40":40,"45":45,"52":52,"72":72,"77":77,"94":94}],225:[function(_dereq_,module,exports){ // 21.2.5.3 get RegExp.prototype.flags() if (_dereq_(29) && /./g.flags != 'g') _dereq_(72).f(RegExp.prototype, 'flags', { configurable: true, get: _dereq_(37) }); },{"29":29,"37":37,"72":72}],226:[function(_dereq_,module,exports){ // @@match logic _dereq_(36)('match', 1, function (defined, MATCH, $match) { // 21.1.3.11 String.prototype.match(regexp) return [function match(regexp) { 'use strict'; var O = defined(this); var fn = regexp == undefined ? undefined : regexp[MATCH]; return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O)); }, $match]; }); },{"36":36}],227:[function(_dereq_,module,exports){ // @@replace logic _dereq_(36)('replace', 2, function (defined, REPLACE, $replace) { // 21.1.3.14 String.prototype.replace(searchValue, replaceValue) return [function replace(searchValue, replaceValue) { 'use strict'; var O = defined(this); var fn = searchValue == undefined ? undefined : searchValue[REPLACE]; return fn !== undefined ? fn.call(searchValue, O, replaceValue) : $replace.call(String(O), searchValue, replaceValue); }, $replace]; }); },{"36":36}],228:[function(_dereq_,module,exports){ // @@search logic _dereq_(36)('search', 1, function (defined, SEARCH, $search) { // 21.1.3.15 String.prototype.search(regexp) return [function search(regexp) { 'use strict'; var O = defined(this); var fn = regexp == undefined ? undefined : regexp[SEARCH]; return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O)); }, $search]; }); },{"36":36}],229:[function(_dereq_,module,exports){ // @@split logic _dereq_(36)('split', 2, function (defined, SPLIT, $split) { 'use strict'; var isRegExp = _dereq_(52); var _split = $split; var $push = [].push; var $SPLIT = 'split'; var LENGTH = 'length'; var LAST_INDEX = 'lastIndex'; if ( 'abbc'[$SPLIT](/(b)*/)[1] == 'c' || 'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 || 'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 || '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 || '.'[$SPLIT](/()()/)[LENGTH] > 1 || ''[$SPLIT](/.?/)[LENGTH] ) { var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group // based on es5-shim implementation, need to rework it $split = function (separator, limit) { var string = String(this); if (separator === undefined && limit === 0) return []; // If `separator` is not a regex, use native split if (!isRegExp(separator)) return _split.call(string, separator, limit); var output = []; var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + (separator.sticky ? 'y' : ''); var lastLastIndex = 0; var splitLimit = limit === undefined ? 4294967295 : limit >>> 0; // Make `global` and avoid `lastIndex` issues by working with a copy var separatorCopy = new RegExp(separator.source, flags + 'g'); var separator2, match, lastIndex, lastLength, i; // Doesn't need flags gy, but they don't hurt if (!NPCG) separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); while (match = separatorCopy.exec(string)) { // `separatorCopy.lastIndex` is not reliable cross-browser lastIndex = match.index + match[0][LENGTH]; if (lastIndex > lastLastIndex) { output.push(string.slice(lastLastIndex, match.index)); // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG // eslint-disable-next-line no-loop-func if (!NPCG && match[LENGTH] > 1) match[0].replace(separator2, function () { for (i = 1; i < arguments[LENGTH] - 2; i++) if (arguments[i] === undefined) match[i] = undefined; }); if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1)); lastLength = match[0][LENGTH]; lastLastIndex = lastIndex; if (output[LENGTH] >= splitLimit) break; } if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop } if (lastLastIndex === string[LENGTH]) { if (lastLength || !separatorCopy.test('')) output.push(''); } else output.push(string.slice(lastLastIndex)); return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output; }; // Chakra, V8 } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) { $split = function (separator, limit) { return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit); }; } // 21.1.3.17 String.prototype.split(separator, limit) return [function split(separator, limit) { var O = defined(this); var fn = separator == undefined ? undefined : separator[SPLIT]; return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit); }, $split]; }); },{"36":36,"52":52}],230:[function(_dereq_,module,exports){ 'use strict'; _dereq_(225); var anObject = _dereq_(7); var $flags = _dereq_(37); var DESCRIPTORS = _dereq_(29); var TO_STRING = 'toString'; var $toString = /./[TO_STRING]; var define = function (fn) { _dereq_(94)(RegExp.prototype, TO_STRING, fn, true); }; // 21.2.5.14 RegExp.prototype.toString() if (_dereq_(35)(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) { define(function toString() { var R = anObject(this); return '/'.concat(R.source, '/', 'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined); }); // FF44- RegExp#toString has a wrong name } else if ($toString.name != TO_STRING) { define(function toString() { return $toString.call(this); }); } },{"225":225,"29":29,"35":35,"37":37,"7":7,"94":94}],231:[function(_dereq_,module,exports){ 'use strict'; var strong = _dereq_(19); var validate = _dereq_(125); var SET = 'Set'; // 23.2 Set Objects module.exports = _dereq_(22)(SET, function (get) { return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; }, { // 23.2.3.1 Set.prototype.add(value) add: function add(value) { return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value); } }, strong); },{"125":125,"19":19,"22":22}],232:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.2 String.prototype.anchor(name) _dereq_(108)('anchor', function (createHTML) { return function anchor(name) { return createHTML(this, 'a', 'name', name); }; }); },{"108":108}],233:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.3 String.prototype.big() _dereq_(108)('big', function (createHTML) { return function big() { return createHTML(this, 'big', '', ''); }; }); },{"108":108}],234:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.4 String.prototype.blink() _dereq_(108)('blink', function (createHTML) { return function blink() { return createHTML(this, 'blink', '', ''); }; }); },{"108":108}],235:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.5 String.prototype.bold() _dereq_(108)('bold', function (createHTML) { return function bold() { return createHTML(this, 'b', '', ''); }; }); },{"108":108}],236:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $at = _dereq_(106)(false); $export($export.P, 'String', { // 21.1.3.3 String.prototype.codePointAt(pos) codePointAt: function codePointAt(pos) { return $at(this, pos); } }); },{"106":106,"33":33}],237:[function(_dereq_,module,exports){ // 21.1.3.6 String.prototype.endsWith(searchString [, endPosition]) 'use strict'; var $export = _dereq_(33); var toLength = _dereq_(118); var context = _dereq_(107); var ENDS_WITH = 'endsWith'; var $endsWith = ''[ENDS_WITH]; $export($export.P + $export.F * _dereq_(34)(ENDS_WITH), 'String', { endsWith: function endsWith(searchString /* , endPosition = @length */) { var that = context(this, searchString, ENDS_WITH); var endPosition = arguments.length > 1 ? arguments[1] : undefined; var len = toLength(that.length); var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len); var search = String(searchString); return $endsWith ? $endsWith.call(that, search, end) : that.slice(end - search.length, end) === search; } }); },{"107":107,"118":118,"33":33,"34":34}],238:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.6 String.prototype.fixed() _dereq_(108)('fixed', function (createHTML) { return function fixed() { return createHTML(this, 'tt', '', ''); }; }); },{"108":108}],239:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.7 String.prototype.fontcolor(color) _dereq_(108)('fontcolor', function (createHTML) { return function fontcolor(color) { return createHTML(this, 'font', 'color', color); }; }); },{"108":108}],240:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.8 String.prototype.fontsize(size) _dereq_(108)('fontsize', function (createHTML) { return function fontsize(size) { return createHTML(this, 'font', 'size', size); }; }); },{"108":108}],241:[function(_dereq_,module,exports){ var $export = _dereq_(33); var toAbsoluteIndex = _dereq_(114); var fromCharCode = String.fromCharCode; var $fromCodePoint = String.fromCodePoint; // length should be 1, old FF problem $export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', { // 21.1.2.2 String.fromCodePoint(...codePoints) fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars var res = []; var aLen = arguments.length; var i = 0; var code; while (aLen > i) { code = +arguments[i++]; if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point'); res.push(code < 0x10000 ? fromCharCode(code) : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00) ); } return res.join(''); } }); },{"114":114,"33":33}],242:[function(_dereq_,module,exports){ // 21.1.3.7 String.prototype.includes(searchString, position = 0) 'use strict'; var $export = _dereq_(33); var context = _dereq_(107); var INCLUDES = 'includes'; $export($export.P + $export.F * _dereq_(34)(INCLUDES), 'String', { includes: function includes(searchString /* , position = 0 */) { return !!~context(this, searchString, INCLUDES) .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined); } }); },{"107":107,"33":33,"34":34}],243:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.9 String.prototype.italics() _dereq_(108)('italics', function (createHTML) { return function italics() { return createHTML(this, 'i', '', ''); }; }); },{"108":108}],244:[function(_dereq_,module,exports){ 'use strict'; var $at = _dereq_(106)(true); // 21.1.3.27 String.prototype[@@iterator]() _dereq_(55)(String, 'String', function (iterated) { this._t = String(iterated); // target this._i = 0; // next index // 21.1.5.2.1 %StringIteratorPrototype%.next() }, function () { var O = this._t; var index = this._i; var point; if (index >= O.length) return { value: undefined, done: true }; point = $at(O, index); this._i += point.length; return { value: point, done: false }; }); },{"106":106,"55":55}],245:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.10 String.prototype.link(url) _dereq_(108)('link', function (createHTML) { return function link(url) { return createHTML(this, 'a', 'href', url); }; }); },{"108":108}],246:[function(_dereq_,module,exports){ var $export = _dereq_(33); var toIObject = _dereq_(117); var toLength = _dereq_(118); $export($export.S, 'String', { // 21.1.2.4 String.raw(callSite, ...substitutions) raw: function raw(callSite) { var tpl = toIObject(callSite.raw); var len = toLength(tpl.length); var aLen = arguments.length; var res = []; var i = 0; while (len > i) { res.push(String(tpl[i++])); if (i < aLen) res.push(String(arguments[i])); } return res.join(''); } }); },{"117":117,"118":118,"33":33}],247:[function(_dereq_,module,exports){ var $export = _dereq_(33); $export($export.P, 'String', { // 21.1.3.13 String.prototype.repeat(count) repeat: _dereq_(110) }); },{"110":110,"33":33}],248:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.11 String.prototype.small() _dereq_(108)('small', function (createHTML) { return function small() { return createHTML(this, 'small', '', ''); }; }); },{"108":108}],249:[function(_dereq_,module,exports){ // 21.1.3.18 String.prototype.startsWith(searchString [, position ]) 'use strict'; var $export = _dereq_(33); var toLength = _dereq_(118); var context = _dereq_(107); var STARTS_WITH = 'startsWith'; var $startsWith = ''[STARTS_WITH]; $export($export.P + $export.F * _dereq_(34)(STARTS_WITH), 'String', { startsWith: function startsWith(searchString /* , position = 0 */) { var that = context(this, searchString, STARTS_WITH); var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length)); var search = String(searchString); return $startsWith ? $startsWith.call(that, search, index) : that.slice(index, index + search.length) === search; } }); },{"107":107,"118":118,"33":33,"34":34}],250:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.12 String.prototype.strike() _dereq_(108)('strike', function (createHTML) { return function strike() { return createHTML(this, 'strike', '', ''); }; }); },{"108":108}],251:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.13 String.prototype.sub() _dereq_(108)('sub', function (createHTML) { return function sub() { return createHTML(this, 'sub', '', ''); }; }); },{"108":108}],252:[function(_dereq_,module,exports){ 'use strict'; // B.2.3.14 String.prototype.sup() _dereq_(108)('sup', function (createHTML) { return function sup() { return createHTML(this, 'sup', '', ''); }; }); },{"108":108}],253:[function(_dereq_,module,exports){ 'use strict'; // 21.1.3.25 String.prototype.trim() _dereq_(111)('trim', function ($trim) { return function trim() { return $trim(this, 3); }; }); },{"111":111}],254:[function(_dereq_,module,exports){ 'use strict'; // ECMAScript 6 symbols shim var global = _dereq_(40); var has = _dereq_(41); var DESCRIPTORS = _dereq_(29); var $export = _dereq_(33); var redefine = _dereq_(94); var META = _dereq_(66).KEY; var $fails = _dereq_(35); var shared = _dereq_(103); var setToStringTag = _dereq_(101); var uid = _dereq_(124); var wks = _dereq_(128); var wksExt = _dereq_(127); var wksDefine = _dereq_(126); var keyOf = _dereq_(59); var enumKeys = _dereq_(32); var isArray = _dereq_(49); var anObject = _dereq_(7); var toIObject = _dereq_(117); var toPrimitive = _dereq_(120); var createDesc = _dereq_(92); var _create = _dereq_(71); var gOPNExt = _dereq_(76); var $GOPD = _dereq_(75); var $DP = _dereq_(72); var $keys = _dereq_(81); var gOPD = $GOPD.f; var dP = $DP.f; var gOPN = gOPNExt.f; var $Symbol = global.Symbol; var $JSON = global.JSON; var _stringify = $JSON && $JSON.stringify; var PROTOTYPE = 'prototype'; var HIDDEN = wks('_hidden'); var TO_PRIMITIVE = wks('toPrimitive'); var isEnum = {}.propertyIsEnumerable; var SymbolRegistry = shared('symbol-registry'); var AllSymbols = shared('symbols'); var OPSymbols = shared('op-symbols'); var ObjectProto = Object[PROTOTYPE]; var USE_NATIVE = typeof $Symbol == 'function'; var QObject = global.QObject; // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 var setSymbolDesc = DESCRIPTORS && $fails(function () { return _create(dP({}, 'a', { get: function () { return dP(this, 'a', { value: 7 }).a; } })).a != 7; }) ? function (it, key, D) { var protoDesc = gOPD(ObjectProto, key); if (protoDesc) delete ObjectProto[key]; dP(it, key, D); if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc); } : dP; var wrap = function (tag) { var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]); sym._k = tag; return sym; }; var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) { return typeof it == 'symbol'; } : function (it) { return it instanceof $Symbol; }; var $defineProperty = function defineProperty(it, key, D) { if (it === ObjectProto) $defineProperty(OPSymbols, key, D); anObject(it); key = toPrimitive(key, true); anObject(D); if (has(AllSymbols, key)) { if (!D.enumerable) { if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {})); it[HIDDEN][key] = true; } else { if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false; D = _create(D, { enumerable: createDesc(0, false) }); } return setSymbolDesc(it, key, D); } return dP(it, key, D); }; var $defineProperties = function defineProperties(it, P) { anObject(it); var keys = enumKeys(P = toIObject(P)); var i = 0; var l = keys.length; var key; while (l > i) $defineProperty(it, key = keys[i++], P[key]); return it; }; var $create = function create(it, P) { return P === undefined ? _create(it) : $defineProperties(_create(it), P); }; var $propertyIsEnumerable = function propertyIsEnumerable(key) { var E = isEnum.call(this, key = toPrimitive(key, true)); if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false; return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true; }; var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) { it = toIObject(it); key = toPrimitive(key, true); if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return; var D = gOPD(it, key); if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true; return D; }; var $getOwnPropertyNames = function getOwnPropertyNames(it) { var names = gOPN(toIObject(it)); var result = []; var i = 0; var key; while (names.length > i) { if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key); } return result; }; var $getOwnPropertySymbols = function getOwnPropertySymbols(it) { var IS_OP = it === ObjectProto; var names = gOPN(IS_OP ? OPSymbols : toIObject(it)); var result = []; var i = 0; var key; while (names.length > i) { if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]); } return result; }; // 19.4.1.1 Symbol([description]) if (!USE_NATIVE) { $Symbol = function Symbol() { if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!'); var tag = uid(arguments.length > 0 ? arguments[0] : undefined); var $set = function (value) { if (this === ObjectProto) $set.call(OPSymbols, value); if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false; setSymbolDesc(this, tag, createDesc(1, value)); }; if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set }); return wrap(tag); }; redefine($Symbol[PROTOTYPE], 'toString', function toString() { return this._k; }); $GOPD.f = $getOwnPropertyDescriptor; $DP.f = $defineProperty; _dereq_(77).f = gOPNExt.f = $getOwnPropertyNames; _dereq_(82).f = $propertyIsEnumerable; _dereq_(78).f = $getOwnPropertySymbols; if (DESCRIPTORS && !_dereq_(60)) { redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); } wksExt.f = function (name) { return wrap(wks(name)); }; } $export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol }); for (var es6Symbols = ( // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' ).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]); for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]); $export($export.S + $export.F * !USE_NATIVE, 'Symbol', { // 19.4.2.1 Symbol.for(key) 'for': function (key) { return has(SymbolRegistry, key += '') ? SymbolRegistry[key] : SymbolRegistry[key] = $Symbol(key); }, // 19.4.2.5 Symbol.keyFor(sym) keyFor: function keyFor(key) { if (isSymbol(key)) return keyOf(SymbolRegistry, key); throw TypeError(key + ' is not a symbol!'); }, useSetter: function () { setter = true; }, useSimple: function () { setter = false; } }); $export($export.S + $export.F * !USE_NATIVE, 'Object', { // 19.1.2.2 Object.create(O [, Properties]) create: $create, // 19.1.2.4 Object.defineProperty(O, P, Attributes) defineProperty: $defineProperty, // 19.1.2.3 Object.defineProperties(O, Properties) defineProperties: $defineProperties, // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) getOwnPropertyDescriptor: $getOwnPropertyDescriptor, // 19.1.2.7 Object.getOwnPropertyNames(O) getOwnPropertyNames: $getOwnPropertyNames, // 19.1.2.8 Object.getOwnPropertySymbols(O) getOwnPropertySymbols: $getOwnPropertySymbols }); // 24.3.2 JSON.stringify(value [, replacer [, space]]) $JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () { var S = $Symbol(); // MS Edge converts symbol values to JSON as {} // WebKit converts symbol values to JSON as null // V8 throws on boxed symbols return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}'; })), 'JSON', { stringify: function stringify(it) { if (it === undefined || isSymbol(it)) return; // IE8 returns string on undefined var args = [it]; var i = 1; var replacer, $replacer; while (arguments.length > i) args.push(arguments[i++]); replacer = args[1]; if (typeof replacer == 'function') $replacer = replacer; if ($replacer || !isArray(replacer)) replacer = function (key, value) { if ($replacer) value = $replacer.call(this, key, value); if (!isSymbol(value)) return value; }; args[1] = replacer; return _stringify.apply($JSON, args); } }); // 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) $Symbol[PROTOTYPE][TO_PRIMITIVE] || _dereq_(42)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); // 19.4.3.5 Symbol.prototype[@@toStringTag] setToStringTag($Symbol, 'Symbol'); // 20.2.1.9 Math[@@toStringTag] setToStringTag(Math, 'Math', true); // 24.3.3 JSON[@@toStringTag] setToStringTag(global.JSON, 'JSON', true); },{"101":101,"103":103,"117":117,"120":120,"124":124,"126":126,"127":127,"128":128,"29":29,"32":32,"33":33,"35":35,"40":40,"41":41,"42":42,"49":49,"59":59,"60":60,"66":66,"7":7,"71":71,"72":72,"75":75,"76":76,"77":77,"78":78,"81":81,"82":82,"92":92,"94":94}],255:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var $typed = _dereq_(123); var buffer = _dereq_(122); var anObject = _dereq_(7); var toAbsoluteIndex = _dereq_(114); var toLength = _dereq_(118); var isObject = _dereq_(51); var ArrayBuffer = _dereq_(40).ArrayBuffer; var speciesConstructor = _dereq_(104); var $ArrayBuffer = buffer.ArrayBuffer; var $DataView = buffer.DataView; var $isView = $typed.ABV && ArrayBuffer.isView; var $slice = $ArrayBuffer.prototype.slice; var VIEW = $typed.VIEW; var ARRAY_BUFFER = 'ArrayBuffer'; $export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), { ArrayBuffer: $ArrayBuffer }); $export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, { // 24.1.3.1 ArrayBuffer.isView(arg) isView: function isView(it) { return $isView && $isView(it) || isObject(it) && VIEW in it; } }); $export($export.P + $export.U + $export.F * _dereq_(35)(function () { return !new $ArrayBuffer(2).slice(1, undefined).byteLength; }), ARRAY_BUFFER, { // 24.1.4.3 ArrayBuffer.prototype.slice(start, end) slice: function slice(start, end) { if ($slice !== undefined && end === undefined) return $slice.call(anObject(this), start); // FF fix var len = anObject(this).byteLength; var first = toAbsoluteIndex(start, len); var final = toAbsoluteIndex(end === undefined ? len : end, len); var result = new (speciesConstructor(this, $ArrayBuffer))(toLength(final - first)); var viewS = new $DataView(this); var viewT = new $DataView(result); var index = 0; while (first < final) { viewT.setUint8(index++, viewS.getUint8(first++)); } return result; } }); _dereq_(100)(ARRAY_BUFFER); },{"100":100,"104":104,"114":114,"118":118,"122":122,"123":123,"33":33,"35":35,"40":40,"51":51,"7":7}],256:[function(_dereq_,module,exports){ var $export = _dereq_(33); $export($export.G + $export.W + $export.F * !_dereq_(123).ABV, { DataView: _dereq_(122).DataView }); },{"122":122,"123":123,"33":33}],257:[function(_dereq_,module,exports){ _dereq_(121)('Float32', 4, function (init) { return function Float32Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],258:[function(_dereq_,module,exports){ _dereq_(121)('Float64', 8, function (init) { return function Float64Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],259:[function(_dereq_,module,exports){ _dereq_(121)('Int16', 2, function (init) { return function Int16Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],260:[function(_dereq_,module,exports){ _dereq_(121)('Int32', 4, function (init) { return function Int32Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],261:[function(_dereq_,module,exports){ _dereq_(121)('Int8', 1, function (init) { return function Int8Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],262:[function(_dereq_,module,exports){ _dereq_(121)('Uint16', 2, function (init) { return function Uint16Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],263:[function(_dereq_,module,exports){ _dereq_(121)('Uint32', 4, function (init) { return function Uint32Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],264:[function(_dereq_,module,exports){ _dereq_(121)('Uint8', 1, function (init) { return function Uint8Array(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }); },{"121":121}],265:[function(_dereq_,module,exports){ _dereq_(121)('Uint8', 1, function (init) { return function Uint8ClampedArray(data, byteOffset, length) { return init(this, data, byteOffset, length); }; }, true); },{"121":121}],266:[function(_dereq_,module,exports){ 'use strict'; var each = _dereq_(12)(0); var redefine = _dereq_(94); var meta = _dereq_(66); var assign = _dereq_(70); var weak = _dereq_(21); var isObject = _dereq_(51); var fails = _dereq_(35); var validate = _dereq_(125); var WEAK_MAP = 'WeakMap'; var getWeak = meta.getWeak; var isExtensible = Object.isExtensible; var uncaughtFrozenStore = weak.ufstore; var tmp = {}; var InternalMap; var wrapper = function (get) { return function WeakMap() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; }; var methods = { // 23.3.3.3 WeakMap.prototype.get(key) get: function get(key) { if (isObject(key)) { var data = getWeak(key); if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key); return data ? data[this._i] : undefined; } }, // 23.3.3.5 WeakMap.prototype.set(key, value) set: function set(key, value) { return weak.def(validate(this, WEAK_MAP), key, value); } }; // 23.3 WeakMap Objects var $WeakMap = module.exports = _dereq_(22)(WEAK_MAP, wrapper, methods, weak, true, true); // IE11 WeakMap frozen keys fix if (fails(function () { return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7; })) { InternalMap = weak.getConstructor(wrapper, WEAK_MAP); assign(InternalMap.prototype, methods); meta.NEED = true; each(['delete', 'has', 'get', 'set'], function (key) { var proto = $WeakMap.prototype; var method = proto[key]; redefine(proto, key, function (a, b) { // store frozen objects on internal weakmap shim if (isObject(a) && !isExtensible(a)) { if (!this._f) this._f = new InternalMap(); var result = this._f[key](a, b); return key == 'set' ? this : result; // store all the rest on native weakmap } return method.call(this, a, b); }); }); } },{"12":12,"125":125,"21":21,"22":22,"35":35,"51":51,"66":66,"70":70,"94":94}],267:[function(_dereq_,module,exports){ 'use strict'; var weak = _dereq_(21); var validate = _dereq_(125); var WEAK_SET = 'WeakSet'; // 23.4 WeakSet Objects _dereq_(22)(WEAK_SET, function (get) { return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); }; }, { // 23.4.3.1 WeakSet.prototype.add(value) add: function add(value) { return weak.def(validate(this, WEAK_SET), value, true); } }, weak, false, true); },{"125":125,"21":21,"22":22}],268:[function(_dereq_,module,exports){ 'use strict'; // https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap var $export = _dereq_(33); var flattenIntoArray = _dereq_(38); var toObject = _dereq_(119); var toLength = _dereq_(118); var aFunction = _dereq_(3); var arraySpeciesCreate = _dereq_(15); $export($export.P, 'Array', { flatMap: function flatMap(callbackfn /* , thisArg */) { var O = toObject(this); var sourceLen, A; aFunction(callbackfn); sourceLen = toLength(O.length); A = arraySpeciesCreate(O, 0); flattenIntoArray(A, O, O, sourceLen, 0, 1, callbackfn, arguments[1]); return A; } }); _dereq_(5)('flatMap'); },{"118":118,"119":119,"15":15,"3":3,"33":33,"38":38,"5":5}],269:[function(_dereq_,module,exports){ 'use strict'; // https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatten var $export = _dereq_(33); var flattenIntoArray = _dereq_(38); var toObject = _dereq_(119); var toLength = _dereq_(118); var toInteger = _dereq_(116); var arraySpeciesCreate = _dereq_(15); $export($export.P, 'Array', { flatten: function flatten(/* depthArg = 1 */) { var depthArg = arguments[0]; var O = toObject(this); var sourceLen = toLength(O.length); var A = arraySpeciesCreate(O, 0); flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toInteger(depthArg)); return A; } }); _dereq_(5)('flatten'); },{"116":116,"118":118,"119":119,"15":15,"33":33,"38":38,"5":5}],270:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/tc39/Array.prototype.includes var $export = _dereq_(33); var $includes = _dereq_(11)(true); $export($export.P, 'Array', { includes: function includes(el /* , fromIndex = 0 */) { return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined); } }); _dereq_(5)('includes'); },{"11":11,"33":33,"5":5}],271:[function(_dereq_,module,exports){ // https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask var $export = _dereq_(33); var microtask = _dereq_(68)(); var process = _dereq_(40).process; var isNode = _dereq_(18)(process) == 'process'; $export($export.G, { asap: function asap(fn) { var domain = isNode && process.domain; microtask(domain ? domain.bind(fn) : fn); } }); },{"18":18,"33":33,"40":40,"68":68}],272:[function(_dereq_,module,exports){ // https://github.com/ljharb/proposal-is-error var $export = _dereq_(33); var cof = _dereq_(18); $export($export.S, 'Error', { isError: function isError(it) { return cof(it) === 'Error'; } }); },{"18":18,"33":33}],273:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-global var $export = _dereq_(33); $export($export.G, { global: _dereq_(40) }); },{"33":33,"40":40}],274:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-map.from _dereq_(97)('Map'); },{"97":97}],275:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-map.of _dereq_(98)('Map'); },{"98":98}],276:[function(_dereq_,module,exports){ // https://github.com/DavidBruant/Map-Set.prototype.toJSON var $export = _dereq_(33); $export($export.P + $export.R, 'Map', { toJSON: _dereq_(20)('Map') }); },{"20":20,"33":33}],277:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); $export($export.S, 'Math', { clamp: function clamp(x, lower, upper) { return Math.min(upper, Math.max(lower, x)); } }); },{"33":33}],278:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); $export($export.S, 'Math', { DEG_PER_RAD: Math.PI / 180 }); },{"33":33}],279:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); var RAD_PER_DEG = 180 / Math.PI; $export($export.S, 'Math', { degrees: function degrees(radians) { return radians * RAD_PER_DEG; } }); },{"33":33}],280:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); var scale = _dereq_(64); var fround = _dereq_(62); $export($export.S, 'Math', { fscale: function fscale(x, inLow, inHigh, outLow, outHigh) { return fround(scale(x, inLow, inHigh, outLow, outHigh)); } }); },{"33":33,"62":62,"64":64}],281:[function(_dereq_,module,exports){ // https://gist.github.com/BrendanEich/4294d5c212a6d2254703 var $export = _dereq_(33); $export($export.S, 'Math', { iaddh: function iaddh(x0, x1, y0, y1) { var $x0 = x0 >>> 0; var $x1 = x1 >>> 0; var $y0 = y0 >>> 0; return $x1 + (y1 >>> 0) + (($x0 & $y0 | ($x0 | $y0) & ~($x0 + $y0 >>> 0)) >>> 31) | 0; } }); },{"33":33}],282:[function(_dereq_,module,exports){ // https://gist.github.com/BrendanEich/4294d5c212a6d2254703 var $export = _dereq_(33); $export($export.S, 'Math', { imulh: function imulh(u, v) { var UINT16 = 0xffff; var $u = +u; var $v = +v; var u0 = $u & UINT16; var v0 = $v & UINT16; var u1 = $u >> 16; var v1 = $v >> 16; var t = (u1 * v0 >>> 0) + (u0 * v0 >>> 16); return u1 * v1 + (t >> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >> 16); } }); },{"33":33}],283:[function(_dereq_,module,exports){ // https://gist.github.com/BrendanEich/4294d5c212a6d2254703 var $export = _dereq_(33); $export($export.S, 'Math', { isubh: function isubh(x0, x1, y0, y1) { var $x0 = x0 >>> 0; var $x1 = x1 >>> 0; var $y0 = y0 >>> 0; return $x1 - (y1 >>> 0) - ((~$x0 & $y0 | ~($x0 ^ $y0) & $x0 - $y0 >>> 0) >>> 31) | 0; } }); },{"33":33}],284:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); $export($export.S, 'Math', { RAD_PER_DEG: 180 / Math.PI }); },{"33":33}],285:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); var DEG_PER_RAD = Math.PI / 180; $export($export.S, 'Math', { radians: function radians(degrees) { return degrees * DEG_PER_RAD; } }); },{"33":33}],286:[function(_dereq_,module,exports){ // https://rwaldron.github.io/proposal-math-extensions/ var $export = _dereq_(33); $export($export.S, 'Math', { scale: _dereq_(64) }); },{"33":33,"64":64}],287:[function(_dereq_,module,exports){ // http://jfbastien.github.io/papers/Math.signbit.html var $export = _dereq_(33); $export($export.S, 'Math', { signbit: function signbit(x) { // eslint-disable-next-line no-self-compare return (x = +x) != x ? x : x == 0 ? 1 / x == Infinity : x > 0; } }); },{"33":33}],288:[function(_dereq_,module,exports){ // https://gist.github.com/BrendanEich/4294d5c212a6d2254703 var $export = _dereq_(33); $export($export.S, 'Math', { umulh: function umulh(u, v) { var UINT16 = 0xffff; var $u = +u; var $v = +v; var u0 = $u & UINT16; var v0 = $v & UINT16; var u1 = $u >>> 16; var v1 = $v >>> 16; var t = (u1 * v0 >>> 0) + (u0 * v0 >>> 16); return u1 * v1 + (t >>> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >>> 16); } }); },{"33":33}],289:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toObject = _dereq_(119); var aFunction = _dereq_(3); var $defineProperty = _dereq_(72); // B.2.2.2 Object.prototype.__defineGetter__(P, getter) _dereq_(29) && $export($export.P + _dereq_(74), 'Object', { __defineGetter__: function __defineGetter__(P, getter) { $defineProperty.f(toObject(this), P, { get: aFunction(getter), enumerable: true, configurable: true }); } }); },{"119":119,"29":29,"3":3,"33":33,"72":72,"74":74}],290:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toObject = _dereq_(119); var aFunction = _dereq_(3); var $defineProperty = _dereq_(72); // B.2.2.3 Object.prototype.__defineSetter__(P, setter) _dereq_(29) && $export($export.P + _dereq_(74), 'Object', { __defineSetter__: function __defineSetter__(P, setter) { $defineProperty.f(toObject(this), P, { set: aFunction(setter), enumerable: true, configurable: true }); } }); },{"119":119,"29":29,"3":3,"33":33,"72":72,"74":74}],291:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-object-values-entries var $export = _dereq_(33); var $entries = _dereq_(84)(true); $export($export.S, 'Object', { entries: function entries(it) { return $entries(it); } }); },{"33":33,"84":84}],292:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-object-getownpropertydescriptors var $export = _dereq_(33); var ownKeys = _dereq_(85); var toIObject = _dereq_(117); var gOPD = _dereq_(75); var createProperty = _dereq_(24); $export($export.S, 'Object', { getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) { var O = toIObject(object); var getDesc = gOPD.f; var keys = ownKeys(O); var result = {}; var i = 0; var key, desc; while (keys.length > i) { desc = getDesc(O, key = keys[i++]); if (desc !== undefined) createProperty(result, key, desc); } return result; } }); },{"117":117,"24":24,"33":33,"75":75,"85":85}],293:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toObject = _dereq_(119); var toPrimitive = _dereq_(120); var getPrototypeOf = _dereq_(79); var getOwnPropertyDescriptor = _dereq_(75).f; // B.2.2.4 Object.prototype.__lookupGetter__(P) _dereq_(29) && $export($export.P + _dereq_(74), 'Object', { __lookupGetter__: function __lookupGetter__(P) { var O = toObject(this); var K = toPrimitive(P, true); var D; do { if (D = getOwnPropertyDescriptor(O, K)) return D.get; } while (O = getPrototypeOf(O)); } }); },{"119":119,"120":120,"29":29,"33":33,"74":74,"75":75,"79":79}],294:[function(_dereq_,module,exports){ 'use strict'; var $export = _dereq_(33); var toObject = _dereq_(119); var toPrimitive = _dereq_(120); var getPrototypeOf = _dereq_(79); var getOwnPropertyDescriptor = _dereq_(75).f; // B.2.2.5 Object.prototype.__lookupSetter__(P) _dereq_(29) && $export($export.P + _dereq_(74), 'Object', { __lookupSetter__: function __lookupSetter__(P) { var O = toObject(this); var K = toPrimitive(P, true); var D; do { if (D = getOwnPropertyDescriptor(O, K)) return D.set; } while (O = getPrototypeOf(O)); } }); },{"119":119,"120":120,"29":29,"33":33,"74":74,"75":75,"79":79}],295:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-object-values-entries var $export = _dereq_(33); var $values = _dereq_(84)(false); $export($export.S, 'Object', { values: function values(it) { return $values(it); } }); },{"33":33,"84":84}],296:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/zenparsing/es-observable var $export = _dereq_(33); var global = _dereq_(40); var core = _dereq_(23); var microtask = _dereq_(68)(); var OBSERVABLE = _dereq_(128)('observable'); var aFunction = _dereq_(3); var anObject = _dereq_(7); var anInstance = _dereq_(6); var redefineAll = _dereq_(93); var hide = _dereq_(42); var forOf = _dereq_(39); var RETURN = forOf.RETURN; var getMethod = function (fn) { return fn == null ? undefined : aFunction(fn); }; var cleanupSubscription = function (subscription) { var cleanup = subscription._c; if (cleanup) { subscription._c = undefined; cleanup(); } }; var subscriptionClosed = function (subscription) { return subscription._o === undefined; }; var closeSubscription = function (subscription) { if (!subscriptionClosed(subscription)) { subscription._o = undefined; cleanupSubscription(subscription); } }; var Subscription = function (observer, subscriber) { anObject(observer); this._c = undefined; this._o = observer; observer = new SubscriptionObserver(this); try { var cleanup = subscriber(observer); var subscription = cleanup; if (cleanup != null) { if (typeof cleanup.unsubscribe === 'function') cleanup = function () { subscription.unsubscribe(); }; else aFunction(cleanup); this._c = cleanup; } } catch (e) { observer.error(e); return; } if (subscriptionClosed(this)) cleanupSubscription(this); }; Subscription.prototype = redefineAll({}, { unsubscribe: function unsubscribe() { closeSubscription(this); } }); var SubscriptionObserver = function (subscription) { this._s = subscription; }; SubscriptionObserver.prototype = redefineAll({}, { next: function next(value) { var subscription = this._s; if (!subscriptionClosed(subscription)) { var observer = subscription._o; try { var m = getMethod(observer.next); if (m) return m.call(observer, value); } catch (e) { try { closeSubscription(subscription); } finally { throw e; } } } }, error: function error(value) { var subscription = this._s; if (subscriptionClosed(subscription)) throw value; var observer = subscription._o; subscription._o = undefined; try { var m = getMethod(observer.error); if (!m) throw value; value = m.call(observer, value); } catch (e) { try { cleanupSubscription(subscription); } finally { throw e; } } cleanupSubscription(subscription); return value; }, complete: function complete(value) { var subscription = this._s; if (!subscriptionClosed(subscription)) { var observer = subscription._o; subscription._o = undefined; try { var m = getMethod(observer.complete); value = m ? m.call(observer, value) : undefined; } catch (e) { try { cleanupSubscription(subscription); } finally { throw e; } } cleanupSubscription(subscription); return value; } } }); var $Observable = function Observable(subscriber) { anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber); }; redefineAll($Observable.prototype, { subscribe: function subscribe(observer) { return new Subscription(observer, this._f); }, forEach: function forEach(fn) { var that = this; return new (core.Promise || global.Promise)(function (resolve, reject) { aFunction(fn); var subscription = that.subscribe({ next: function (value) { try { return fn(value); } catch (e) { reject(e); subscription.unsubscribe(); } }, error: reject, complete: resolve }); }); } }); redefineAll($Observable, { from: function from(x) { var C = typeof this === 'function' ? this : $Observable; var method = getMethod(anObject(x)[OBSERVABLE]); if (method) { var observable = anObject(method.call(x)); return observable.constructor === C ? observable : new C(function (observer) { return observable.subscribe(observer); }); } return new C(function (observer) { var done = false; microtask(function () { if (!done) { try { if (forOf(x, false, function (it) { observer.next(it); if (done) return RETURN; }) === RETURN) return; } catch (e) { if (done) throw e; observer.error(e); return; } observer.complete(); } }); return function () { done = true; }; }); }, of: function of() { for (var i = 0, l = arguments.length, items = Array(l); i < l;) items[i] = arguments[i++]; return new (typeof this === 'function' ? this : $Observable)(function (observer) { var done = false; microtask(function () { if (!done) { for (var j = 0; j < items.length; ++j) { observer.next(items[j]); if (done) return; } observer.complete(); } }); return function () { done = true; }; }); } }); hide($Observable.prototype, OBSERVABLE, function () { return this; }); $export($export.G, { Observable: $Observable }); _dereq_(100)('Observable'); },{"100":100,"128":128,"23":23,"3":3,"33":33,"39":39,"40":40,"42":42,"6":6,"68":68,"7":7,"93":93}],297:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-promise-finally 'use strict'; var $export = _dereq_(33); var core = _dereq_(23); var global = _dereq_(40); var speciesConstructor = _dereq_(104); var promiseResolve = _dereq_(91); $export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) { var C = speciesConstructor(this, core.Promise || global.Promise); var isFunction = typeof onFinally == 'function'; return this.then( isFunction ? function (x) { return promiseResolve(C, onFinally()).then(function () { return x; }); } : onFinally, isFunction ? function (e) { return promiseResolve(C, onFinally()).then(function () { throw e; }); } : onFinally ); } }); },{"104":104,"23":23,"33":33,"40":40,"91":91}],298:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/tc39/proposal-promise-try var $export = _dereq_(33); var newPromiseCapability = _dereq_(69); var perform = _dereq_(90); $export($export.S, 'Promise', { 'try': function (callbackfn) { var promiseCapability = newPromiseCapability.f(this); var result = perform(callbackfn); (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v); return promiseCapability.promise; } }); },{"33":33,"69":69,"90":90}],299:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var toMetaKey = metadata.key; var ordinaryDefineOwnMetadata = metadata.set; metadata.exp({ defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey) { ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey)); } }); },{"67":67,"7":7}],300:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var toMetaKey = metadata.key; var getOrCreateMetadataMap = metadata.map; var store = metadata.store; metadata.exp({ deleteMetadata: function deleteMetadata(metadataKey, target /* , targetKey */) { var targetKey = arguments.length < 3 ? undefined : toMetaKey(arguments[2]); var metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false); if (metadataMap === undefined || !metadataMap['delete'](metadataKey)) return false; if (metadataMap.size) return true; var targetMetadata = store.get(target); targetMetadata['delete'](targetKey); return !!targetMetadata.size || store['delete'](target); } }); },{"67":67,"7":7}],301:[function(_dereq_,module,exports){ var Set = _dereq_(231); var from = _dereq_(10); var metadata = _dereq_(67); var anObject = _dereq_(7); var getPrototypeOf = _dereq_(79); var ordinaryOwnMetadataKeys = metadata.keys; var toMetaKey = metadata.key; var ordinaryMetadataKeys = function (O, P) { var oKeys = ordinaryOwnMetadataKeys(O, P); var parent = getPrototypeOf(O); if (parent === null) return oKeys; var pKeys = ordinaryMetadataKeys(parent, P); return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys; }; metadata.exp({ getMetadataKeys: function getMetadataKeys(target /* , targetKey */) { return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1])); } }); },{"10":10,"231":231,"67":67,"7":7,"79":79}],302:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var getPrototypeOf = _dereq_(79); var ordinaryHasOwnMetadata = metadata.has; var ordinaryGetOwnMetadata = metadata.get; var toMetaKey = metadata.key; var ordinaryGetMetadata = function (MetadataKey, O, P) { var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P); if (hasOwn) return ordinaryGetOwnMetadata(MetadataKey, O, P); var parent = getPrototypeOf(O); return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined; }; metadata.exp({ getMetadata: function getMetadata(metadataKey, target /* , targetKey */) { return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2])); } }); },{"67":67,"7":7,"79":79}],303:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var ordinaryOwnMetadataKeys = metadata.keys; var toMetaKey = metadata.key; metadata.exp({ getOwnMetadataKeys: function getOwnMetadataKeys(target /* , targetKey */) { return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1])); } }); },{"67":67,"7":7}],304:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var ordinaryGetOwnMetadata = metadata.get; var toMetaKey = metadata.key; metadata.exp({ getOwnMetadata: function getOwnMetadata(metadataKey, target /* , targetKey */) { return ordinaryGetOwnMetadata(metadataKey, anObject(target) , arguments.length < 3 ? undefined : toMetaKey(arguments[2])); } }); },{"67":67,"7":7}],305:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var getPrototypeOf = _dereq_(79); var ordinaryHasOwnMetadata = metadata.has; var toMetaKey = metadata.key; var ordinaryHasMetadata = function (MetadataKey, O, P) { var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P); if (hasOwn) return true; var parent = getPrototypeOf(O); return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false; }; metadata.exp({ hasMetadata: function hasMetadata(metadataKey, target /* , targetKey */) { return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2])); } }); },{"67":67,"7":7,"79":79}],306:[function(_dereq_,module,exports){ var metadata = _dereq_(67); var anObject = _dereq_(7); var ordinaryHasOwnMetadata = metadata.has; var toMetaKey = metadata.key; metadata.exp({ hasOwnMetadata: function hasOwnMetadata(metadataKey, target /* , targetKey */) { return ordinaryHasOwnMetadata(metadataKey, anObject(target) , arguments.length < 3 ? undefined : toMetaKey(arguments[2])); } }); },{"67":67,"7":7}],307:[function(_dereq_,module,exports){ var $metadata = _dereq_(67); var anObject = _dereq_(7); var aFunction = _dereq_(3); var toMetaKey = $metadata.key; var ordinaryDefineOwnMetadata = $metadata.set; $metadata.exp({ metadata: function metadata(metadataKey, metadataValue) { return function decorator(target, targetKey) { ordinaryDefineOwnMetadata( metadataKey, metadataValue, (targetKey !== undefined ? anObject : aFunction)(target), toMetaKey(targetKey) ); }; } }); },{"3":3,"67":67,"7":7}],308:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-set.from _dereq_(97)('Set'); },{"97":97}],309:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-set.of _dereq_(98)('Set'); },{"98":98}],310:[function(_dereq_,module,exports){ // https://github.com/DavidBruant/Map-Set.prototype.toJSON var $export = _dereq_(33); $export($export.P + $export.R, 'Set', { toJSON: _dereq_(20)('Set') }); },{"20":20,"33":33}],311:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/mathiasbynens/String.prototype.at var $export = _dereq_(33); var $at = _dereq_(106)(true); $export($export.P, 'String', { at: function at(pos) { return $at(this, pos); } }); },{"106":106,"33":33}],312:[function(_dereq_,module,exports){ 'use strict'; // https://tc39.github.io/String.prototype.matchAll/ var $export = _dereq_(33); var defined = _dereq_(28); var toLength = _dereq_(118); var isRegExp = _dereq_(52); var getFlags = _dereq_(37); var RegExpProto = RegExp.prototype; var $RegExpStringIterator = function (regexp, string) { this._r = regexp; this._s = string; }; _dereq_(54)($RegExpStringIterator, 'RegExp String', function next() { var match = this._r.exec(this._s); return { value: match, done: match === null }; }); $export($export.P, 'String', { matchAll: function matchAll(regexp) { defined(this); if (!isRegExp(regexp)) throw TypeError(regexp + ' is not a regexp!'); var S = String(this); var flags = 'flags' in RegExpProto ? String(regexp.flags) : getFlags.call(regexp); var rx = new RegExp(regexp.source, ~flags.indexOf('g') ? flags : 'g' + flags); rx.lastIndex = toLength(regexp.lastIndex); return new $RegExpStringIterator(rx, S); } }); },{"118":118,"28":28,"33":33,"37":37,"52":52,"54":54}],313:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/tc39/proposal-string-pad-start-end var $export = _dereq_(33); var $pad = _dereq_(109); $export($export.P, 'String', { padEnd: function padEnd(maxLength /* , fillString = ' ' */) { return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false); } }); },{"109":109,"33":33}],314:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/tc39/proposal-string-pad-start-end var $export = _dereq_(33); var $pad = _dereq_(109); $export($export.P, 'String', { padStart: function padStart(maxLength /* , fillString = ' ' */) { return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true); } }); },{"109":109,"33":33}],315:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/sebmarkbage/ecmascript-string-left-right-trim _dereq_(111)('trimLeft', function ($trim) { return function trimLeft() { return $trim(this, 1); }; }, 'trimStart'); },{"111":111}],316:[function(_dereq_,module,exports){ 'use strict'; // https://github.com/sebmarkbage/ecmascript-string-left-right-trim _dereq_(111)('trimRight', function ($trim) { return function trimRight() { return $trim(this, 2); }; }, 'trimEnd'); },{"111":111}],317:[function(_dereq_,module,exports){ _dereq_(126)('asyncIterator'); },{"126":126}],318:[function(_dereq_,module,exports){ _dereq_(126)('observable'); },{"126":126}],319:[function(_dereq_,module,exports){ // https://github.com/tc39/proposal-global var $export = _dereq_(33); $export($export.S, 'System', { global: _dereq_(40) }); },{"33":33,"40":40}],320:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.from _dereq_(97)('WeakMap'); },{"97":97}],321:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.of _dereq_(98)('WeakMap'); },{"98":98}],322:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.from _dereq_(97)('WeakSet'); },{"97":97}],323:[function(_dereq_,module,exports){ // https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.of _dereq_(98)('WeakSet'); },{"98":98}],324:[function(_dereq_,module,exports){ var $iterators = _dereq_(141); var getKeys = _dereq_(81); var redefine = _dereq_(94); var global = _dereq_(40); var hide = _dereq_(42); var Iterators = _dereq_(58); var wks = _dereq_(128); var ITERATOR = wks('iterator'); var TO_STRING_TAG = wks('toStringTag'); var ArrayValues = Iterators.Array; var DOMIterables = { CSSRuleList: true, // TODO: Not spec compliant, should be false. CSSStyleDeclaration: false, CSSValueList: false, ClientRectList: false, DOMRectList: false, DOMStringList: false, DOMTokenList: true, DataTransferItemList: false, FileList: false, HTMLAllCollection: false, HTMLCollection: false, HTMLFormElement: false, HTMLSelectElement: false, MediaList: true, // TODO: Not spec compliant, should be false. MimeTypeArray: false, NamedNodeMap: false, NodeList: true, PaintRequestList: false, Plugin: false, PluginArray: false, SVGLengthList: false, SVGNumberList: false, SVGPathSegList: false, SVGPointList: false, SVGStringList: false, SVGTransformList: false, SourceBufferList: false, StyleSheetList: true, // TODO: Not spec compliant, should be false. TextTrackCueList: false, TextTrackList: false, TouchList: false }; for (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) { var NAME = collections[i]; var explicit = DOMIterables[NAME]; var Collection = global[NAME]; var proto = Collection && Collection.prototype; var key; if (proto) { if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues); if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); Iterators[NAME] = ArrayValues; if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true); } } },{"128":128,"141":141,"40":40,"42":42,"58":58,"81":81,"94":94}],325:[function(_dereq_,module,exports){ var $export = _dereq_(33); var $task = _dereq_(113); $export($export.G + $export.B, { setImmediate: $task.set, clearImmediate: $task.clear }); },{"113":113,"33":33}],326:[function(_dereq_,module,exports){ // ie9- setTimeout & setInterval additional parameters fix var global = _dereq_(40); var $export = _dereq_(33); var invoke = _dereq_(46); var partial = _dereq_(88); var navigator = global.navigator; var MSIE = !!navigator && /MSIE .\./.test(navigator.userAgent); // <- dirty ie9- check var wrap = function (set) { return MSIE ? function (fn, time /* , ...args */) { return set(invoke( partial, [].slice.call(arguments, 2), // eslint-disable-next-line no-new-func typeof fn == 'function' ? fn : Function(fn) ), time); } : set; }; $export($export.G + $export.B + $export.F * MSIE, { setTimeout: wrap(global.setTimeout), setInterval: wrap(global.setInterval) }); },{"33":33,"40":40,"46":46,"88":88}],327:[function(_dereq_,module,exports){ _dereq_(254); _dereq_(191); _dereq_(193); _dereq_(192); _dereq_(195); _dereq_(197); _dereq_(202); _dereq_(196); _dereq_(194); _dereq_(204); _dereq_(203); _dereq_(199); _dereq_(200); _dereq_(198); _dereq_(190); _dereq_(201); _dereq_(205); _dereq_(206); _dereq_(157); _dereq_(159); _dereq_(158); _dereq_(208); _dereq_(207); _dereq_(178); _dereq_(188); _dereq_(189); _dereq_(179); _dereq_(180); _dereq_(181); _dereq_(182); _dereq_(183); _dereq_(184); _dereq_(185); _dereq_(186); _dereq_(187); _dereq_(161); _dereq_(162); _dereq_(163); _dereq_(164); _dereq_(165); _dereq_(166); _dereq_(167); _dereq_(168); _dereq_(169); _dereq_(170); _dereq_(171); _dereq_(172); _dereq_(173); _dereq_(174); _dereq_(175); _dereq_(176); _dereq_(177); _dereq_(241); _dereq_(246); _dereq_(253); _dereq_(244); _dereq_(236); _dereq_(237); _dereq_(242); _dereq_(247); _dereq_(249); _dereq_(232); _dereq_(233); _dereq_(234); _dereq_(235); _dereq_(238); _dereq_(239); _dereq_(240); _dereq_(243); _dereq_(245); _dereq_(248); _dereq_(250); _dereq_(251); _dereq_(252); _dereq_(152); _dereq_(154); _dereq_(153); _dereq_(156); _dereq_(155); _dereq_(140); _dereq_(138); _dereq_(145); _dereq_(142); _dereq_(148); _dereq_(150); _dereq_(137); _dereq_(144); _dereq_(134); _dereq_(149); _dereq_(132); _dereq_(147); _dereq_(146); _dereq_(139); _dereq_(143); _dereq_(131); _dereq_(133); _dereq_(136); _dereq_(135); _dereq_(151); _dereq_(141); _dereq_(224); _dereq_(230); _dereq_(225); _dereq_(226); _dereq_(227); _dereq_(228); _dereq_(229); _dereq_(209); _dereq_(160); _dereq_(231); _dereq_(266); _dereq_(267); _dereq_(255); _dereq_(256); _dereq_(261); _dereq_(264); _dereq_(265); _dereq_(259); _dereq_(262); _dereq_(260); _dereq_(263); _dereq_(257); _dereq_(258); _dereq_(210); _dereq_(211); _dereq_(212); _dereq_(213); _dereq_(214); _dereq_(217); _dereq_(215); _dereq_(216); _dereq_(218); _dereq_(219); _dereq_(220); _dereq_(221); _dereq_(223); _dereq_(222); _dereq_(270); _dereq_(268); _dereq_(269); _dereq_(311); _dereq_(314); _dereq_(313); _dereq_(315); _dereq_(316); _dereq_(312); _dereq_(317); _dereq_(318); _dereq_(292); _dereq_(295); _dereq_(291); _dereq_(289); _dereq_(290); _dereq_(293); _dereq_(294); _dereq_(276); _dereq_(310); _dereq_(275); _dereq_(309); _dereq_(321); _dereq_(323); _dereq_(274); _dereq_(308); _dereq_(320); _dereq_(322); _dereq_(273); _dereq_(319); _dereq_(272); _dereq_(277); _dereq_(278); _dereq_(279); _dereq_(280); _dereq_(281); _dereq_(283); _dereq_(282); _dereq_(284); _dereq_(285); _dereq_(286); _dereq_(288); _dereq_(287); _dereq_(297); _dereq_(298); _dereq_(299); _dereq_(300); _dereq_(302); _dereq_(301); _dereq_(304); _dereq_(303); _dereq_(305); _dereq_(306); _dereq_(307); _dereq_(271); _dereq_(296); _dereq_(326); _dereq_(325); _dereq_(324); module.exports = _dereq_(23); },{"131":131,"132":132,"133":133,"134":134,"135":135,"136":136,"137":137,"138":138,"139":139,"140":140,"141":141,"142":142,"143":143,"144":144,"145":145,"146":146,"147":147,"148":148,"149":149,"150":150,"151":151,"152":152,"153":153,"154":154,"155":155,"156":156,"157":157,"158":158,"159":159,"160":160,"161":161,"162":162,"163":163,"164":164,"165":165,"166":166,"167":167,"168":168,"169":169,"170":170,"171":171,"172":172,"173":173,"174":174,"175":175,"176":176,"177":177,"178":178,"179":179,"180":180,"181":181,"182":182,"183":183,"184":184,"185":185,"186":186,"187":187,"188":188,"189":189,"190":190,"191":191,"192":192,"193":193,"194":194,"195":195,"196":196,"197":197,"198":198,"199":199,"200":200,"201":201,"202":202,"203":203,"204":204,"205":205,"206":206,"207":207,"208":208,"209":209,"210":210,"211":211,"212":212,"213":213,"214":214,"215":215,"216":216,"217":217,"218":218,"219":219,"220":220,"221":221,"222":222,"223":223,"224":224,"225":225,"226":226,"227":227,"228":228,"229":229,"23":23,"230":230,"231":231,"232":232,"233":233,"234":234,"235":235,"236":236,"237":237,"238":238,"239":239,"240":240,"241":241,"242":242,"243":243,"244":244,"245":245,"246":246,"247":247,"248":248,"249":249,"250":250,"251":251,"252":252,"253":253,"254":254,"255":255,"256":256,"257":257,"258":258,"259":259,"260":260,"261":261,"262":262,"263":263,"264":264,"265":265,"266":266,"267":267,"268":268,"269":269,"270":270,"271":271,"272":272,"273":273,"274":274,"275":275,"276":276,"277":277,"278":278,"279":279,"280":280,"281":281,"282":282,"283":283,"284":284,"285":285,"286":286,"287":287,"288":288,"289":289,"290":290,"291":291,"292":292,"293":293,"294":294,"295":295,"296":296,"297":297,"298":298,"299":299,"300":300,"301":301,"302":302,"303":303,"304":304,"305":305,"306":306,"307":307,"308":308,"309":309,"310":310,"311":311,"312":312,"313":313,"314":314,"315":315,"316":316,"317":317,"318":318,"319":319,"320":320,"321":321,"322":322,"323":323,"324":324,"325":325,"326":326}],328:[function(_dereq_,module,exports){ (function (global){ /** * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * https://raw.github.com/facebook/regenerator/master/LICENSE file. An * additional grant of patent rights can be found in the PATENTS file in * the same directory. */ !(function(global) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; // More compressible than void 0. var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; var inModule = typeof module === "object"; var runtime = global.regeneratorRuntime; if (runtime) { if (inModule) { // If regeneratorRuntime is defined globally and we're in a module, // make the exports object identical to regeneratorRuntime. module.exports = runtime; } // Don't bother evaluating the rest of this file if the runtime was // already defined globally. return; } // Define the runtime globally (as expected by generated code) as either // module.exports (if we're in a module) or a new, empty object. runtime = global.regeneratorRuntime = inModule ? module.exports : {}; function wrap(innerFn, outerFn, self, tryLocsList) { // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next, // .throw, and .return methods. generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } runtime.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion // record like context.tryEntries[i].completion. This interface could // have been (and was previously) designed to take a closure to be // invoked without arguments, but in all the cases we care about we // already have an existing method we want to call, so there's no need // to create a new function object. We can even get away with assuming // the method takes exactly one argument, since that happens to be true // in every case, so we don't have to touch the arguments object. The // only additional allocation required is the completion record, which // has a stable shape and so hopefully should be cheap to allocate. function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as // breaking out of the dispatch switch statement. var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and // .constructor.prototype properties for functions that return Generator // objects. For full spec compliance, you may wish to configure your // minifier not to mangle the names of these two functions. function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that // don't natively support it. var IteratorPrototype = {}; IteratorPrototype[iteratorSymbol] = function () { return this; }; var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { // This environment has a native %IteratorPrototype%; use it instead // of the polyfill. IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; GeneratorFunctionPrototype.constructor = GeneratorFunction; GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; // Helper for defining the .next, .throw, and .return methods of the // Iterator interface in terms of a single ._invoke method. function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function(method) { prototype[method] = function(arg) { return this._invoke(method, arg); }; }); } runtime.isGeneratorFunction = function(genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can // do is to check its .name property. (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; runtime.mark = function(genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; if (!(toStringTagSymbol in genFun)) { genFun[toStringTagSymbol] = "GeneratorFunction"; } } genFun.prototype = Object.create(Gp); return genFun; }; // Within the body of any async function, `await x` is transformed to // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test // `hasOwn.call(value, "__await")` to determine if the yielded value is // meant to be awaited. runtime.awrap = function(arg) { return { __await: arg }; }; function AsyncIterator(generator) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return Promise.resolve(value.__await).then(function(value) { invoke("next", value, resolve, reject); }, function(err) { invoke("throw", err, resolve, reject); }); } return Promise.resolve(value).then(function(unwrapped) { // When a yielded Promise is resolved, its final value becomes // the .value of the Promise<{value,done}> result for the // current iteration. If the Promise is rejected, however, the // result for this iteration will be rejected with the same // reason. Note that rejections of yielded Promises are not // thrown back into the generator function, as is the case // when an awaited Promise is rejected. This difference in // behavior between yield and await is important, because it // allows the consumer to decide what to do with the yielded // rejection (swallow it and continue, manually .throw it back // into the generator, abandon iteration, whatever). With // await, by contrast, there is no opportunity to examine the // rejection reason outside the generator function, so the // only option is to throw it from the await expression, and // let the generator function handle the exception. result.value = unwrapped; resolve(result); }, reject); } } if (typeof global.process === "object" && global.process.domain) { invoke = global.process.domain.bind(invoke); } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new Promise(function(resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = // If enqueue has been called before, then we want to wait until // all previous Promises have been resolved before calling invoke, // so that results are always delivered in the correct order. If // enqueue has not been called before, then it is important to // call invoke immediately, without waiting on a callback to fire, // so that the async generator function has the opportunity to do // any necessary setup in a predictable way. This predictability // is why the Promise constructor synchronously invokes its // executor callback, and why async functions synchronously // execute code before the first await. Since we implement simple // async functions in terms of async generators, it is especially // important to get this right, even though it requires care. previousPromise ? previousPromise.then( callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later // invocations of the iterator. callInvokeWithMethodAndArg ) : callInvokeWithMethodAndArg(); } // Define the unified helper method that is used to implement .next, // .throw, and .return (see defineIteratorMethods). this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); AsyncIterator.prototype[asyncIteratorSymbol] = function () { return this; }; runtime.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of // AsyncIterator objects; they just return a Promise for the value of // the final result produced by the iterator. runtime.async = function(innerFn, outerFn, self, tryLocsList) { var iter = new AsyncIterator( wrap(innerFn, outerFn, self, tryLocsList) ); return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. : iter.next().then(function(result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } // Be forgiving, per 25.3.3.3.3 of the spec: // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { // Setting context._sent for legacy support of Babel's // function.sent implementation. context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { // If an exception is thrown from innerFn, we leave state === // GenStateExecuting and loop back for another invocation. state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; // Dispatch the exception by looping back around to the // context.dispatchException(context.arg) call above. context.method = "throw"; context.arg = record.arg; } } }; } // Call delegate.iterator[context.method](context.arg) and handle the // result, either by returning a { value, done } result from the // delegate iterator, or by modifying context.method and context.arg, // setting context.delegate to null, and returning the ContinueSentinel. function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined) { // A .throw or .return when the delegate iterator has no .throw // method always terminates the yield* loop. context.delegate = null; if (context.method === "throw") { if (delegate.iterator.return) { // If the delegate iterator has a return method, give it a // chance to clean up. context.method = "return"; context.arg = undefined; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { // If maybeInvokeDelegate(context) changed context.method from // "return" to "throw", let that override the TypeError below. return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError( "The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (! info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { // Assign the result of the finished delegate to the temporary // variable specified by delegate.resultName (see delegateYield). context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield). context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the // exception, let the outer generator proceed normally. If // context.method was "next", forget context.arg since it has been // "consumed" by the delegate iterator. If context.method was // "return", allow the original .return call to continue in the // outer generator. if (context.method !== "return") { context.method = "next"; context.arg = undefined; } } else { // Re-yield the result returned by the delegate method. return info; } // The delegate iterator is finished, so forget it and continue with // the outer generator. context.delegate = null; return ContinueSentinel; } // Define Generator.prototype.{next,throw,return} in terms of the // unified ._invoke helper method. defineIteratorMethods(Gp); Gp[toStringTagSymbol] = "Generator"; // A Generator should always return itself as the iterator object when the // @@iterator function is called on it. Some browsers' implementations of the // iterator prototype chain incorrectly implement this, causing the Generator // object to not be returned from this call. This ensures that doesn't happen. // See https://github.com/facebook/regenerator/issues/274 for more details. Gp[iteratorSymbol] = function() { return this; }; Gp.toString = function() { return "[object Generator]"; }; function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { // The root entry object (effectively a try statement without a catch // or a finally block) gives us a place to store values thrown from // locations where there is no enclosing try statement. this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } runtime.keys = function(object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); // Rather than returning an object with a next method, we keep // things simple and return the next function itself. return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } // To avoid creating an additional object, we just hang the .value // and .done properties off the next function object itself. This // also ensures that the minifier will not anonymize the function. next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined; next.done = true; return next; }; return next.next = next; } } // Return an iterator with no values. return { next: doneResult }; } runtime.values = values; function doneResult() { return { value: undefined, done: true }; } Context.prototype = { constructor: Context, reset: function(skipTempReset) { this.prev = 0; this.next = 0; // Resetting context._sent for legacy support of Babel's // function.sent implementation. this.sent = this._sent = undefined; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { // Not sure about the optimal order of these conditions: if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined; } } } }, stop: function() { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function(exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { // If the dispatched exception was caught by a catch block, // then let that catch block handle the exception normally. context.method = "next"; context.arg = undefined; } return !! caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { // Exception thrown outside of any try block that could handle // it, so set the completion value of the entire function to // throw the exception. return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { // Ignore the finally entry if control is not jumping to a // location outside the try/catch block. finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function(record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } // The context.catch method must only be called with a location // argument that corresponds to a known catch block. throw new Error("illegal catch attempt"); }, delegateYield: function(iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { // Deliberately forget the last sent value so that we don't // accidentally pass it on to the delegate. this.arg = undefined; } return ContinueSentinel; } }; })( // Among the various tricks for obtaining a reference to the global // object, this seems to be the most reliable technique that does not // use indirect eval (which violates Content Security Policy). typeof global === "object" ? global : typeof window === "object" ? window : typeof self === "object" ? self : this ); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}]},{},[1]); require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i...', true, true); var tok = { jsxName: new TokenType('jsxName'), jsxText: new TokenType('jsxText', { beforeExpr: true }), jsxTagStart: new TokenType('jsxTagStart'), jsxTagEnd: new TokenType('jsxTagEnd') }; tok.jsxTagStart.updateContext = function () { this.context.push(tc_expr); // treat as beginning of JSX expression this.context.push(tc_oTag); // start opening tag context this.exprAllowed = false; }; tok.jsxTagEnd.updateContext = function (prevType) { var out = this.context.pop(); if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) { this.context.pop(); this.exprAllowed = this.curContext() === tc_expr; } else { this.exprAllowed = true; } }; // Transforms JSX element name to string. function getQualifiedJSXName(object) { if (!object) return object; if (object.type === 'JSXIdentifier') return object.name; if (object.type === 'JSXNamespacedName') return object.namespace.name + ':' + object.name.name; if (object.type === 'JSXMemberExpression') return getQualifiedJSXName(object.object) + '.' + getQualifiedJSXName(object.property); } module.exports = function (options) { options = options || {}; return function (Parser) { return plugin({ allowNamespaces: options.allowNamespaces !== false, allowNamespacedObjects: !!options.allowNamespacedObjects }, Parser); }; }; module.exports.tokTypes = tok; function plugin(options, Parser) { return function (_Parser) { _inherits(_class, _Parser); function _class() { _classCallCheck(this, _class); return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); } _createClass(_class, [{ key: 'jsx_readToken', // Reads inline JSX contents token. value: function jsx_readToken() { var out = '', chunkStart = this.pos; for (;;) { if (this.pos >= this.input.length) this.raise(this.start, 'Unterminated JSX contents'); var ch = this.input.charCodeAt(this.pos); switch (ch) { case 60: // '<' case 123: // '{' if (this.pos === this.start) { if (ch === 60 && this.exprAllowed) { ++this.pos; return this.finishToken(tok.jsxTagStart); } return this.getTokenFromCode(ch); } out += this.input.slice(chunkStart, this.pos); return this.finishToken(tok.jsxText, out); case 38: // '&' out += this.input.slice(chunkStart, this.pos); out += this.jsx_readEntity(); chunkStart = this.pos; break; default: if (isNewLine(ch)) { out += this.input.slice(chunkStart, this.pos); out += this.jsx_readNewLine(true); chunkStart = this.pos; } else { ++this.pos; } } } } }, { key: 'jsx_readNewLine', value: function jsx_readNewLine(normalizeCRLF) { var ch = this.input.charCodeAt(this.pos); var out = void 0; ++this.pos; if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { ++this.pos; out = normalizeCRLF ? '\n' : '\r\n'; } else { out = String.fromCharCode(ch); } if (this.options.locations) { ++this.curLine; this.lineStart = this.pos; } return out; } }, { key: 'jsx_readString', value: function jsx_readString(quote) { var out = '', chunkStart = ++this.pos; for (;;) { if (this.pos >= this.input.length) this.raise(this.start, 'Unterminated string constant'); var ch = this.input.charCodeAt(this.pos); if (ch === quote) break; if (ch === 38) { // '&' out += this.input.slice(chunkStart, this.pos); out += this.jsx_readEntity(); chunkStart = this.pos; } else if (isNewLine(ch)) { out += this.input.slice(chunkStart, this.pos); out += this.jsx_readNewLine(false); chunkStart = this.pos; } else { ++this.pos; } } out += this.input.slice(chunkStart, this.pos++); return this.finishToken(tt.string, out); } }, { key: 'jsx_readEntity', value: function jsx_readEntity() { var str = '', count = 0, entity = void 0; var ch = this.input[this.pos]; if (ch !== '&') this.raise(this.pos, 'Entity must start with an ampersand'); var startPos = ++this.pos; while (this.pos < this.input.length && count++ < 10) { ch = this.input[this.pos++]; if (ch === ';') { if (str[0] === '#') { if (str[1] === 'x') { str = str.substr(2); if (hexNumber.test(str)) entity = String.fromCharCode(parseInt(str, 16)); } else { str = str.substr(1); if (decimalNumber.test(str)) entity = String.fromCharCode(parseInt(str, 10)); } } else { entity = XHTMLEntities[str]; } break; } str += ch; } if (!entity) { this.pos = startPos; return '&'; } return entity; } // Read a JSX identifier (valid tag or attribute name). // // Optimized version since JSX identifiers can't contain // escape characters and so can be read as single slice. // Also assumes that first character was already checked // by isIdentifierStart in readToken. }, { key: 'jsx_readWord', value: function jsx_readWord() { var ch = void 0, start = this.pos; do { ch = this.input.charCodeAt(++this.pos); } while (isIdentifierChar(ch) || ch === 45); // '-' return this.finishToken(tok.jsxName, this.input.slice(start, this.pos)); } // Parse next token as JSX identifier }, { key: 'jsx_parseIdentifier', value: function jsx_parseIdentifier() { var node = this.startNode(); if (this.type === tok.jsxName) node.name = this.value;else if (this.type.keyword) node.name = this.type.keyword;else this.unexpected(); this.next(); return this.finishNode(node, 'JSXIdentifier'); } // Parse namespaced identifier. }, { key: 'jsx_parseNamespacedName', value: function jsx_parseNamespacedName() { var startPos = this.start, startLoc = this.startLoc; var name = this.jsx_parseIdentifier(); if (!options.allowNamespaces || !this.eat(tt.colon)) return name; var node = this.startNodeAt(startPos, startLoc); node.namespace = name; node.name = this.jsx_parseIdentifier(); return this.finishNode(node, 'JSXNamespacedName'); } // Parses element name in any form - namespaced, member // or single identifier. }, { key: 'jsx_parseElementName', value: function jsx_parseElementName() { if (this.type === tok.jsxTagEnd) return ''; var startPos = this.start, startLoc = this.startLoc; var node = this.jsx_parseNamespacedName(); if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) { this.unexpected(); } while (this.eat(tt.dot)) { var newNode = this.startNodeAt(startPos, startLoc); newNode.object = node; newNode.property = this.jsx_parseIdentifier(); node = this.finishNode(newNode, 'JSXMemberExpression'); } return node; } // Parses any type of JSX attribute value. }, { key: 'jsx_parseAttributeValue', value: function jsx_parseAttributeValue() { switch (this.type) { case tt.braceL: var node = this.jsx_parseExpressionContainer(); if (node.expression.type === 'JSXEmptyExpression') this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); return node; case tok.jsxTagStart: case tt.string: return this.parseExprAtom(); default: this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); } } // JSXEmptyExpression is unique type since it doesn't actually parse anything, // and so it should start at the end of last read token (left brace) and finish // at the beginning of the next one (right brace). }, { key: 'jsx_parseEmptyExpression', value: function jsx_parseEmptyExpression() { var node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); } // Parses JSX expression enclosed into curly brackets. }, { key: 'jsx_parseExpressionContainer', value: function jsx_parseExpressionContainer() { var node = this.startNode(); this.next(); node.expression = this.type === tt.braceR ? this.jsx_parseEmptyExpression() : this.parseExpression(); this.expect(tt.braceR); return this.finishNode(node, 'JSXExpressionContainer'); } // Parses following JSX attribute name-value pair. }, { key: 'jsx_parseAttribute', value: function jsx_parseAttribute() { var node = this.startNode(); if (this.eat(tt.braceL)) { this.expect(tt.ellipsis); node.argument = this.parseMaybeAssign(); this.expect(tt.braceR); return this.finishNode(node, 'JSXSpreadAttribute'); } node.name = this.jsx_parseNamespacedName(); node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; return this.finishNode(node, 'JSXAttribute'); } // Parses JSX opening tag starting after '<'. }, { key: 'jsx_parseOpeningElementAt', value: function jsx_parseOpeningElementAt(startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); node.attributes = []; var nodeName = this.jsx_parseElementName(); if (nodeName) node.name = nodeName; while (this.type !== tt.slash && this.type !== tok.jsxTagEnd) { node.attributes.push(this.jsx_parseAttribute()); }node.selfClosing = this.eat(tt.slash); this.expect(tok.jsxTagEnd); return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment'); } // Parses JSX closing tag starting after ''); } } var fragmentOrElement = openingElement.name ? 'Element' : 'Fragment'; node['opening' + fragmentOrElement] = openingElement; node['closing' + fragmentOrElement] = closingElement; node.children = children; if (this.type === tt.relational && this.value === "<") { this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); } return this.finishNode(node, 'JSX' + fragmentOrElement); } // Parse JSX text }, { key: 'jsx_parseText', value: function jsx_parseText(value) { var node = this.parseLiteral(value); node.type = "JSXText"; return node; } // Parses entire JSX element from current position. }, { key: 'jsx_parseElement', value: function jsx_parseElement() { var startPos = this.start, startLoc = this.startLoc; this.next(); return this.jsx_parseElementAt(startPos, startLoc); } }, { key: 'parseExprAtom', value: function parseExprAtom(refShortHandDefaultPos) { if (this.type === tok.jsxText) return this.jsx_parseText(this.value);else if (this.type === tok.jsxTagStart) return this.jsx_parseElement();else return _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'parseExprAtom', this).call(this, refShortHandDefaultPos); } }, { key: 'readToken', value: function readToken(code) { var context = this.curContext(); if (context === tc_expr) return this.jsx_readToken(); if (context === tc_oTag || context === tc_cTag) { if (isIdentifierStart(code)) return this.jsx_readWord(); if (code == 62) { ++this.pos; return this.finishToken(tok.jsxTagEnd); } if ((code === 34 || code === 39) && context == tc_oTag) return this.jsx_readString(code); } if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) { ++this.pos; return this.finishToken(tok.jsxTagStart); } return _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'readToken', this).call(this, code); } }, { key: 'updateContext', value: function updateContext(prevType) { if (this.type == tt.braceL) { var curContext = this.curContext(); if (curContext == tc_oTag) this.context.push(tokContexts.b_expr);else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl);else _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'updateContext', this).call(this, prevType); this.exprAllowed = true; } else if (this.type === tt.slash && prevType === tok.jsxTagStart) { this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore this.context.push(tc_cTag); // reconsider as closing tag context this.exprAllowed = false; } else { return _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'updateContext', this).call(this, prevType); } } }]); return _class; }(Parser); } },{"./xhtml":2,"acorn":3}],2:[function(require,module,exports){ 'use strict'; module.exports = { quot: '"', amp: '&', apos: '\'', lt: '<', gt: '>', nbsp: '\xA0', iexcl: '\xA1', cent: '\xA2', pound: '\xA3', curren: '\xA4', yen: '\xA5', brvbar: '\xA6', sect: '\xA7', uml: '\xA8', copy: '\xA9', ordf: '\xAA', laquo: '\xAB', not: '\xAC', shy: '\xAD', reg: '\xAE', macr: '\xAF', deg: '\xB0', plusmn: '\xB1', sup2: '\xB2', sup3: '\xB3', acute: '\xB4', micro: '\xB5', para: '\xB6', middot: '\xB7', cedil: '\xB8', sup1: '\xB9', ordm: '\xBA', raquo: '\xBB', frac14: '\xBC', frac12: '\xBD', frac34: '\xBE', iquest: '\xBF', Agrave: '\xC0', Aacute: '\xC1', Acirc: '\xC2', Atilde: '\xC3', Auml: '\xC4', Aring: '\xC5', AElig: '\xC6', Ccedil: '\xC7', Egrave: '\xC8', Eacute: '\xC9', Ecirc: '\xCA', Euml: '\xCB', Igrave: '\xCC', Iacute: '\xCD', Icirc: '\xCE', Iuml: '\xCF', ETH: '\xD0', Ntilde: '\xD1', Ograve: '\xD2', Oacute: '\xD3', Ocirc: '\xD4', Otilde: '\xD5', Ouml: '\xD6', times: '\xD7', Oslash: '\xD8', Ugrave: '\xD9', Uacute: '\xDA', Ucirc: '\xDB', Uuml: '\xDC', Yacute: '\xDD', THORN: '\xDE', szlig: '\xDF', agrave: '\xE0', aacute: '\xE1', acirc: '\xE2', atilde: '\xE3', auml: '\xE4', aring: '\xE5', aelig: '\xE6', ccedil: '\xE7', egrave: '\xE8', eacute: '\xE9', ecirc: '\xEA', euml: '\xEB', igrave: '\xEC', iacute: '\xED', icirc: '\xEE', iuml: '\xEF', eth: '\xF0', ntilde: '\xF1', ograve: '\xF2', oacute: '\xF3', ocirc: '\xF4', otilde: '\xF5', ouml: '\xF6', divide: '\xF7', oslash: '\xF8', ugrave: '\xF9', uacute: '\xFA', ucirc: '\xFB', uuml: '\xFC', yacute: '\xFD', thorn: '\xFE', yuml: '\xFF', OElig: '\u0152', oelig: '\u0153', Scaron: '\u0160', scaron: '\u0161', Yuml: '\u0178', fnof: '\u0192', circ: '\u02C6', tilde: '\u02DC', Alpha: '\u0391', Beta: '\u0392', Gamma: '\u0393', Delta: '\u0394', Epsilon: '\u0395', Zeta: '\u0396', Eta: '\u0397', Theta: '\u0398', Iota: '\u0399', Kappa: '\u039A', Lambda: '\u039B', Mu: '\u039C', Nu: '\u039D', Xi: '\u039E', Omicron: '\u039F', Pi: '\u03A0', Rho: '\u03A1', Sigma: '\u03A3', Tau: '\u03A4', Upsilon: '\u03A5', Phi: '\u03A6', Chi: '\u03A7', Psi: '\u03A8', Omega: '\u03A9', alpha: '\u03B1', beta: '\u03B2', gamma: '\u03B3', delta: '\u03B4', epsilon: '\u03B5', zeta: '\u03B6', eta: '\u03B7', theta: '\u03B8', iota: '\u03B9', kappa: '\u03BA', lambda: '\u03BB', mu: '\u03BC', nu: '\u03BD', xi: '\u03BE', omicron: '\u03BF', pi: '\u03C0', rho: '\u03C1', sigmaf: '\u03C2', sigma: '\u03C3', tau: '\u03C4', upsilon: '\u03C5', phi: '\u03C6', chi: '\u03C7', psi: '\u03C8', omega: '\u03C9', thetasym: '\u03D1', upsih: '\u03D2', piv: '\u03D6', ensp: '\u2002', emsp: '\u2003', thinsp: '\u2009', zwnj: '\u200C', zwj: '\u200D', lrm: '\u200E', rlm: '\u200F', ndash: '\u2013', mdash: '\u2014', lsquo: '\u2018', rsquo: '\u2019', sbquo: '\u201A', ldquo: '\u201C', rdquo: '\u201D', bdquo: '\u201E', dagger: '\u2020', Dagger: '\u2021', bull: '\u2022', hellip: '\u2026', permil: '\u2030', prime: '\u2032', Prime: '\u2033', lsaquo: '\u2039', rsaquo: '\u203A', oline: '\u203E', frasl: '\u2044', euro: '\u20AC', image: '\u2111', weierp: '\u2118', real: '\u211C', trade: '\u2122', alefsym: '\u2135', larr: '\u2190', uarr: '\u2191', rarr: '\u2192', darr: '\u2193', harr: '\u2194', crarr: '\u21B5', lArr: '\u21D0', uArr: '\u21D1', rArr: '\u21D2', dArr: '\u21D3', hArr: '\u21D4', forall: '\u2200', part: '\u2202', exist: '\u2203', empty: '\u2205', nabla: '\u2207', isin: '\u2208', notin: '\u2209', ni: '\u220B', prod: '\u220F', sum: '\u2211', minus: '\u2212', lowast: '\u2217', radic: '\u221A', prop: '\u221D', infin: '\u221E', ang: '\u2220', and: '\u2227', or: '\u2228', cap: '\u2229', cup: '\u222A', 'int': '\u222B', there4: '\u2234', sim: '\u223C', cong: '\u2245', asymp: '\u2248', ne: '\u2260', equiv: '\u2261', le: '\u2264', ge: '\u2265', sub: '\u2282', sup: '\u2283', nsub: '\u2284', sube: '\u2286', supe: '\u2287', oplus: '\u2295', otimes: '\u2297', perp: '\u22A5', sdot: '\u22C5', lceil: '\u2308', rceil: '\u2309', lfloor: '\u230A', rfloor: '\u230B', lang: '\u2329', rang: '\u232A', loz: '\u25CA', spades: '\u2660', clubs: '\u2663', hearts: '\u2665', diams: '\u2666' }; },{}],3:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; (function (global, factory) { (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : factory(global.acorn = {}); })(undefined, function (exports) { 'use strict'; // Reserved word lists for various dialects of the language var reservedWords = { 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", 5: "class enum extends super const export import", 6: "enum", strict: "implements interface let package private protected public static yield", strictBind: "eval arguments" }; // And the keywords var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; var keywords = { 5: ecma5AndLessKeywords, 6: ecma5AndLessKeywords + " const class extends export import super" }; var keywordRelationalOperator = /^in(stanceof)?$/; // ## Character categories // Big ugly regular expressions that match characters in the // whitespace, identifier, and identifier-start categories. These // are only applied when a character is found to actually have a // code point above 128. // Generated by `bin/generate-identifier-regex.js`. var nonASCIIidentifierStartChars = '\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\u0560-\u0588\u05D0-\u05EA\u05EF-\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\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\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\u09FC\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\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\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-\u1878\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\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\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-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7B9\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\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\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'; var nonASCIIidentifierChars = '\u200C\u200D\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA8FF-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F'; var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; // These are a run-length and offset encoded representation of the // >0xffff code points that are a valid part of identifiers. The // offset starts at 0x10000, and each pair of numbers represents an // offset to the next range, and then a size of the range. They were // generated by bin/generate-identifier-regex.js // eslint-disable-next-line comma-spacing var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 477, 28, 11, 0, 9, 21, 190, 52, 76, 44, 33, 24, 27, 35, 30, 0, 12, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 54, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 86, 26, 230, 43, 117, 63, 32, 0, 257, 0, 11, 39, 8, 0, 22, 0, 12, 39, 3, 3, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 270, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 68, 12, 0, 67, 12, 65, 1, 31, 6129, 15, 754, 9486, 286, 82, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 60, 67, 1213, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541]; // eslint-disable-next-line comma-spacing var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 525, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 280, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 2214, 6, 110, 6, 6, 9, 792487, 239]; // This has a complexity linear to the value of the code. The // assumption is that looking up astral identifier characters is // rare. function isInAstralSet(code, set) { var pos = 0x10000; for (var i = 0; i < set.length; i += 2) { pos += set[i]; if (pos > code) { return false; } pos += set[i + 1]; if (pos >= code) { return true; } } } // Test whether a given character code starts an identifier. function isIdentifierStart(code, astral) { if (code < 65) { return code === 36; } if (code < 91) { return true; } if (code < 97) { return code === 95; } if (code < 123) { return true; } if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); } if (astral === false) { return false; } return isInAstralSet(code, astralIdentifierStartCodes); } // Test whether a given character is part of an identifier. function isIdentifierChar(code, astral) { if (code < 48) { return code === 36; } if (code < 58) { return true; } if (code < 65) { return false; } if (code < 91) { return true; } if (code < 97) { return code === 95; } if (code < 123) { return true; } if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); } if (astral === false) { return false; } return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); } // ## Token types // The assignment of fine-grained, information-carrying type objects // allows the tokenizer to store the information it has about a // token in a way that is very cheap for the parser to look up. // All token type variables start with an underscore, to make them // easy to recognize. // The `beforeExpr` property is used to disambiguate between regular // expressions and divisions. It is set on all token types that can // be followed by an expression (thus, a slash after them would be a // regular expression). // // The `startsExpr` property is used to check if the token ends a // `yield` expression. It is set on all token types that either can // directly start an expression (like a quotation mark) or can // continue an expression (like the body of a string). // // `isLoop` marks a keyword as starting a loop, which is important // to know when parsing a label, in order to allow or disallow // continue jumps to that label. var TokenType = function TokenType(label, conf) { if (conf === void 0) conf = {}; this.label = label; this.keyword = conf.keyword; this.beforeExpr = !!conf.beforeExpr; this.startsExpr = !!conf.startsExpr; this.isLoop = !!conf.isLoop; this.isAssign = !!conf.isAssign; this.prefix = !!conf.prefix; this.postfix = !!conf.postfix; this.binop = conf.binop || null; this.updateContext = null; }; function binop(name, prec) { return new TokenType(name, { beforeExpr: true, binop: prec }); } var beforeExpr = { beforeExpr: true }; var startsExpr = { startsExpr: true }; // Map keyword names to token types. var keywords$1 = {}; // Succinct definitions of keyword token types function kw(name, options) { if (options === void 0) options = {}; options.keyword = name; return keywords$1[name] = new TokenType(name, options); } var types = { num: new TokenType("num", startsExpr), regexp: new TokenType("regexp", startsExpr), string: new TokenType("string", startsExpr), name: new TokenType("name", startsExpr), eof: new TokenType("eof"), // Punctuation token types. bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }), bracketR: new TokenType("]"), braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }), braceR: new TokenType("}"), parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }), parenR: new TokenType(")"), comma: new TokenType(",", beforeExpr), semi: new TokenType(";", beforeExpr), colon: new TokenType(":", beforeExpr), dot: new TokenType("."), question: new TokenType("?", beforeExpr), arrow: new TokenType("=>", beforeExpr), template: new TokenType("template"), invalidTemplate: new TokenType("invalidTemplate"), ellipsis: new TokenType("...", beforeExpr), backQuote: new TokenType("`", startsExpr), dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }), // Operators. These carry several kinds of properties to help the // parser use them properly (the presence of these properties is // what categorizes them as operators). // // `binop`, when present, specifies that this operator is a binary // operator, and will refer to its precedence. // // `prefix` and `postfix` mark the operator as a prefix or postfix // unary operator. // // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as // binary operators with a very low precedence, that should result // in AssignmentExpression nodes. eq: new TokenType("=", { beforeExpr: true, isAssign: true }), assign: new TokenType("_=", { beforeExpr: true, isAssign: true }), incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }), prefix: new TokenType("!/~", { beforeExpr: true, prefix: true, startsExpr: true }), logicalOR: binop("||", 1), logicalAND: binop("&&", 2), bitwiseOR: binop("|", 3), bitwiseXOR: binop("^", 4), bitwiseAND: binop("&", 5), equality: binop("==/!=/===/!==", 6), relational: binop("/<=/>=", 7), bitShift: binop("<>/>>>", 8), plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }), modulo: binop("%", 10), star: binop("*", 10), slash: binop("/", 10), starstar: new TokenType("**", { beforeExpr: true }), // Keyword token types. _break: kw("break"), _case: kw("case", beforeExpr), _catch: kw("catch"), _continue: kw("continue"), _debugger: kw("debugger"), _default: kw("default", beforeExpr), _do: kw("do", { isLoop: true, beforeExpr: true }), _else: kw("else", beforeExpr), _finally: kw("finally"), _for: kw("for", { isLoop: true }), _function: kw("function", startsExpr), _if: kw("if"), _return: kw("return", beforeExpr), _switch: kw("switch"), _throw: kw("throw", beforeExpr), _try: kw("try"), _var: kw("var"), _const: kw("const"), _while: kw("while", { isLoop: true }), _with: kw("with"), _new: kw("new", { beforeExpr: true, startsExpr: true }), _this: kw("this", startsExpr), _super: kw("super", startsExpr), _class: kw("class", startsExpr), _extends: kw("extends", beforeExpr), _export: kw("export"), _import: kw("import"), _null: kw("null", startsExpr), _true: kw("true", startsExpr), _false: kw("false", startsExpr), _in: kw("in", { beforeExpr: true, binop: 7 }), _instanceof: kw("instanceof", { beforeExpr: true, binop: 7 }), _typeof: kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true }), _void: kw("void", { beforeExpr: true, prefix: true, startsExpr: true }), _delete: kw("delete", { beforeExpr: true, prefix: true, startsExpr: true }) }; // Matches a whole line break (where CRLF is considered a single // line break). Used to count lines. var lineBreak = /\r\n?|\n|\u2028|\u2029/; var lineBreakG = new RegExp(lineBreak.source, "g"); function isNewLine(code, ecma2019String) { return code === 10 || code === 13 || !ecma2019String && (code === 0x2028 || code === 0x2029); } var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; var ref = Object.prototype; var hasOwnProperty = ref.hasOwnProperty; var toString = ref.toString; // Checks if an object has a property. function has(obj, propName) { return hasOwnProperty.call(obj, propName); } var isArray = Array.isArray || function (obj) { return toString.call(obj) === "[object Array]"; }; // These are used when `options.locations` is on, for the // `startLoc` and `endLoc` properties. var Position = function Position(line, col) { this.line = line; this.column = col; }; Position.prototype.offset = function offset(n) { return new Position(this.line, this.column + n); }; var SourceLocation = function SourceLocation(p, start, end) { this.start = start; this.end = end; if (p.sourceFile !== null) { this.source = p.sourceFile; } }; // The `getLineInfo` function is mostly useful when the // `locations` option is off (for performance reasons) and you // want to find the line/column position for a given character // offset. `input` should be the code string that the offset refers // into. function getLineInfo(input, offset) { for (var line = 1, cur = 0;;) { lineBreakG.lastIndex = cur; var match = lineBreakG.exec(input); if (match && match.index < offset) { ++line; cur = match.index + match[0].length; } else { return new Position(line, offset - cur); } } } // A second optional argument can be given to further configure // the parser process. These options are recognized: var defaultOptions = { // `ecmaVersion` indicates the ECMAScript version to parse. Must be // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10 // (2019). This influences support for strict mode, the set of // reserved words, and support for new syntax features. The default // is 9. ecmaVersion: 9, // `sourceType` indicates the mode the code should be parsed in. // Can be either `"script"` or `"module"`. This influences global // strict mode and parsing of `import` and `export` declarations. sourceType: "script", // `onInsertedSemicolon` can be a callback that will be called // when a semicolon is automatically inserted. It will be passed // th position of the comma as an offset, and if `locations` is // enabled, it is given the location as a `{line, column}` object // as second argument. onInsertedSemicolon: null, // `onTrailingComma` is similar to `onInsertedSemicolon`, but for // trailing commas. onTrailingComma: null, // By default, reserved words are only enforced if ecmaVersion >= 5. // Set `allowReserved` to a boolean value to explicitly turn this on // an off. When this option has the value "never", reserved words // and keywords can also not be used as property names. allowReserved: null, // When enabled, a return at the top level is not considered an // error. allowReturnOutsideFunction: false, // When enabled, import/export statements are not constrained to // appearing at the top of the program. allowImportExportEverywhere: false, // When enabled, await identifiers are allowed to appear at the top-level scope, // but they are still not allowed in non-async functions. allowAwaitOutsideFunction: false, // When enabled, hashbang directive in the beginning of file // is allowed and treated as a line comment. allowHashBang: false, // When `locations` is on, `loc` properties holding objects with // `start` and `end` properties in `{line, column}` form (with // line being 1-based and column 0-based) will be attached to the // nodes. locations: false, // A function can be passed as `onToken` option, which will // cause Acorn to call that function with object in the same // format as tokens returned from `tokenizer().getToken()`. Note // that you are not allowed to call the parser from the // callback—that will corrupt its internal state. onToken: null, // A function can be passed as `onComment` option, which will // cause Acorn to call that function with `(block, text, start, // end)` parameters whenever a comment is skipped. `block` is a // boolean indicating whether this is a block (`/* */`) comment, // `text` is the content of the comment, and `start` and `end` are // character offsets that denote the start and end of the comment. // When the `locations` option is on, two more parameters are // passed, the full `{line, column}` locations of the start and // end of the comments. Note that you are not allowed to call the // parser from the callback—that will corrupt its internal state. onComment: null, // Nodes have their start and end characters offsets recorded in // `start` and `end` properties (directly on the node, rather than // the `loc` object, which holds line/column data. To also add a // [semi-standardized][range] `range` property holding a `[start, // end]` array with the same numbers, set the `ranges` option to // `true`. // // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 ranges: false, // It is possible to parse multiple files into a single AST by // passing the tree produced by parsing the first file as // `program` option in subsequent parses. This will add the // toplevel forms of the parsed file to the `Program` (top) node // of an existing parse tree. program: null, // When `locations` is on, you can pass this to record the source // file in every node's `loc` object. sourceFile: null, // This value, if given, is stored in every node, whether // `locations` is on or off. directSourceFile: null, // When enabled, parenthesized expressions are represented by // (non-standard) ParenthesizedExpression nodes preserveParens: false }; // Interpret and default an options object function getOptions(opts) { var options = {}; for (var opt in defaultOptions) { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } if (options.ecmaVersion >= 2015) { options.ecmaVersion -= 2009; } if (options.allowReserved == null) { options.allowReserved = options.ecmaVersion < 5; } if (isArray(options.onToken)) { var tokens = options.onToken; options.onToken = function (token) { return tokens.push(token); }; } if (isArray(options.onComment)) { options.onComment = pushComment(options, options.onComment); } return options; } function pushComment(options, array) { return function (block, text, start, end, startLoc, endLoc) { var comment = { type: block ? "Block" : "Line", value: text, start: start, end: end }; if (options.locations) { comment.loc = new SourceLocation(this, startLoc, endLoc); } if (options.ranges) { comment.range = [start, end]; } array.push(comment); }; } // Each scope gets a bitset that may contain these flags var SCOPE_TOP = 1; var SCOPE_FUNCTION = 2; var SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION; var SCOPE_ASYNC = 4; var SCOPE_GENERATOR = 8; var SCOPE_ARROW = 16; var SCOPE_SIMPLE_CATCH = 32; var SCOPE_SUPER = 64; var SCOPE_DIRECT_SUPER = 128; function functionFlags(async, generator) { return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0); } // Used in checkLVal and declareName to determine the type of a binding var BIND_NONE = 0; var BIND_VAR = 1; var BIND_LEXICAL = 2; var BIND_FUNCTION = 3; var BIND_SIMPLE_CATCH = 4; var BIND_OUTSIDE = 5; // Special case for function names as bound inside the function function keywordRegexp(words) { return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$"); } var Parser = function Parser(options, input, startPos) { this.options = options = getOptions(options); this.sourceFile = options.sourceFile; this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]); var reserved = ""; if (!options.allowReserved) { for (var v = options.ecmaVersion;; v--) { if (reserved = reservedWords[v]) { break; } } if (options.sourceType === "module") { reserved += " await"; } } this.reservedWords = keywordRegexp(reserved); var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; this.reservedWordsStrict = keywordRegexp(reservedStrict); this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind); this.input = String(input); // Used to signal to callers of `readWord1` whether the word // contained any escape sequences. This is needed because words with // escape sequences must not be interpreted as keywords. this.containsEsc = false; // Set up token state // The current position of the tokenizer in the input. if (startPos) { this.pos = startPos; this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; } else { this.pos = this.lineStart = 0; this.curLine = 1; } // Properties of the current token: // Its type this.type = types.eof; // For tokens that include more information than their type, the value this.value = null; // Its start and end offset this.start = this.end = this.pos; // And, if locations are used, the {line, column} object // corresponding to those offsets this.startLoc = this.endLoc = this.curPosition(); // Position information for the previous token this.lastTokEndLoc = this.lastTokStartLoc = null; this.lastTokStart = this.lastTokEnd = this.pos; // The context stack is used to superficially track syntactic // context to predict whether a regular expression is allowed in a // given position. this.context = this.initialContext(); this.exprAllowed = true; // Figure out if it's a module code. this.inModule = options.sourceType === "module"; this.strict = this.inModule || this.strictDirective(this.pos); // Used to signify the start of a potential arrow function this.potentialArrowAt = -1; // Positions to delayed-check that yield/await does not exist in default parameters. this.yieldPos = this.awaitPos = 0; // Labels in scope. this.labels = []; // If enabled, skip leading hashbang line. if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") { this.skipLineComment(2); } // Scope tracking for duplicate variable names (see scope.js) this.scopeStack = []; this.enterScope(SCOPE_TOP); // For RegExp validation this.regexpState = null; }; var prototypeAccessors = { inFunction: { configurable: true }, inGenerator: { configurable: true }, inAsync: { configurable: true }, allowSuper: { configurable: true }, allowDirectSuper: { configurable: true } }; Parser.prototype.parse = function parse() { var node = this.options.program || this.startNode(); this.nextToken(); return this.parseTopLevel(node); }; prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0; }; prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0; }; prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0; }; prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0; }; prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0; }; // Switch to a getter for 7.0.0. Parser.prototype.inNonArrowFunction = function inNonArrowFunction() { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0; }; Parser.extend = function extend() { var plugins = [], len = arguments.length; while (len--) { plugins[len] = arguments[len]; }var cls = this; for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } return cls; }; Parser.parse = function parse(input, options) { return new this(options, input).parse(); }; Parser.parseExpressionAt = function parseExpressionAt(input, pos, options) { var parser = new this(options, input, pos); parser.nextToken(); return parser.parseExpression(); }; Parser.tokenizer = function tokenizer(input, options) { return new this(options, input); }; Object.defineProperties(Parser.prototype, prototypeAccessors); var pp = Parser.prototype; // ## Parser utilities var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; pp.strictDirective = function (start) { var this$1 = this; for (;;) { skipWhiteSpace.lastIndex = start; start += skipWhiteSpace.exec(this$1.input)[0].length; var match = literal.exec(this$1.input.slice(start)); if (!match) { return false; } if ((match[1] || match[2]) === "use strict") { return true; } start += match[0].length; } }; // Predicate that tests whether the next token is of the given // type, and if yes, consumes it as a side effect. pp.eat = function (type) { if (this.type === type) { this.next(); return true; } else { return false; } }; // Tests whether parsed token is a contextual keyword. pp.isContextual = function (name) { return this.type === types.name && this.value === name && !this.containsEsc; }; // Consumes contextual keyword if possible. pp.eatContextual = function (name) { if (!this.isContextual(name)) { return false; } this.next(); return true; }; // Asserts that following token is given contextual keyword. pp.expectContextual = function (name) { if (!this.eatContextual(name)) { this.unexpected(); } }; // Test whether a semicolon can be inserted at the current position. pp.canInsertSemicolon = function () { return this.type === types.eof || this.type === types.braceR || lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); }; pp.insertSemicolon = function () { if (this.canInsertSemicolon()) { if (this.options.onInsertedSemicolon) { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } return true; } }; // Consume a semicolon, or, failing that, see if we are allowed to // pretend that there is a semicolon at this position. pp.semicolon = function () { if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } }; pp.afterTrailingComma = function (tokType, notNext) { if (this.type === tokType) { if (this.options.onTrailingComma) { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } if (!notNext) { this.next(); } return true; } }; // Expect a token of a given type. If found, consume it, otherwise, // raise an unexpected token error. pp.expect = function (type) { this.eat(type) || this.unexpected(); }; // Raise an unexpected token error. pp.unexpected = function (pos) { this.raise(pos != null ? pos : this.start, "Unexpected token"); }; function DestructuringErrors() { this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = this.doubleProto = -1; } pp.checkPatternErrors = function (refDestructuringErrors, isAssign) { if (!refDestructuringErrors) { return; } if (refDestructuringErrors.trailingComma > -1) { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } }; pp.checkExpressionErrors = function (refDestructuringErrors, andThrow) { if (!refDestructuringErrors) { return false; } var shorthandAssign = refDestructuringErrors.shorthandAssign; var doubleProto = refDestructuringErrors.doubleProto; if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0; } if (shorthandAssign >= 0) { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } if (doubleProto >= 0) { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } }; pp.checkYieldAwaitInDefaultParams = function () { if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } if (this.awaitPos) { this.raise(this.awaitPos, "Await expression cannot be a default value"); } }; pp.isSimpleAssignTarget = function (expr) { if (expr.type === "ParenthesizedExpression") { return this.isSimpleAssignTarget(expr.expression); } return expr.type === "Identifier" || expr.type === "MemberExpression"; }; var pp$1 = Parser.prototype; // ### Statement parsing // Parse a program. Initializes the parser, reads any number of // statements, and wraps them in a Program node. Optionally takes a // `program` argument. If present, the statements will be appended // to its body instead of creating a new node. pp$1.parseTopLevel = function (node) { var this$1 = this; var exports = {}; if (!node.body) { node.body = []; } while (this.type !== types.eof) { var stmt = this$1.parseStatement(null, true, exports); node.body.push(stmt); } this.adaptDirectivePrologue(node.body); this.next(); if (this.options.ecmaVersion >= 6) { node.sourceType = this.options.sourceType; } return this.finishNode(node, "Program"); }; var loopLabel = { kind: "loop" }; var switchLabel = { kind: "switch" }; pp$1.isLet = function () { if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false; } skipWhiteSpace.lastIndex = this.pos; var skip = skipWhiteSpace.exec(this.input); var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); if (nextCh === 91 || nextCh === 123) { return true; } // '{' and '[' if (isIdentifierStart(nextCh, true)) { var pos = next + 1; while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } var ident = this.input.slice(next, pos); if (!keywordRelationalOperator.test(ident)) { return true; } } return false; }; // check 'async [no LineTerminator here] function' // - 'async /*foo*/ function' is OK. // - 'async /*\n*/ function' is invalid. pp$1.isAsyncFunction = function () { if (this.options.ecmaVersion < 8 || !this.isContextual("async")) { return false; } skipWhiteSpace.lastIndex = this.pos; var skip = skipWhiteSpace.exec(this.input); var next = this.pos + skip[0].length; return !lineBreak.test(this.input.slice(this.pos, next)) && this.input.slice(next, next + 8) === "function" && (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8))); }; // Parse a single statement. // // If expecting a statement and finding a slash operator, parse a // regular expression literal. This is to handle cases like // `if (foo) /blah/.exec(foo)`, where looking at the previous token // does not help. pp$1.parseStatement = function (context, topLevel, exports) { var starttype = this.type, node = this.startNode(), kind; if (this.isLet()) { starttype = types._var; kind = "let"; } // Most types of statements are recognized by the keyword they // start with. Many are trivial to parse, some require a bit of // complexity. switch (starttype) { case types._break:case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword); case types._debugger: return this.parseDebuggerStatement(node); case types._do: return this.parseDoStatement(node); case types._for: return this.parseForStatement(node); case types._function: if (context && (this.strict || context !== "if") && this.options.ecmaVersion >= 6) { this.unexpected(); } return this.parseFunctionStatement(node, false, !context); case types._class: if (context) { this.unexpected(); } return this.parseClass(node, true); case types._if: return this.parseIfStatement(node); case types._return: return this.parseReturnStatement(node); case types._switch: return this.parseSwitchStatement(node); case types._throw: return this.parseThrowStatement(node); case types._try: return this.parseTryStatement(node); case types._const:case types._var: kind = kind || this.value; if (context && kind !== "var") { this.unexpected(); } return this.parseVarStatement(node, kind); case types._while: return this.parseWhileStatement(node); case types._with: return this.parseWithStatement(node); case types.braceL: return this.parseBlock(true, node); case types.semi: return this.parseEmptyStatement(node); case types._export: case types._import: if (!this.options.allowImportExportEverywhere) { if (!topLevel) { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } if (!this.inModule) { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } } return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports); // If the statement does not start with a statement keyword or a // brace, it's an ExpressionStatement or LabeledStatement. We // simply start parsing an expression, and afterwards, if the // next token is a colon and the expression was a simple // Identifier node, we switch to interpreting it as a label. default: if (this.isAsyncFunction()) { if (context) { this.unexpected(); } this.next(); return this.parseFunctionStatement(node, true, !context); } var maybeName = this.value, expr = this.parseExpression(); if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) { return this.parseLabeledStatement(node, maybeName, expr, context); } else { return this.parseExpressionStatement(node, expr); } } }; pp$1.parseBreakContinueStatement = function (node, keyword) { var this$1 = this; var isBreak = keyword === "break"; this.next(); if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } else if (this.type !== types.name) { this.unexpected(); } else { node.label = this.parseIdent(); this.semicolon(); } // Verify that there is an actual destination to break or // continue to. var i = 0; for (; i < this.labels.length; ++i) { var lab = this$1.labels[i]; if (node.label == null || lab.name === node.label.name) { if (lab.kind != null && (isBreak || lab.kind === "loop")) { break; } if (node.label && isBreak) { break; } } } if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); }; pp$1.parseDebuggerStatement = function (node) { this.next(); this.semicolon(); return this.finishNode(node, "DebuggerStatement"); }; pp$1.parseDoStatement = function (node) { this.next(); this.labels.push(loopLabel); node.body = this.parseStatement("do"); this.labels.pop(); this.expect(types._while); node.test = this.parseParenExpression(); if (this.options.ecmaVersion >= 6) { this.eat(types.semi); } else { this.semicolon(); } return this.finishNode(node, "DoWhileStatement"); }; // Disambiguating between a `for` and a `for`/`in` or `for`/`of` // loop is non-trivial. Basically, we have to parse the init `var` // statement or expression, disallowing the `in` operator (see // the second parameter to `parseExpression`), and then check // whether the next token is `in` or `of`. When there is no init // part (semicolon immediately after the opening parenthesis), it // is a regular `for` loop. pp$1.parseForStatement = function (node) { this.next(); var awaitAt = this.options.ecmaVersion >= 9 && (this.inAsync || !this.inFunction && this.options.allowAwaitOutsideFunction) && this.eatContextual("await") ? this.lastTokStart : -1; this.labels.push(loopLabel); this.enterScope(0); this.expect(types.parenL); if (this.type === types.semi) { if (awaitAt > -1) { this.unexpected(awaitAt); } return this.parseFor(node, null); } var isLet = this.isLet(); if (this.type === types._var || this.type === types._const || isLet) { var init$1 = this.startNode(), kind = isLet ? "let" : this.value; this.next(); this.parseVar(init$1, true, kind); this.finishNode(init$1, "VariableDeclaration"); if ((this.type === types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && init$1.declarations.length === 1 && !(kind !== "var" && init$1.declarations[0].init)) { if (this.options.ecmaVersion >= 9) { if (this.type === types._in) { if (awaitAt > -1) { this.unexpected(awaitAt); } } else { node.await = awaitAt > -1; } } return this.parseForIn(node, init$1); } if (awaitAt > -1) { this.unexpected(awaitAt); } return this.parseFor(node, init$1); } var refDestructuringErrors = new DestructuringErrors(); var init = this.parseExpression(true, refDestructuringErrors); if (this.type === types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) { if (this.options.ecmaVersion >= 9) { if (this.type === types._in) { if (awaitAt > -1) { this.unexpected(awaitAt); } } else { node.await = awaitAt > -1; } } this.toAssignable(init, false, refDestructuringErrors); this.checkLVal(init); return this.parseForIn(node, init); } else { this.checkExpressionErrors(refDestructuringErrors, true); } if (awaitAt > -1) { this.unexpected(awaitAt); } return this.parseFor(node, init); }; pp$1.parseFunctionStatement = function (node, isAsync, declarationPosition) { this.next(); return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync); }; pp$1.parseIfStatement = function (node) { this.next(); node.test = this.parseParenExpression(); // allow function declarations in branches, but only in non-strict mode node.consequent = this.parseStatement("if"); node.alternate = this.eat(types._else) ? this.parseStatement("if") : null; return this.finishNode(node, "IfStatement"); }; pp$1.parseReturnStatement = function (node) { if (!this.inFunction && !this.options.allowReturnOutsideFunction) { this.raise(this.start, "'return' outside of function"); } this.next(); // In `return` (and `break`/`continue`), the keywords with // optional arguments, we eagerly look for a semicolon or the // possibility to insert one. if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } else { node.argument = this.parseExpression();this.semicolon(); } return this.finishNode(node, "ReturnStatement"); }; pp$1.parseSwitchStatement = function (node) { var this$1 = this; this.next(); node.discriminant = this.parseParenExpression(); node.cases = []; this.expect(types.braceL); this.labels.push(switchLabel); this.enterScope(0); // Statements under must be grouped (by label) in SwitchCase // nodes. `cur` is used to keep the node that we are currently // adding statements to. var cur; for (var sawDefault = false; this.type !== types.braceR;) { if (this$1.type === types._case || this$1.type === types._default) { var isCase = this$1.type === types._case; if (cur) { this$1.finishNode(cur, "SwitchCase"); } node.cases.push(cur = this$1.startNode()); cur.consequent = []; this$1.next(); if (isCase) { cur.test = this$1.parseExpression(); } else { if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } sawDefault = true; cur.test = null; } this$1.expect(types.colon); } else { if (!cur) { this$1.unexpected(); } cur.consequent.push(this$1.parseStatement(null)); } } this.exitScope(); if (cur) { this.finishNode(cur, "SwitchCase"); } this.next(); // Closing brace this.labels.pop(); return this.finishNode(node, "SwitchStatement"); }; pp$1.parseThrowStatement = function (node) { this.next(); if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) { this.raise(this.lastTokEnd, "Illegal newline after throw"); } node.argument = this.parseExpression(); this.semicolon(); return this.finishNode(node, "ThrowStatement"); }; // Reused empty array added for node fields that are always empty. var empty = []; pp$1.parseTryStatement = function (node) { this.next(); node.block = this.parseBlock(); node.handler = null; if (this.type === types._catch) { var clause = this.startNode(); this.next(); if (this.eat(types.parenL)) { clause.param = this.parseBindingAtom(); var simple = clause.param.type === "Identifier"; this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); this.expect(types.parenR); } else { if (this.options.ecmaVersion < 10) { this.unexpected(); } clause.param = null; this.enterScope(0); } clause.body = this.parseBlock(false); this.exitScope(); node.handler = this.finishNode(clause, "CatchClause"); } node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; if (!node.handler && !node.finalizer) { this.raise(node.start, "Missing catch or finally clause"); } return this.finishNode(node, "TryStatement"); }; pp$1.parseVarStatement = function (node, kind) { this.next(); this.parseVar(node, false, kind); this.semicolon(); return this.finishNode(node, "VariableDeclaration"); }; pp$1.parseWhileStatement = function (node) { this.next(); node.test = this.parseParenExpression(); this.labels.push(loopLabel); node.body = this.parseStatement("while"); this.labels.pop(); return this.finishNode(node, "WhileStatement"); }; pp$1.parseWithStatement = function (node) { if (this.strict) { this.raise(this.start, "'with' in strict mode"); } this.next(); node.object = this.parseParenExpression(); node.body = this.parseStatement("with"); return this.finishNode(node, "WithStatement"); }; pp$1.parseEmptyStatement = function (node) { this.next(); return this.finishNode(node, "EmptyStatement"); }; pp$1.parseLabeledStatement = function (node, maybeName, expr, context) { var this$1 = this; for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1) { var label = list[i$1]; if (label.name === maybeName) { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); } } var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; for (var i = this.labels.length - 1; i >= 0; i--) { var label$1 = this$1.labels[i]; if (label$1.statementStart === node.start) { // Update information about previous labels on this node label$1.statementStart = this$1.start; label$1.kind = kind; } else { break; } } this.labels.push({ name: maybeName, kind: kind, statementStart: this.start }); node.body = this.parseStatement(context); if (node.body.type === "ClassDeclaration" || node.body.type === "VariableDeclaration" && node.body.kind !== "var" || node.body.type === "FunctionDeclaration" && (this.strict || node.body.generator || node.body.async)) { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); } this.labels.pop(); node.label = expr; return this.finishNode(node, "LabeledStatement"); }; pp$1.parseExpressionStatement = function (node, expr) { node.expression = expr; this.semicolon(); return this.finishNode(node, "ExpressionStatement"); }; // Parse a semicolon-enclosed block of statements, handling `"use // strict"` declarations when `allowStrict` is true (used for // function bodies). pp$1.parseBlock = function (createNewLexicalScope, node) { var this$1 = this; if (createNewLexicalScope === void 0) createNewLexicalScope = true; if (node === void 0) node = this.startNode(); node.body = []; this.expect(types.braceL); if (createNewLexicalScope) { this.enterScope(0); } while (!this.eat(types.braceR)) { var stmt = this$1.parseStatement(null); node.body.push(stmt); } if (createNewLexicalScope) { this.exitScope(); } return this.finishNode(node, "BlockStatement"); }; // Parse a regular `for` loop. The disambiguation code in // `parseStatement` will already have parsed the init statement or // expression. pp$1.parseFor = function (node, init) { node.init = init; this.expect(types.semi); node.test = this.type === types.semi ? null : this.parseExpression(); this.expect(types.semi); node.update = this.type === types.parenR ? null : this.parseExpression(); this.expect(types.parenR); this.exitScope(); node.body = this.parseStatement("for"); this.labels.pop(); return this.finishNode(node, "ForStatement"); }; // Parse a `for`/`in` and `for`/`of` loop, which are almost // same from parser's perspective. pp$1.parseForIn = function (node, init) { var type = this.type === types._in ? "ForInStatement" : "ForOfStatement"; this.next(); if (type === "ForInStatement") { if (init.type === "AssignmentPattern" || init.type === "VariableDeclaration" && init.declarations[0].init != null && (this.strict || init.declarations[0].id.type !== "Identifier")) { this.raise(init.start, "Invalid assignment in for-in loop head"); } } node.left = init; node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); this.expect(types.parenR); this.exitScope(); node.body = this.parseStatement("for"); this.labels.pop(); return this.finishNode(node, type); }; // Parse a list of variable declarations. pp$1.parseVar = function (node, isFor, kind) { var this$1 = this; node.declarations = []; node.kind = kind; for (;;) { var decl = this$1.startNode(); this$1.parseVarId(decl, kind); if (this$1.eat(types.eq)) { decl.init = this$1.parseMaybeAssign(isFor); } else if (kind === "const" && !(this$1.type === types._in || this$1.options.ecmaVersion >= 6 && this$1.isContextual("of"))) { this$1.unexpected(); } else if (decl.id.type !== "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) { this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value"); } else { decl.init = null; } node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")); if (!this$1.eat(types.comma)) { break; } } return node; }; pp$1.parseVarId = function (decl, kind) { decl.id = this.parseBindingAtom(kind); this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); }; var FUNC_STATEMENT = 1; var FUNC_HANGING_STATEMENT = 2; var FUNC_NULLABLE_ID = 4; // Parse a function declaration or literal (depending on the // `isStatement` parameter). pp$1.parseFunction = function (node, statement, allowExpressionBody, isAsync) { this.initFunction(node); if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { node.generator = this.eat(types.star); } if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } if (statement & FUNC_STATEMENT) { node.id = statement & FUNC_NULLABLE_ID && this.type !== types.name ? null : this.parseIdent(); if (node.id && !(statement & FUNC_HANGING_STATEMENT)) { this.checkLVal(node.id, this.inModule && !this.inFunction ? BIND_LEXICAL : BIND_FUNCTION); } } var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos; this.yieldPos = 0; this.awaitPos = 0; this.enterScope(functionFlags(node.async, node.generator)); if (!(statement & FUNC_STATEMENT)) { node.id = this.type === types.name ? this.parseIdent() : null; } this.parseFunctionParams(node); this.parseFunctionBody(node, allowExpressionBody); this.yieldPos = oldYieldPos; this.awaitPos = oldAwaitPos; return this.finishNode(node, statement & FUNC_STATEMENT ? "FunctionDeclaration" : "FunctionExpression"); }; pp$1.parseFunctionParams = function (node) { this.expect(types.parenL); node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); this.checkYieldAwaitInDefaultParams(); }; // Parse a class declaration or literal (depending on the // `isStatement` parameter). pp$1.parseClass = function (node, isStatement) { var this$1 = this; this.next(); this.parseClassId(node, isStatement); this.parseClassSuper(node); var classBody = this.startNode(); var hadConstructor = false; classBody.body = []; this.expect(types.braceL); while (!this.eat(types.braceR)) { var element = this$1.parseClassElement(node.superClass !== null); if (element) { classBody.body.push(element); if (element.type === "MethodDefinition" && element.kind === "constructor") { if (hadConstructor) { this$1.raise(element.start, "Duplicate constructor in the same class"); } hadConstructor = true; } } } node.body = this.finishNode(classBody, "ClassBody"); return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); }; pp$1.parseClassElement = function (constructorAllowsSuper) { var this$1 = this; if (this.eat(types.semi)) { return null; } var method = this.startNode(); var tryContextual = function tryContextual(k, noLineBreak) { if (noLineBreak === void 0) noLineBreak = false; var start = this$1.start, startLoc = this$1.startLoc; if (!this$1.eatContextual(k)) { return false; } if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true; } if (method.key) { this$1.unexpected(); } method.computed = false; method.key = this$1.startNodeAt(start, startLoc); method.key.name = k; this$1.finishNode(method.key, "Identifier"); return false; }; method.kind = "method"; method.static = tryContextual("static"); var isGenerator = this.eat(types.star); var isAsync = false; if (!isGenerator) { if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { isAsync = true; isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); } else if (tryContextual("get")) { method.kind = "get"; } else if (tryContextual("set")) { method.kind = "set"; } } if (!method.key) { this.parsePropertyName(method); } var key = method.key; var allowsDirectSuper = false; if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) { if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } method.kind = "constructor"; allowsDirectSuper = constructorAllowsSuper; } else if (method.static && key.type === "Identifier" && key.name === "prototype") { this.raise(key.start, "Classes may not have a static property named prototype"); } this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper); if (method.kind === "get" && method.value.params.length !== 0) { this.raiseRecoverable(method.value.start, "getter should have no params"); } if (method.kind === "set" && method.value.params.length !== 1) { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } if (method.kind === "set" && method.value.params[0].type === "RestElement") { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } return method; }; pp$1.parseClassMethod = function (method, isGenerator, isAsync, allowsDirectSuper) { method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); return this.finishNode(method, "MethodDefinition"); }; pp$1.parseClassId = function (node, isStatement) { node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; }; pp$1.parseClassSuper = function (node) { node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; }; // Parses module export declaration. pp$1.parseExport = function (node, exports) { var this$1 = this; this.next(); // export * from '...' if (this.eat(types.star)) { this.expectContextual("from"); if (this.type !== types.string) { this.unexpected(); } node.source = this.parseExprAtom(); this.semicolon(); return this.finishNode(node, "ExportAllDeclaration"); } if (this.eat(types._default)) { // export default ... this.checkExport(exports, "default", this.lastTokStart); var isAsync; if (this.type === types._function || (isAsync = this.isAsyncFunction())) { var fNode = this.startNode(); this.next(); if (isAsync) { this.next(); } node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync, true); } else if (this.type === types._class) { var cNode = this.startNode(); node.declaration = this.parseClass(cNode, "nullableID"); } else { node.declaration = this.parseMaybeAssign(); this.semicolon(); } return this.finishNode(node, "ExportDefaultDeclaration"); } // export var|const|let|function|class ... if (this.shouldParseExportStatement()) { node.declaration = this.parseStatement(null); if (node.declaration.type === "VariableDeclaration") { this.checkVariableExport(exports, node.declaration.declarations); } else { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } node.specifiers = []; node.source = null; } else { // export { x, y as z } [from '...'] node.declaration = null; node.specifiers = this.parseExportSpecifiers(exports); if (this.eatContextual("from")) { if (this.type !== types.string) { this.unexpected(); } node.source = this.parseExprAtom(); } else { // check for keywords used as local names for (var i = 0, list = node.specifiers; i < list.length; i += 1) { var spec = list[i]; this$1.checkUnreserved(spec.local); } node.source = null; } this.semicolon(); } return this.finishNode(node, "ExportNamedDeclaration"); }; pp$1.checkExport = function (exports, name, pos) { if (!exports) { return; } if (has(exports, name)) { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } exports[name] = true; }; pp$1.checkPatternExport = function (exports, pat) { var this$1 = this; var type = pat.type; if (type === "Identifier") { this.checkExport(exports, pat.name, pat.start); } else if (type === "ObjectPattern") { for (var i = 0, list = pat.properties; i < list.length; i += 1) { var prop = list[i]; this$1.checkPatternExport(exports, prop); } } else if (type === "ArrayPattern") { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { var elt = list$1[i$1]; if (elt) { this$1.checkPatternExport(exports, elt); } } } else if (type === "Property") { this.checkPatternExport(exports, pat.value); } else if (type === "AssignmentPattern") { this.checkPatternExport(exports, pat.left); } else if (type === "RestElement") { this.checkPatternExport(exports, pat.argument); } else if (type === "ParenthesizedExpression") { this.checkPatternExport(exports, pat.expression); } }; pp$1.checkVariableExport = function (exports, decls) { var this$1 = this; if (!exports) { return; } for (var i = 0, list = decls; i < list.length; i += 1) { var decl = list[i]; this$1.checkPatternExport(exports, decl.id); } }; pp$1.shouldParseExportStatement = function () { return this.type.keyword === "var" || this.type.keyword === "const" || this.type.keyword === "class" || this.type.keyword === "function" || this.isLet() || this.isAsyncFunction(); }; // Parses a comma-separated list of module exports. pp$1.parseExportSpecifiers = function (exports) { var this$1 = this; var nodes = [], first = true; // export { x, y as z } [from '...'] this.expect(types.braceL); while (!this.eat(types.braceR)) { if (!first) { this$1.expect(types.comma); if (this$1.afterTrailingComma(types.braceR)) { break; } } else { first = false; } var node = this$1.startNode(); node.local = this$1.parseIdent(true); node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local; this$1.checkExport(exports, node.exported.name, node.exported.start); nodes.push(this$1.finishNode(node, "ExportSpecifier")); } return nodes; }; // Parses import declaration. pp$1.parseImport = function (node) { this.next(); // import '...' if (this.type === types.string) { node.specifiers = empty; node.source = this.parseExprAtom(); } else { node.specifiers = this.parseImportSpecifiers(); this.expectContextual("from"); node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); } this.semicolon(); return this.finishNode(node, "ImportDeclaration"); }; // Parses a comma-separated list of module imports. pp$1.parseImportSpecifiers = function () { var this$1 = this; var nodes = [], first = true; if (this.type === types.name) { // import defaultObj, { x, y as z } from '...' var node = this.startNode(); node.local = this.parseIdent(); this.checkLVal(node.local, BIND_LEXICAL); nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); if (!this.eat(types.comma)) { return nodes; } } if (this.type === types.star) { var node$1 = this.startNode(); this.next(); this.expectContextual("as"); node$1.local = this.parseIdent(); this.checkLVal(node$1.local, BIND_LEXICAL); nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); return nodes; } this.expect(types.braceL); while (!this.eat(types.braceR)) { if (!first) { this$1.expect(types.comma); if (this$1.afterTrailingComma(types.braceR)) { break; } } else { first = false; } var node$2 = this$1.startNode(); node$2.imported = this$1.parseIdent(true); if (this$1.eatContextual("as")) { node$2.local = this$1.parseIdent(); } else { this$1.checkUnreserved(node$2.imported); node$2.local = node$2.imported; } this$1.checkLVal(node$2.local, BIND_LEXICAL); nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); } return nodes; }; // Set `ExpressionStatement#directive` property for directive prologues. pp$1.adaptDirectivePrologue = function (statements) { for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { statements[i].directive = statements[i].expression.raw.slice(1, -1); } }; pp$1.isDirectiveCandidate = function (statement) { return statement.type === "ExpressionStatement" && statement.expression.type === "Literal" && typeof statement.expression.value === "string" && ( // Reject parenthesized strings. this.input[statement.start] === "\"" || this.input[statement.start] === "'"); }; var pp$2 = Parser.prototype; // Convert existing expression atom to assignable pattern // if possible. pp$2.toAssignable = function (node, isBinding, refDestructuringErrors) { var this$1 = this; if (this.options.ecmaVersion >= 6 && node) { switch (node.type) { case "Identifier": if (this.inAsync && node.name === "await") { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } break; case "ObjectPattern": case "ArrayPattern": case "RestElement": break; case "ObjectExpression": node.type = "ObjectPattern"; if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } for (var i = 0, list = node.properties; i < list.length; i += 1) { var prop = list[i]; this$1.toAssignable(prop, isBinding); // Early error: // AssignmentRestProperty[Yield, Await] : // `...` DestructuringAssignmentTarget[Yield, Await] // // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. if (prop.type === "RestElement" && (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")) { this$1.raise(prop.argument.start, "Unexpected token"); } } break; case "Property": // AssignmentProperty has type === "Property" if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } this.toAssignable(node.value, isBinding); break; case "ArrayExpression": node.type = "ArrayPattern"; if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } this.toAssignableList(node.elements, isBinding); break; case "SpreadElement": node.type = "RestElement"; this.toAssignable(node.argument, isBinding); if (node.argument.type === "AssignmentPattern") { this.raise(node.argument.start, "Rest elements cannot have a default value"); } break; case "AssignmentExpression": if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } node.type = "AssignmentPattern"; delete node.operator; this.toAssignable(node.left, isBinding); // falls through to AssignmentPattern case "AssignmentPattern": break; case "ParenthesizedExpression": this.toAssignable(node.expression, isBinding); break; case "MemberExpression": if (!isBinding) { break; } default: this.raise(node.start, "Assigning to rvalue"); } } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } return node; }; // Convert list of expression atoms to binding list. pp$2.toAssignableList = function (exprList, isBinding) { var this$1 = this; var end = exprList.length; for (var i = 0; i < end; i++) { var elt = exprList[i]; if (elt) { this$1.toAssignable(elt, isBinding); } } if (end) { var last = exprList[end - 1]; if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") { this.unexpected(last.argument.start); } } return exprList; }; // Parses spread element. pp$2.parseSpread = function (refDestructuringErrors) { var node = this.startNode(); this.next(); node.argument = this.parseMaybeAssign(false, refDestructuringErrors); return this.finishNode(node, "SpreadElement"); }; pp$2.parseRestBinding = function () { var node = this.startNode(); this.next(); // RestElement inside of a function parameter must be an identifier if (this.options.ecmaVersion === 6 && this.type !== types.name) { this.unexpected(); } node.argument = this.parseBindingAtom(); return this.finishNode(node, "RestElement"); }; // Parses lvalue (assignable) atom. pp$2.parseBindingAtom = function () { if (this.options.ecmaVersion >= 6) { switch (this.type) { case types.bracketL: var node = this.startNode(); this.next(); node.elements = this.parseBindingList(types.bracketR, true, true); return this.finishNode(node, "ArrayPattern"); case types.braceL: return this.parseObj(true); } } return this.parseIdent(); }; pp$2.parseBindingList = function (close, allowEmpty, allowTrailingComma) { var this$1 = this; var elts = [], first = true; while (!this.eat(close)) { if (first) { first = false; } else { this$1.expect(types.comma); } if (allowEmpty && this$1.type === types.comma) { elts.push(null); } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { break; } else if (this$1.type === types.ellipsis) { var rest = this$1.parseRestBinding(); this$1.parseBindingListItem(rest); elts.push(rest); if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } this$1.expect(close); break; } else { var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc); this$1.parseBindingListItem(elem); elts.push(elem); } } return elts; }; pp$2.parseBindingListItem = function (param) { return param; }; // Parses assignment pattern around given atom if possible. pp$2.parseMaybeDefault = function (startPos, startLoc, left) { left = left || this.parseBindingAtom(); if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left; } var node = this.startNodeAt(startPos, startLoc); node.left = left; node.right = this.parseMaybeAssign(); return this.finishNode(node, "AssignmentPattern"); }; // Verify that a node is an lval — something that can be assigned // to. // bindingType can be either: // 'var' indicating that the lval creates a 'var' binding // 'let' indicating that the lval creates a lexical ('let' or 'const') binding // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references pp$2.checkLVal = function (expr, bindingType, checkClashes) { var this$1 = this; if (bindingType === void 0) bindingType = BIND_NONE; switch (expr.type) { case "Identifier": if (this.strict && this.reservedWordsStrictBind.test(expr.name)) { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } if (checkClashes) { if (has(checkClashes, expr.name)) { this.raiseRecoverable(expr.start, "Argument name clash"); } checkClashes[expr.name] = true; } if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } break; case "MemberExpression": if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } break; case "ObjectPattern": for (var i = 0, list = expr.properties; i < list.length; i += 1) { var prop = list[i]; this$1.checkLVal(prop, bindingType, checkClashes); } break; case "Property": // AssignmentProperty has type === "Property" this.checkLVal(expr.value, bindingType, checkClashes); break; case "ArrayPattern": for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { var elem = list$1[i$1]; if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); } } break; case "AssignmentPattern": this.checkLVal(expr.left, bindingType, checkClashes); break; case "RestElement": this.checkLVal(expr.argument, bindingType, checkClashes); break; case "ParenthesizedExpression": this.checkLVal(expr.expression, bindingType, checkClashes); break; default: this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); } }; // A recursive descent parser operates by defining functions for all // syntactic elements, and recursively calling those, each function // advancing the input stream and returning an AST node. Precedence // of constructs (for example, the fact that `!x[1]` means `!(x[1])` // instead of `(!x)[1]` is handled by the fact that the parser // function that parses unary prefix operators is called first, and // in turn calls the function that parses `[]` subscripts — that // way, it'll receive the node for `x[1]` already parsed, and wraps // *that* in the unary operator node. // // Acorn uses an [operator precedence parser][opp] to handle binary // operator precedence, because it is much more compact than using // the technique outlined above, which uses different, nesting // functions to specify precedence, for all of the ten binary // precedence levels that JavaScript defines. // // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser var pp$3 = Parser.prototype; // Check if property name clashes with already added. // Object/class getters and setters are not allowed to clash — // either with each other or with an init property — and in // strict mode, init properties are also not allowed to be repeated. pp$3.checkPropClash = function (prop, propHash, refDestructuringErrors) { if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") { return; } if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) { return; } var key = prop.key; var name; switch (key.type) { case "Identifier": name = key.name;break; case "Literal": name = String(key.value);break; default: return; } var kind = prop.kind; if (this.options.ecmaVersion >= 6) { if (name === "__proto__" && kind === "init") { if (propHash.proto) { if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } // Backwards-compat kludge. Can be removed in version 6.0 else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } } propHash.proto = true; } return; } name = "$" + name; var other = propHash[name]; if (other) { var redefinition; if (kind === "init") { redefinition = this.strict && other.init || other.get || other.set; } else { redefinition = other.init || other[kind]; } if (redefinition) { this.raiseRecoverable(key.start, "Redefinition of property"); } } else { other = propHash[name] = { init: false, get: false, set: false }; } other[kind] = true; }; // ### Expression parsing // These nest, from the most general expression type at the top to // 'atomic', nondivisible expression types at the bottom. Most of // the functions will simply let the function(s) below them parse, // and, *if* the syntactic construct they handle is present, wrap // the AST node that the inner parser gave them in another node. // Parse a full expression. The optional arguments are used to // forbid the `in` operator (in for loops initalization expressions) // and provide reference for storing '=' operator inside shorthand // property assignment in contexts where both object expression // and object pattern might appear (so it's possible to raise // delayed syntax error at correct position). pp$3.parseExpression = function (noIn, refDestructuringErrors) { var this$1 = this; var startPos = this.start, startLoc = this.startLoc; var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); if (this.type === types.comma) { var node = this.startNodeAt(startPos, startLoc); node.expressions = [expr]; while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); } return this.finishNode(node, "SequenceExpression"); } return expr; }; // Parse an assignment expression. This includes applications of // operators like `+=`. pp$3.parseMaybeAssign = function (noIn, refDestructuringErrors, afterLeftParse) { if (this.isContextual("yield")) { if (this.inGenerator) { return this.parseYield(); } // The tokenizer will assume an expression is allowed after // `yield`, but this isn't that kind of yield else { this.exprAllowed = false; } } var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldShorthandAssign = -1; if (refDestructuringErrors) { oldParenAssign = refDestructuringErrors.parenthesizedAssign; oldTrailingComma = refDestructuringErrors.trailingComma; oldShorthandAssign = refDestructuringErrors.shorthandAssign; refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.shorthandAssign = -1; } else { refDestructuringErrors = new DestructuringErrors(); ownDestructuringErrors = true; } var startPos = this.start, startLoc = this.startLoc; if (this.type === types.parenL || this.type === types.name) { this.potentialArrowAt = this.start; } var left = this.parseMaybeConditional(noIn, refDestructuringErrors); if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } if (this.type.isAssign) { var node = this.startNodeAt(startPos, startLoc); node.operator = this.value; node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly this.checkLVal(left); this.next(); node.right = this.parseMaybeAssign(noIn); return this.finishNode(node, "AssignmentExpression"); } else { if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } } if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } if (oldShorthandAssign > -1) { refDestructuringErrors.shorthandAssign = oldShorthandAssign; } return left; }; // Parse a ternary conditional (`?:`) operator. pp$3.parseMaybeConditional = function (noIn, refDestructuringErrors) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseExprOps(noIn, refDestructuringErrors); if (this.checkExpressionErrors(refDestructuringErrors)) { return expr; } if (this.eat(types.question)) { var node = this.startNodeAt(startPos, startLoc); node.test = expr; node.consequent = this.parseMaybeAssign(); this.expect(types.colon); node.alternate = this.parseMaybeAssign(noIn); return this.finishNode(node, "ConditionalExpression"); } return expr; }; // Start the precedence parser. pp$3.parseExprOps = function (noIn, refDestructuringErrors) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseMaybeUnary(refDestructuringErrors, false); if (this.checkExpressionErrors(refDestructuringErrors)) { return expr; } return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn); }; // Parse binary operators with the operator precedence parsing // algorithm. `left` is the left-hand side of the operator. // `minPrec` provides context that allows the function to stop and // defer further parser to one of its callers when it encounters an // operator that has a lower precedence than the set it is parsing. pp$3.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) { var prec = this.type.binop; if (prec != null && (!noIn || this.type !== types._in)) { if (prec > minPrec) { var logical = this.type === types.logicalOR || this.type === types.logicalAND; var op = this.value; this.next(); var startPos = this.start, startLoc = this.startLoc; var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); } } return left; }; pp$3.buildBinary = function (startPos, startLoc, left, right, op, logical) { var node = this.startNodeAt(startPos, startLoc); node.left = left; node.operator = op; node.right = right; return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression"); }; // Parse unary operators, both prefix and postfix. pp$3.parseMaybeUnary = function (refDestructuringErrors, sawUnary) { var this$1 = this; var startPos = this.start, startLoc = this.startLoc, expr; if (this.isContextual("await") && (this.inAsync || !this.inFunction && this.options.allowAwaitOutsideFunction)) { expr = this.parseAwait(); sawUnary = true; } else if (this.type.prefix) { var node = this.startNode(), update = this.type === types.incDec; node.operator = this.value; node.prefix = true; this.next(); node.argument = this.parseMaybeUnary(null, true); this.checkExpressionErrors(refDestructuringErrors, true); if (update) { this.checkLVal(node.argument); } else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } else { sawUnary = true; } expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } else { expr = this.parseExprSubscripts(refDestructuringErrors); if (this.checkExpressionErrors(refDestructuringErrors)) { return expr; } while (this.type.postfix && !this.canInsertSemicolon()) { var node$1 = this$1.startNodeAt(startPos, startLoc); node$1.operator = this$1.value; node$1.prefix = false; node$1.argument = expr; this$1.checkLVal(expr); this$1.next(); expr = this$1.finishNode(node$1, "UpdateExpression"); } } if (!sawUnary && this.eat(types.starstar)) { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false); } else { return expr; } }; // Parse call, dot, and `[]`-subscript expressions. pp$3.parseExprSubscripts = function (refDestructuringErrors) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseExprAtom(refDestructuringErrors); var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"; if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr; } var result = this.parseSubscripts(expr, startPos, startLoc); if (refDestructuringErrors && result.type === "MemberExpression") { if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } } return result; }; pp$3.parseSubscripts = function (base, startPos, startLoc, noCalls) { var this$1 = this; var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; for (var computed = void 0;;) { if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) { var node = this$1.startNodeAt(startPos, startLoc); node.object = base; node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true); node.computed = !!computed; if (computed) { this$1.expect(types.bracketR); } base = this$1.finishNode(node, "MemberExpression"); } else if (!noCalls && this$1.eat(types.parenL)) { var refDestructuringErrors = new DestructuringErrors(), oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos; this$1.yieldPos = 0; this$1.awaitPos = 0; var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors); if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) { this$1.checkPatternErrors(refDestructuringErrors, false); this$1.checkYieldAwaitInDefaultParams(); this$1.yieldPos = oldYieldPos; this$1.awaitPos = oldAwaitPos; return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true); } this$1.checkExpressionErrors(refDestructuringErrors, true); this$1.yieldPos = oldYieldPos || this$1.yieldPos; this$1.awaitPos = oldAwaitPos || this$1.awaitPos; var node$1 = this$1.startNodeAt(startPos, startLoc); node$1.callee = base; node$1.arguments = exprList; base = this$1.finishNode(node$1, "CallExpression"); } else if (this$1.type === types.backQuote) { var node$2 = this$1.startNodeAt(startPos, startLoc); node$2.tag = base; node$2.quasi = this$1.parseTemplate({ isTagged: true }); base = this$1.finishNode(node$2, "TaggedTemplateExpression"); } else { return base; } } }; // Parse an atomic expression — either a single token that is an // expression, an expression started by a keyword like `function` or // `new`, or an expression wrapped in punctuation like `()`, `[]`, // or `{}`. pp$3.parseExprAtom = function (refDestructuringErrors) { // If a division operator appears in an expression position, the // tokenizer got confused, and we force it to read a regexp instead. if (this.type === types.slash) { this.readRegexp(); } var node, canBeArrow = this.potentialArrowAt === this.start; switch (this.type) { case types._super: if (!this.allowSuper) { this.raise(this.start, "'super' keyword outside a method"); } node = this.startNode(); this.next(); if (this.type === types.parenL && !this.allowDirectSuper) { this.raise(node.start, "super() call outside constructor of a subclass"); } // The `super` keyword can appear at below: // SuperProperty: // super [ Expression ] // super . IdentifierName // SuperCall: // super Arguments if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) { this.unexpected(); } return this.finishNode(node, "Super"); case types._this: node = this.startNode(); this.next(); return this.finishNode(node, "ThisExpression"); case types.name: var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; var id = this.parseIdent(this.type !== types.name); if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true); } if (canBeArrow && !this.canInsertSemicolon()) { if (this.eat(types.arrow)) { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false); } if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { id = this.parseIdent(); if (this.canInsertSemicolon() || !this.eat(types.arrow)) { this.unexpected(); } return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true); } } return id; case types.regexp: var value = this.value; node = this.parseLiteral(value.value); node.regex = { pattern: value.pattern, flags: value.flags }; return node; case types.num:case types.string: return this.parseLiteral(this.value); case types._null:case types._true:case types._false: node = this.startNode(); node.value = this.type === types._null ? null : this.type === types._true; node.raw = this.type.keyword; this.next(); return this.finishNode(node, "Literal"); case types.parenL: var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); if (refDestructuringErrors) { if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) { refDestructuringErrors.parenthesizedAssign = start; } if (refDestructuringErrors.parenthesizedBind < 0) { refDestructuringErrors.parenthesizedBind = start; } } return expr; case types.bracketL: node = this.startNode(); this.next(); node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); return this.finishNode(node, "ArrayExpression"); case types.braceL: return this.parseObj(false, refDestructuringErrors); case types._function: node = this.startNode(); this.next(); return this.parseFunction(node, 0); case types._class: return this.parseClass(this.startNode(), false); case types._new: return this.parseNew(); case types.backQuote: return this.parseTemplate(); default: this.unexpected(); } }; pp$3.parseLiteral = function (value) { var node = this.startNode(); node.value = value; node.raw = this.input.slice(this.start, this.end); this.next(); return this.finishNode(node, "Literal"); }; pp$3.parseParenExpression = function () { this.expect(types.parenL); var val = this.parseExpression(); this.expect(types.parenR); return val; }; pp$3.parseParenAndDistinguishExpression = function (canBeArrow) { var this$1 = this; var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; if (this.options.ecmaVersion >= 6) { this.next(); var innerStartPos = this.start, innerStartLoc = this.startLoc; var exprList = [], first = true, lastIsComma = false; var refDestructuringErrors = new DestructuringErrors(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; this.yieldPos = 0; this.awaitPos = 0; while (this.type !== types.parenR) { first ? first = false : this$1.expect(types.comma); if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) { lastIsComma = true; break; } else if (this$1.type === types.ellipsis) { spreadStart = this$1.start; exprList.push(this$1.parseParenItem(this$1.parseRestBinding())); if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } break; } else { exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); } } var innerEndPos = this.start, innerEndLoc = this.startLoc; this.expect(types.parenR); if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { this.checkPatternErrors(refDestructuringErrors, false); this.checkYieldAwaitInDefaultParams(); this.yieldPos = oldYieldPos; this.awaitPos = oldAwaitPos; return this.parseParenArrowList(startPos, startLoc, exprList); } if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } if (spreadStart) { this.unexpected(spreadStart); } this.checkExpressionErrors(refDestructuringErrors, true); this.yieldPos = oldYieldPos || this.yieldPos; this.awaitPos = oldAwaitPos || this.awaitPos; if (exprList.length > 1) { val = this.startNodeAt(innerStartPos, innerStartLoc); val.expressions = exprList; this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); } else { val = exprList[0]; } } else { val = this.parseParenExpression(); } if (this.options.preserveParens) { var par = this.startNodeAt(startPos, startLoc); par.expression = val; return this.finishNode(par, "ParenthesizedExpression"); } else { return val; } }; pp$3.parseParenItem = function (item) { return item; }; pp$3.parseParenArrowList = function (startPos, startLoc, exprList) { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList); }; // New's precedence is slightly tricky. It must allow its argument to // be a `[]` or dot subscript expression, but not a call — at least, // not without wrapping it in parentheses. Thus, it uses the noCalls // argument to parseSubscripts to prevent it from consuming the // argument list. var empty$1 = []; pp$3.parseNew = function () { var node = this.startNode(); var meta = this.parseIdent(true); if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { node.meta = meta; var containsEsc = this.containsEsc; node.property = this.parseIdent(true); if (node.property.name !== "target" || containsEsc) { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } if (!this.inNonArrowFunction()) { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } return this.finishNode(node, "MetaProperty"); } var startPos = this.start, startLoc = this.startLoc; node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } else { node.arguments = empty$1; } return this.finishNode(node, "NewExpression"); }; // Parse template expression. pp$3.parseTemplateElement = function (ref) { var isTagged = ref.isTagged; var elem = this.startNode(); if (this.type === types.invalidTemplate) { if (!isTagged) { this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); } elem.value = { raw: this.value, cooked: null }; } else { elem.value = { raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), cooked: this.value }; } this.next(); elem.tail = this.type === types.backQuote; return this.finishNode(elem, "TemplateElement"); }; pp$3.parseTemplate = function (ref) { var this$1 = this; if (ref === void 0) ref = {}; var isTagged = ref.isTagged;if (isTagged === void 0) isTagged = false; var node = this.startNode(); this.next(); node.expressions = []; var curElt = this.parseTemplateElement({ isTagged: isTagged }); node.quasis = [curElt]; while (!curElt.tail) { if (this$1.type === types.eof) { this$1.raise(this$1.pos, "Unterminated template literal"); } this$1.expect(types.dollarBraceL); node.expressions.push(this$1.parseExpression()); this$1.expect(types.braceR); node.quasis.push(curElt = this$1.parseTemplateElement({ isTagged: isTagged })); } this.next(); return this.finishNode(node, "TemplateLiteral"); }; pp$3.isAsyncProp = function (prop) { return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || this.options.ecmaVersion >= 9 && this.type === types.star) && !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); }; // Parse an object literal or binding pattern. pp$3.parseObj = function (isPattern, refDestructuringErrors) { var this$1 = this; var node = this.startNode(), first = true, propHash = {}; node.properties = []; this.next(); while (!this.eat(types.braceR)) { if (!first) { this$1.expect(types.comma); if (this$1.afterTrailingComma(types.braceR)) { break; } } else { first = false; } var prop = this$1.parseProperty(isPattern, refDestructuringErrors); if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } node.properties.push(prop); } return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); }; pp$3.parseProperty = function (isPattern, refDestructuringErrors) { var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { if (isPattern) { prop.argument = this.parseIdent(false); if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } return this.finishNode(prop, "RestElement"); } // To disallow parenthesized identifier via `this.toAssignable()`. if (this.type === types.parenL && refDestructuringErrors) { if (refDestructuringErrors.parenthesizedAssign < 0) { refDestructuringErrors.parenthesizedAssign = this.start; } if (refDestructuringErrors.parenthesizedBind < 0) { refDestructuringErrors.parenthesizedBind = this.start; } } // Parse argument. prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); // To disallow trailing comma via `this.toAssignable()`. if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { refDestructuringErrors.trailingComma = this.start; } // Finish return this.finishNode(prop, "SpreadElement"); } if (this.options.ecmaVersion >= 6) { prop.method = false; prop.shorthand = false; if (isPattern || refDestructuringErrors) { startPos = this.start; startLoc = this.startLoc; } if (!isPattern) { isGenerator = this.eat(types.star); } } var containsEsc = this.containsEsc; this.parsePropertyName(prop); if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { isAsync = true; isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); this.parsePropertyName(prop, refDestructuringErrors); } else { isAsync = false; } this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); return this.finishNode(prop, "Property"); }; pp$3.parsePropertyValue = function (prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { if ((isGenerator || isAsync) && this.type === types.colon) { this.unexpected(); } if (this.eat(types.colon)) { prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); prop.kind = "init"; } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { if (isPattern) { this.unexpected(); } prop.kind = "init"; prop.method = true; prop.value = this.parseMethod(isGenerator, isAsync); } else if (!isPattern && !containsEsc && this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && this.type !== types.comma && this.type !== types.braceR) { if (isGenerator || isAsync) { this.unexpected(); } prop.kind = prop.key.name; this.parsePropertyName(prop); prop.value = this.parseMethod(false); var paramCount = prop.kind === "get" ? 0 : 1; if (prop.value.params.length !== paramCount) { var start = prop.value.start; if (prop.kind === "get") { this.raiseRecoverable(start, "getter should have no params"); } else { this.raiseRecoverable(start, "setter should have exactly one param"); } } else { if (prop.kind === "set" && prop.value.params[0].type === "RestElement") { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } } } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { this.checkUnreserved(prop.key); prop.kind = "init"; if (isPattern) { prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); } else if (this.type === types.eq && refDestructuringErrors) { if (refDestructuringErrors.shorthandAssign < 0) { refDestructuringErrors.shorthandAssign = this.start; } prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); } else { prop.value = prop.key; } prop.shorthand = true; } else { this.unexpected(); } }; pp$3.parsePropertyName = function (prop) { if (this.options.ecmaVersion >= 6) { if (this.eat(types.bracketL)) { prop.computed = true; prop.key = this.parseMaybeAssign(); this.expect(types.bracketR); return prop.key; } else { prop.computed = false; } } return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true); }; // Initialize empty function node. pp$3.initFunction = function (node) { node.id = null; if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } if (this.options.ecmaVersion >= 8) { node.async = false; } }; // Parse object or class method. pp$3.parseMethod = function (isGenerator, isAsync, allowDirectSuper) { var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos; this.initFunction(node); if (this.options.ecmaVersion >= 6) { node.generator = isGenerator; } if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } this.yieldPos = 0; this.awaitPos = 0; this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); this.expect(types.parenL); node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); this.checkYieldAwaitInDefaultParams(); this.parseFunctionBody(node, false); this.yieldPos = oldYieldPos; this.awaitPos = oldAwaitPos; return this.finishNode(node, "FunctionExpression"); }; // Parse arrow function expression with given parameters. pp$3.parseArrowExpression = function (node, params, isAsync) { var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos; this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); this.initFunction(node); if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } this.yieldPos = 0; this.awaitPos = 0; node.params = this.toAssignableList(params, true); this.parseFunctionBody(node, true); this.yieldPos = oldYieldPos; this.awaitPos = oldAwaitPos; return this.finishNode(node, "ArrowFunctionExpression"); }; // Parse function body and check parameters. pp$3.parseFunctionBody = function (node, isArrowFunction) { var isExpression = isArrowFunction && this.type !== types.braceL; var oldStrict = this.strict, useStrict = false; if (isExpression) { node.body = this.parseMaybeAssign(); node.expression = true; this.checkParams(node, false); } else { var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); if (!oldStrict || nonSimple) { useStrict = this.strictDirective(this.end); // If this is a strict mode function, verify that argument names // are not repeated, and it does not try to bind the words `eval` // or `arguments`. if (useStrict && nonSimple) { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } } // Start a new scope with regard to labels and the `inFunction` // flag (restore them to their old value afterwards). var oldLabels = this.labels; this.labels = []; if (useStrict) { this.strict = true; } // Add the params to varDeclaredNames to ensure that an error is thrown // if a let/const declaration in the function clashes with one of the params. this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); node.body = this.parseBlock(false); node.expression = false; this.adaptDirectivePrologue(node.body.body); this.labels = oldLabels; } this.exitScope(); // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); } this.strict = oldStrict; }; pp$3.isSimpleParamList = function (params) { for (var i = 0, list = params; i < list.length; i += 1) { var param = list[i]; if (param.type !== "Identifier") { return false; } } return true; }; // Checks function params for various disallowed patterns such as using "eval" // or "arguments" and duplicate parameters. pp$3.checkParams = function (node, allowDuplicates) { var this$1 = this; var nameHash = {}; for (var i = 0, list = node.params; i < list.length; i += 1) { var param = list[i]; this$1.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash); } }; // Parses a comma-separated list of expressions, and returns them as // an array. `close` is the token type that ends the list, and // `allowEmpty` can be turned on to allow subsequent commas with // nothing in between them to be parsed as `null` (which is needed // for array literals). pp$3.parseExprList = function (close, allowTrailingComma, allowEmpty, refDestructuringErrors) { var this$1 = this; var elts = [], first = true; while (!this.eat(close)) { if (!first) { this$1.expect(types.comma); if (allowTrailingComma && this$1.afterTrailingComma(close)) { break; } } else { first = false; } var elt = void 0; if (allowEmpty && this$1.type === types.comma) { elt = null; } else if (this$1.type === types.ellipsis) { elt = this$1.parseSpread(refDestructuringErrors); if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0) { refDestructuringErrors.trailingComma = this$1.start; } } else { elt = this$1.parseMaybeAssign(false, refDestructuringErrors); } elts.push(elt); } return elts; }; pp$3.checkUnreserved = function (ref) { var start = ref.start; var end = ref.end; var name = ref.name; if (this.inGenerator && name === "yield") { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); } if (this.inAsync && name === "await") { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); } if (this.keywords.test(name)) { this.raise(start, "Unexpected keyword '" + name + "'"); } if (this.options.ecmaVersion < 6 && this.input.slice(start, end).indexOf("\\") !== -1) { return; } var re = this.strict ? this.reservedWordsStrict : this.reservedWords; if (re.test(name)) { if (!this.inAsync && name === "await") { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } this.raiseRecoverable(start, "The keyword '" + name + "' is reserved"); } }; // Parse the next token as an identifier. If `liberal` is true (used // when parsing properties), it will also convert keywords into // identifiers. pp$3.parseIdent = function (liberal, isBinding) { var node = this.startNode(); if (liberal && this.options.allowReserved === "never") { liberal = false; } if (this.type === types.name) { node.name = this.value; } else if (this.type.keyword) { node.name = this.type.keyword; // To fix https://github.com/acornjs/acorn/issues/575 // `class` and `function` keywords push new context into this.context. // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword if ((node.name === "class" || node.name === "function") && (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { this.context.pop(); } } else { this.unexpected(); } this.next(); this.finishNode(node, "Identifier"); if (!liberal) { this.checkUnreserved(node); } return node; }; // Parses yield expression inside generator. pp$3.parseYield = function () { if (!this.yieldPos) { this.yieldPos = this.start; } var node = this.startNode(); this.next(); if (this.type === types.semi || this.canInsertSemicolon() || this.type !== types.star && !this.type.startsExpr) { node.delegate = false; node.argument = null; } else { node.delegate = this.eat(types.star); node.argument = this.parseMaybeAssign(); } return this.finishNode(node, "YieldExpression"); }; pp$3.parseAwait = function () { if (!this.awaitPos) { this.awaitPos = this.start; } var node = this.startNode(); this.next(); node.argument = this.parseMaybeUnary(null, true); return this.finishNode(node, "AwaitExpression"); }; var pp$4 = Parser.prototype; // This function is used to raise exceptions on parse errors. It // takes an offset integer (into the current `input`) to indicate // the location of the error, attaches the position to the end // of the error message, and then raises a `SyntaxError` with that // message. pp$4.raise = function (pos, message) { var loc = getLineInfo(this.input, pos); message += " (" + loc.line + ":" + loc.column + ")"; var err = new SyntaxError(message); err.pos = pos;err.loc = loc;err.raisedAt = this.pos; throw err; }; pp$4.raiseRecoverable = pp$4.raise; pp$4.curPosition = function () { if (this.options.locations) { return new Position(this.curLine, this.pos - this.lineStart); } }; var pp$5 = Parser.prototype; var Scope = function Scope(flags) { this.flags = flags; // A list of var-declared names in the current lexical scope this.var = []; // A list of lexically-declared names in the current lexical scope this.lexical = []; }; // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. pp$5.enterScope = function (flags) { this.scopeStack.push(new Scope(flags)); }; pp$5.exitScope = function () { this.scopeStack.pop(); }; pp$5.declareName = function (name, bindingType, pos) { var this$1 = this; var redeclared = false; if (bindingType === BIND_LEXICAL) { var scope = this.currentScope(); redeclared = scope.lexical.indexOf(name) > -1 || scope.var.indexOf(name) > -1; scope.lexical.push(name); } else if (bindingType === BIND_SIMPLE_CATCH) { var scope$1 = this.currentScope(); scope$1.lexical.push(name); } else if (bindingType === BIND_FUNCTION) { var scope$2 = this.currentScope(); redeclared = scope$2.lexical.indexOf(name) > -1; scope$2.var.push(name); } else { for (var i = this.scopeStack.length - 1; i >= 0; --i) { var scope$3 = this$1.scopeStack[i]; if (scope$3.lexical.indexOf(name) > -1 && !(scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) { redeclared = true; } scope$3.var.push(name); if (scope$3.flags & SCOPE_VAR) { break; } } } if (redeclared) { this.raiseRecoverable(pos, "Identifier '" + name + "' has already been declared"); } }; pp$5.currentScope = function () { return this.scopeStack[this.scopeStack.length - 1]; }; pp$5.currentVarScope = function () { var this$1 = this; for (var i = this.scopeStack.length - 1;; i--) { var scope = this$1.scopeStack[i]; if (scope.flags & SCOPE_VAR) { return scope; } } }; // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. pp$5.currentThisScope = function () { var this$1 = this; for (var i = this.scopeStack.length - 1;; i--) { var scope = this$1.scopeStack[i]; if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope; } } }; var Node = function Node(parser, pos, loc) { this.type = ""; this.start = pos; this.end = 0; if (parser.options.locations) { this.loc = new SourceLocation(parser, loc); } if (parser.options.directSourceFile) { this.sourceFile = parser.options.directSourceFile; } if (parser.options.ranges) { this.range = [pos, 0]; } }; // Start an AST node, attaching a start offset. var pp$6 = Parser.prototype; pp$6.startNode = function () { return new Node(this, this.start, this.startLoc); }; pp$6.startNodeAt = function (pos, loc) { return new Node(this, pos, loc); }; // Finish an AST node, adding `type` and `end` properties. function finishNodeAt(node, type, pos, loc) { node.type = type; node.end = pos; if (this.options.locations) { node.loc.end = loc; } if (this.options.ranges) { node.range[1] = pos; } return node; } pp$6.finishNode = function (node, type) { return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc); }; // Finish node at given position pp$6.finishNodeAt = function (node, type, pos, loc) { return finishNodeAt.call(this, node, type, pos, loc); }; // The algorithm used to determine whether a regexp can appear at a // given point in the program is loosely based on sweet.js' approach. // See https://github.com/mozilla/sweet.js/wiki/design var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { this.token = token; this.isExpr = !!isExpr; this.preserveSpace = !!preserveSpace; this.override = override; this.generator = !!generator; }; var types$1 = { b_stat: new TokContext("{", false), b_expr: new TokContext("{", true), b_tmpl: new TokContext("${", false), p_stat: new TokContext("(", false), p_expr: new TokContext("(", true), q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), f_stat: new TokContext("function", false), f_expr: new TokContext("function", true), f_expr_gen: new TokContext("function", true, false, null, true), f_gen: new TokContext("function", false, false, null, true) }; var pp$7 = Parser.prototype; pp$7.initialContext = function () { return [types$1.b_stat]; }; pp$7.braceIsBlock = function (prevType) { var parent = this.curContext(); if (parent === types$1.f_expr || parent === types$1.f_stat) { return true; } if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) { return !parent.isExpr; } // The check for `tt.name && exprAllowed` detects whether we are // after a `yield` or `of` construct. See the `updateContext` for // `tt.name`. if (prevType === types._return || prevType === types.name && this.exprAllowed) { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); } if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) { return true; } if (prevType === types.braceL) { return parent === types$1.b_stat; } if (prevType === types._var || prevType === types._const || prevType === types.name) { return false; } return !this.exprAllowed; }; pp$7.inGeneratorContext = function () { var this$1 = this; for (var i = this.context.length - 1; i >= 1; i--) { var context = this$1.context[i]; if (context.token === "function") { return context.generator; } } return false; }; pp$7.updateContext = function (prevType) { var update, type = this.type; if (type.keyword && prevType === types.dot) { this.exprAllowed = false; } else if (update = type.updateContext) { update.call(this, prevType); } else { this.exprAllowed = type.beforeExpr; } }; // Token-specific context update code types.parenR.updateContext = types.braceR.updateContext = function () { if (this.context.length === 1) { this.exprAllowed = true; return; } var out = this.context.pop(); if (out === types$1.b_stat && this.curContext().token === "function") { out = this.context.pop(); } this.exprAllowed = !out.isExpr; }; types.braceL.updateContext = function (prevType) { this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); this.exprAllowed = true; }; types.dollarBraceL.updateContext = function () { this.context.push(types$1.b_tmpl); this.exprAllowed = true; }; types.parenL.updateContext = function (prevType) { var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); this.exprAllowed = true; }; types.incDec.updateContext = function () { // tokExprAllowed stays unchanged }; types._function.updateContext = types._class.updateContext = function (prevType) { if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) { this.context.push(types$1.f_expr); } else { this.context.push(types$1.f_stat); } this.exprAllowed = false; }; types.backQuote.updateContext = function () { if (this.curContext() === types$1.q_tmpl) { this.context.pop(); } else { this.context.push(types$1.q_tmpl); } this.exprAllowed = false; }; types.star.updateContext = function (prevType) { if (prevType === types._function) { var index = this.context.length - 1; if (this.context[index] === types$1.f_expr) { this.context[index] = types$1.f_expr_gen; } else { this.context[index] = types$1.f_gen; } } this.exprAllowed = true; }; types.name.updateContext = function (prevType) { var allowed = false; if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { if (this.value === "of" && !this.exprAllowed || this.value === "yield" && this.inGeneratorContext()) { allowed = true; } } this.exprAllowed = allowed; }; var data = { "$LONE": ["ASCII", "ASCII_Hex_Digit", "AHex", "Alphabetic", "Alpha", "Any", "Assigned", "Bidi_Control", "Bidi_C", "Bidi_Mirrored", "Bidi_M", "Case_Ignorable", "CI", "Cased", "Changes_When_Casefolded", "CWCF", "Changes_When_Casemapped", "CWCM", "Changes_When_Lowercased", "CWL", "Changes_When_NFKC_Casefolded", "CWKCF", "Changes_When_Titlecased", "CWT", "Changes_When_Uppercased", "CWU", "Dash", "Default_Ignorable_Code_Point", "DI", "Deprecated", "Dep", "Diacritic", "Dia", "Emoji", "Emoji_Component", "Emoji_Modifier", "Emoji_Modifier_Base", "Emoji_Presentation", "Extender", "Ext", "Grapheme_Base", "Gr_Base", "Grapheme_Extend", "Gr_Ext", "Hex_Digit", "Hex", "IDS_Binary_Operator", "IDSB", "IDS_Trinary_Operator", "IDST", "ID_Continue", "IDC", "ID_Start", "IDS", "Ideographic", "Ideo", "Join_Control", "Join_C", "Logical_Order_Exception", "LOE", "Lowercase", "Lower", "Math", "Noncharacter_Code_Point", "NChar", "Pattern_Syntax", "Pat_Syn", "Pattern_White_Space", "Pat_WS", "Quotation_Mark", "QMark", "Radical", "Regional_Indicator", "RI", "Sentence_Terminal", "STerm", "Soft_Dotted", "SD", "Terminal_Punctuation", "Term", "Unified_Ideograph", "UIdeo", "Uppercase", "Upper", "Variation_Selector", "VS", "White_Space", "space", "XID_Continue", "XIDC", "XID_Start", "XIDS"], "General_Category": ["Cased_Letter", "LC", "Close_Punctuation", "Pe", "Connector_Punctuation", "Pc", "Control", "Cc", "cntrl", "Currency_Symbol", "Sc", "Dash_Punctuation", "Pd", "Decimal_Number", "Nd", "digit", "Enclosing_Mark", "Me", "Final_Punctuation", "Pf", "Format", "Cf", "Initial_Punctuation", "Pi", "Letter", "L", "Letter_Number", "Nl", "Line_Separator", "Zl", "Lowercase_Letter", "Ll", "Mark", "M", "Combining_Mark", "Math_Symbol", "Sm", "Modifier_Letter", "Lm", "Modifier_Symbol", "Sk", "Nonspacing_Mark", "Mn", "Number", "N", "Open_Punctuation", "Ps", "Other", "C", "Other_Letter", "Lo", "Other_Number", "No", "Other_Punctuation", "Po", "Other_Symbol", "So", "Paragraph_Separator", "Zp", "Private_Use", "Co", "Punctuation", "P", "punct", "Separator", "Z", "Space_Separator", "Zs", "Spacing_Mark", "Mc", "Surrogate", "Cs", "Symbol", "S", "Titlecase_Letter", "Lt", "Unassigned", "Cn", "Uppercase_Letter", "Lu"], "Script": ["Adlam", "Adlm", "Ahom", "Anatolian_Hieroglyphs", "Hluw", "Arabic", "Arab", "Armenian", "Armn", "Avestan", "Avst", "Balinese", "Bali", "Bamum", "Bamu", "Bassa_Vah", "Bass", "Batak", "Batk", "Bengali", "Beng", "Bhaiksuki", "Bhks", "Bopomofo", "Bopo", "Brahmi", "Brah", "Braille", "Brai", "Buginese", "Bugi", "Buhid", "Buhd", "Canadian_Aboriginal", "Cans", "Carian", "Cari", "Caucasian_Albanian", "Aghb", "Chakma", "Cakm", "Cham", "Cherokee", "Cher", "Common", "Zyyy", "Coptic", "Copt", "Qaac", "Cuneiform", "Xsux", "Cypriot", "Cprt", "Cyrillic", "Cyrl", "Deseret", "Dsrt", "Devanagari", "Deva", "Duployan", "Dupl", "Egyptian_Hieroglyphs", "Egyp", "Elbasan", "Elba", "Ethiopic", "Ethi", "Georgian", "Geor", "Glagolitic", "Glag", "Gothic", "Goth", "Grantha", "Gran", "Greek", "Grek", "Gujarati", "Gujr", "Gurmukhi", "Guru", "Han", "Hani", "Hangul", "Hang", "Hanunoo", "Hano", "Hatran", "Hatr", "Hebrew", "Hebr", "Hiragana", "Hira", "Imperial_Aramaic", "Armi", "Inherited", "Zinh", "Qaai", "Inscriptional_Pahlavi", "Phli", "Inscriptional_Parthian", "Prti", "Javanese", "Java", "Kaithi", "Kthi", "Kannada", "Knda", "Katakana", "Kana", "Kayah_Li", "Kali", "Kharoshthi", "Khar", "Khmer", "Khmr", "Khojki", "Khoj", "Khudawadi", "Sind", "Lao", "Laoo", "Latin", "Latn", "Lepcha", "Lepc", "Limbu", "Limb", "Linear_A", "Lina", "Linear_B", "Linb", "Lisu", "Lycian", "Lyci", "Lydian", "Lydi", "Mahajani", "Mahj", "Malayalam", "Mlym", "Mandaic", "Mand", "Manichaean", "Mani", "Marchen", "Marc", "Masaram_Gondi", "Gonm", "Meetei_Mayek", "Mtei", "Mende_Kikakui", "Mend", "Meroitic_Cursive", "Merc", "Meroitic_Hieroglyphs", "Mero", "Miao", "Plrd", "Modi", "Mongolian", "Mong", "Mro", "Mroo", "Multani", "Mult", "Myanmar", "Mymr", "Nabataean", "Nbat", "New_Tai_Lue", "Talu", "Newa", "Nko", "Nkoo", "Nushu", "Nshu", "Ogham", "Ogam", "Ol_Chiki", "Olck", "Old_Hungarian", "Hung", "Old_Italic", "Ital", "Old_North_Arabian", "Narb", "Old_Permic", "Perm", "Old_Persian", "Xpeo", "Old_South_Arabian", "Sarb", "Old_Turkic", "Orkh", "Oriya", "Orya", "Osage", "Osge", "Osmanya", "Osma", "Pahawh_Hmong", "Hmng", "Palmyrene", "Palm", "Pau_Cin_Hau", "Pauc", "Phags_Pa", "Phag", "Phoenician", "Phnx", "Psalter_Pahlavi", "Phlp", "Rejang", "Rjng", "Runic", "Runr", "Samaritan", "Samr", "Saurashtra", "Saur", "Sharada", "Shrd", "Shavian", "Shaw", "Siddham", "Sidd", "SignWriting", "Sgnw", "Sinhala", "Sinh", "Sora_Sompeng", "Sora", "Soyombo", "Soyo", "Sundanese", "Sund", "Syloti_Nagri", "Sylo", "Syriac", "Syrc", "Tagalog", "Tglg", "Tagbanwa", "Tagb", "Tai_Le", "Tale", "Tai_Tham", "Lana", "Tai_Viet", "Tavt", "Takri", "Takr", "Tamil", "Taml", "Tangut", "Tang", "Telugu", "Telu", "Thaana", "Thaa", "Thai", "Tibetan", "Tibt", "Tifinagh", "Tfng", "Tirhuta", "Tirh", "Ugaritic", "Ugar", "Vai", "Vaii", "Warang_Citi", "Wara", "Yi", "Yiii", "Zanabazar_Square", "Zanb"] }; Array.prototype.push.apply(data.$LONE, data.General_Category); data.gc = data.General_Category; data.sc = data.Script_Extensions = data.scx = data.Script; var pp$9 = Parser.prototype; var RegExpValidationState = function RegExpValidationState(parser) { this.parser = parser; this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); this.source = ""; this.flags = ""; this.start = 0; this.switchU = false; this.switchN = false; this.pos = 0; this.lastIntValue = 0; this.lastStringValue = ""; this.lastAssertionIsQuantifiable = false; this.numCapturingParens = 0; this.maxBackReference = 0; this.groupNames = []; this.backReferenceNames = []; }; RegExpValidationState.prototype.reset = function reset(start, pattern, flags) { var unicode = flags.indexOf("u") !== -1; this.start = start | 0; this.source = pattern + ""; this.flags = flags; this.switchU = unicode && this.parser.options.ecmaVersion >= 6; this.switchN = unicode && this.parser.options.ecmaVersion >= 9; }; RegExpValidationState.prototype.raise = function raise(message) { this.parser.raiseRecoverable(this.start, "Invalid regular expression: /" + this.source + "/: " + message); }; // If u flag is given, this returns the code point at the index (it combines a surrogate pair). // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). RegExpValidationState.prototype.at = function at(i) { var s = this.source; var l = s.length; if (i >= l) { return -1; } var c = s.charCodeAt(i); if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { return c; } return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00; }; RegExpValidationState.prototype.nextIndex = function nextIndex(i) { var s = this.source; var l = s.length; if (i >= l) { return l; } var c = s.charCodeAt(i); if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { return i + 1; } return i + 2; }; RegExpValidationState.prototype.current = function current() { return this.at(this.pos); }; RegExpValidationState.prototype.lookahead = function lookahead() { return this.at(this.nextIndex(this.pos)); }; RegExpValidationState.prototype.advance = function advance() { this.pos = this.nextIndex(this.pos); }; RegExpValidationState.prototype.eat = function eat(ch) { if (this.current() === ch) { this.advance(); return true; } return false; }; function codePointToString$1(ch) { if (ch <= 0xFFFF) { return String.fromCharCode(ch); } ch -= 0x10000; return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00); } /** * Validate the flags part of a given RegExpLiteral. * * @param {RegExpValidationState} state The state to validate RegExp. * @returns {void} */ pp$9.validateRegExpFlags = function (state) { var this$1 = this; var validFlags = state.validFlags; var flags = state.flags; for (var i = 0; i < flags.length; i++) { var flag = flags.charAt(i); if (validFlags.indexOf(flag) === -1) { this$1.raise(state.start, "Invalid regular expression flag"); } if (flags.indexOf(flag, i + 1) > -1) { this$1.raise(state.start, "Duplicate regular expression flag"); } } }; /** * Validate the pattern part of a given RegExpLiteral. * * @param {RegExpValidationState} state The state to validate RegExp. * @returns {void} */ pp$9.validateRegExpPattern = function (state) { this.regexp_pattern(state); // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of // parsing contains a |GroupName|, reparse with the goal symbol // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* // exception if _P_ did not conform to the grammar, if any elements of _P_ // were not matched by the parse, or if any Early Error conditions exist. if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { state.switchN = true; this.regexp_pattern(state); } }; // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern pp$9.regexp_pattern = function (state) { state.pos = 0; state.lastIntValue = 0; state.lastStringValue = ""; state.lastAssertionIsQuantifiable = false; state.numCapturingParens = 0; state.maxBackReference = 0; state.groupNames.length = 0; state.backReferenceNames.length = 0; this.regexp_disjunction(state); if (state.pos !== state.source.length) { // Make the same messages as V8. if (state.eat(0x29 /* ) */)) { state.raise("Unmatched ')'"); } if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) { state.raise("Lone quantifier brackets"); } } if (state.maxBackReference > state.numCapturingParens) { state.raise("Invalid escape"); } for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { var name = list[i]; if (state.groupNames.indexOf(name) === -1) { state.raise("Invalid named capture referenced"); } } }; // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction pp$9.regexp_disjunction = function (state) { var this$1 = this; this.regexp_alternative(state); while (state.eat(0x7C /* | */)) { this$1.regexp_alternative(state); } // Make the same message as V8. if (this.regexp_eatQuantifier(state, true)) { state.raise("Nothing to repeat"); } if (state.eat(0x7B /* { */)) { state.raise("Lone quantifier brackets"); } }; // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative pp$9.regexp_alternative = function (state) { while (state.pos < state.source.length && this.regexp_eatTerm(state)) {} }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term pp$9.regexp_eatTerm = function (state) { if (this.regexp_eatAssertion(state)) { // Handle `QuantifiableAssertion Quantifier` alternative. // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion // is a QuantifiableAssertion. if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { // Make the same message as V8. if (state.switchU) { state.raise("Invalid quantifier"); } } return true; } if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { this.regexp_eatQuantifier(state); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion pp$9.regexp_eatAssertion = function (state) { var start = state.pos; state.lastAssertionIsQuantifiable = false; // ^, $ if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { return true; } // \b \B if (state.eat(0x5C /* \ */)) { if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { return true; } state.pos = start; } // Lookahead / Lookbehind if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { var lookbehind = false; if (this.options.ecmaVersion >= 9) { lookbehind = state.eat(0x3C /* < */); } if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { this.regexp_disjunction(state); if (!state.eat(0x29 /* ) */)) { state.raise("Unterminated group"); } state.lastAssertionIsQuantifiable = !lookbehind; return true; } } state.pos = start; return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier pp$9.regexp_eatQuantifier = function (state, noError) { if (noError === void 0) noError = false; if (this.regexp_eatQuantifierPrefix(state, noError)) { state.eat(0x3F /* ? */); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix pp$9.regexp_eatQuantifierPrefix = function (state, noError) { return state.eat(0x2A /* * */) || state.eat(0x2B /* + */) || state.eat(0x3F /* ? */) || this.regexp_eatBracedQuantifier(state, noError); }; pp$9.regexp_eatBracedQuantifier = function (state, noError) { var start = state.pos; if (state.eat(0x7B /* { */)) { var min = 0, max = -1; if (this.regexp_eatDecimalDigits(state)) { min = state.lastIntValue; if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { max = state.lastIntValue; } if (state.eat(0x7D /* } */)) { // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term if (max !== -1 && max < min && !noError) { state.raise("numbers out of order in {} quantifier"); } return true; } } if (state.switchU && !noError) { state.raise("Incomplete quantifier"); } state.pos = start; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom pp$9.regexp_eatAtom = function (state) { return this.regexp_eatPatternCharacters(state) || state.eat(0x2E /* . */) || this.regexp_eatReverseSolidusAtomEscape(state) || this.regexp_eatCharacterClass(state) || this.regexp_eatUncapturingGroup(state) || this.regexp_eatCapturingGroup(state); }; pp$9.regexp_eatReverseSolidusAtomEscape = function (state) { var start = state.pos; if (state.eat(0x5C /* \ */)) { if (this.regexp_eatAtomEscape(state)) { return true; } state.pos = start; } return false; }; pp$9.regexp_eatUncapturingGroup = function (state) { var start = state.pos; if (state.eat(0x28 /* ( */)) { if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { this.regexp_disjunction(state); if (state.eat(0x29 /* ) */)) { return true; } state.raise("Unterminated group"); } state.pos = start; } return false; }; pp$9.regexp_eatCapturingGroup = function (state) { if (state.eat(0x28 /* ( */)) { if (this.options.ecmaVersion >= 9) { this.regexp_groupSpecifier(state); } else if (state.current() === 0x3F /* ? */) { state.raise("Invalid group"); } this.regexp_disjunction(state); if (state.eat(0x29 /* ) */)) { state.numCapturingParens += 1; return true; } state.raise("Unterminated group"); } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom pp$9.regexp_eatExtendedAtom = function (state) { return state.eat(0x2E /* . */) || this.regexp_eatReverseSolidusAtomEscape(state) || this.regexp_eatCharacterClass(state) || this.regexp_eatUncapturingGroup(state) || this.regexp_eatCapturingGroup(state) || this.regexp_eatInvalidBracedQuantifier(state) || this.regexp_eatExtendedPatternCharacter(state); }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier pp$9.regexp_eatInvalidBracedQuantifier = function (state) { if (this.regexp_eatBracedQuantifier(state, true)) { state.raise("Nothing to repeat"); } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter pp$9.regexp_eatSyntaxCharacter = function (state) { var ch = state.current(); if (isSyntaxCharacter(ch)) { state.lastIntValue = ch; state.advance(); return true; } return false; }; function isSyntaxCharacter(ch) { return ch === 0x24 /* $ */ || ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || ch === 0x2E /* . */ || ch === 0x3F /* ? */ || ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || ch >= 0x7B /* { */ && ch <= 0x7D /* } */ ; } // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter // But eat eager. pp$9.regexp_eatPatternCharacters = function (state) { var start = state.pos; var ch = 0; while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { state.advance(); } return state.pos !== start; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter pp$9.regexp_eatExtendedPatternCharacter = function (state) { var ch = state.current(); if (ch !== -1 && ch !== 0x24 /* $ */ && !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && ch !== 0x2E /* . */ && ch !== 0x3F /* ? */ && ch !== 0x5B /* [ */ && ch !== 0x5E /* ^ */ && ch !== 0x7C /* | */ ) { state.advance(); return true; } return false; }; // GroupSpecifier[U] :: // [empty] // `?` GroupName[?U] pp$9.regexp_groupSpecifier = function (state) { if (state.eat(0x3F /* ? */)) { if (this.regexp_eatGroupName(state)) { if (state.groupNames.indexOf(state.lastStringValue) !== -1) { state.raise("Duplicate capture group name"); } state.groupNames.push(state.lastStringValue); return; } state.raise("Invalid group"); } }; // GroupName[U] :: // `<` RegExpIdentifierName[?U] `>` // Note: this updates `state.lastStringValue` property with the eaten name. pp$9.regexp_eatGroupName = function (state) { state.lastStringValue = ""; if (state.eat(0x3C /* < */)) { if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { return true; } state.raise("Invalid capture group name"); } return false; }; // RegExpIdentifierName[U] :: // RegExpIdentifierStart[?U] // RegExpIdentifierName[?U] RegExpIdentifierPart[?U] // Note: this updates `state.lastStringValue` property with the eaten name. pp$9.regexp_eatRegExpIdentifierName = function (state) { state.lastStringValue = ""; if (this.regexp_eatRegExpIdentifierStart(state)) { state.lastStringValue += codePointToString$1(state.lastIntValue); while (this.regexp_eatRegExpIdentifierPart(state)) { state.lastStringValue += codePointToString$1(state.lastIntValue); } return true; } return false; }; // RegExpIdentifierStart[U] :: // UnicodeIDStart // `$` // `_` // `\` RegExpUnicodeEscapeSequence[?U] pp$9.regexp_eatRegExpIdentifierStart = function (state) { var start = state.pos; var ch = state.current(); state.advance(); if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { ch = state.lastIntValue; } if (isRegExpIdentifierStart(ch)) { state.lastIntValue = ch; return true; } state.pos = start; return false; }; function isRegExpIdentifierStart(ch) { return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F; /* _ */ } // RegExpIdentifierPart[U] :: // UnicodeIDContinue // `$` // `_` // `\` RegExpUnicodeEscapeSequence[?U] // // pp$9.regexp_eatRegExpIdentifierPart = function (state) { var start = state.pos; var ch = state.current(); state.advance(); if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { ch = state.lastIntValue; } if (isRegExpIdentifierPart(ch)) { state.lastIntValue = ch; return true; } state.pos = start; return false; }; function isRegExpIdentifierPart(ch) { return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D; /* */ } // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape pp$9.regexp_eatAtomEscape = function (state) { if (this.regexp_eatBackReference(state) || this.regexp_eatCharacterClassEscape(state) || this.regexp_eatCharacterEscape(state) || state.switchN && this.regexp_eatKGroupName(state)) { return true; } if (state.switchU) { // Make the same message as V8. if (state.current() === 0x63 /* c */) { state.raise("Invalid unicode escape"); } state.raise("Invalid escape"); } return false; }; pp$9.regexp_eatBackReference = function (state) { var start = state.pos; if (this.regexp_eatDecimalEscape(state)) { var n = state.lastIntValue; if (state.switchU) { // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape if (n > state.maxBackReference) { state.maxBackReference = n; } return true; } if (n <= state.numCapturingParens) { return true; } state.pos = start; } return false; }; pp$9.regexp_eatKGroupName = function (state) { if (state.eat(0x6B /* k */)) { if (this.regexp_eatGroupName(state)) { state.backReferenceNames.push(state.lastStringValue); return true; } state.raise("Invalid named reference"); } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape pp$9.regexp_eatCharacterEscape = function (state) { return this.regexp_eatControlEscape(state) || this.regexp_eatCControlLetter(state) || this.regexp_eatZero(state) || this.regexp_eatHexEscapeSequence(state) || this.regexp_eatRegExpUnicodeEscapeSequence(state) || !state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state) || this.regexp_eatIdentityEscape(state); }; pp$9.regexp_eatCControlLetter = function (state) { var start = state.pos; if (state.eat(0x63 /* c */)) { if (this.regexp_eatControlLetter(state)) { return true; } state.pos = start; } return false; }; pp$9.regexp_eatZero = function (state) { if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { state.lastIntValue = 0; state.advance(); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape pp$9.regexp_eatControlEscape = function (state) { var ch = state.current(); if (ch === 0x74 /* t */) { state.lastIntValue = 0x09; /* \t */ state.advance(); return true; } if (ch === 0x6E /* n */) { state.lastIntValue = 0x0A; /* \n */ state.advance(); return true; } if (ch === 0x76 /* v */) { state.lastIntValue = 0x0B; /* \v */ state.advance(); return true; } if (ch === 0x66 /* f */) { state.lastIntValue = 0x0C; /* \f */ state.advance(); return true; } if (ch === 0x72 /* r */) { state.lastIntValue = 0x0D; /* \r */ state.advance(); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter pp$9.regexp_eatControlLetter = function (state) { var ch = state.current(); if (isControlLetter(ch)) { state.lastIntValue = ch % 0x20; state.advance(); return true; } return false; }; function isControlLetter(ch) { return ch >= 0x41 /* A */ && ch <= 0x5A /* Z */ || ch >= 0x61 /* a */ && ch <= 0x7A /* z */; } // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence pp$9.regexp_eatRegExpUnicodeEscapeSequence = function (state) { var start = state.pos; if (state.eat(0x75 /* u */)) { if (this.regexp_eatFixedHexDigits(state, 4)) { var lead = state.lastIntValue; if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) { var leadSurrogateEnd = state.pos; if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { var trail = state.lastIntValue; if (trail >= 0xDC00 && trail <= 0xDFFF) { state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; return true; } } state.pos = leadSurrogateEnd; state.lastIntValue = lead; } return true; } if (state.switchU && state.eat(0x7B /* { */) && this.regexp_eatHexDigits(state) && state.eat(0x7D /* } */) && isValidUnicode(state.lastIntValue)) { return true; } if (state.switchU) { state.raise("Invalid unicode escape"); } state.pos = start; } return false; }; function isValidUnicode(ch) { return ch >= 0 && ch <= 0x10FFFF; } // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape pp$9.regexp_eatIdentityEscape = function (state) { if (state.switchU) { if (this.regexp_eatSyntaxCharacter(state)) { return true; } if (state.eat(0x2F /* / */)) { state.lastIntValue = 0x2F; /* / */ return true; } return false; } var ch = state.current(); if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { state.lastIntValue = ch; state.advance(); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape pp$9.regexp_eatDecimalEscape = function (state) { state.lastIntValue = 0; var ch = state.current(); if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { do { state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); state.advance(); } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape pp$9.regexp_eatCharacterClassEscape = function (state) { var ch = state.current(); if (isCharacterClassEscape(ch)) { state.lastIntValue = -1; state.advance(); return true; } if (state.switchU && this.options.ecmaVersion >= 9 && (ch === 0x50 /* P */ || ch === 0x70 /* p */)) { state.lastIntValue = -1; state.advance(); if (state.eat(0x7B /* { */) && this.regexp_eatUnicodePropertyValueExpression(state) && state.eat(0x7D /* } */)) { return true; } state.raise("Invalid property name"); } return false; }; function isCharacterClassEscape(ch) { return ch === 0x64 /* d */ || ch === 0x44 /* D */ || ch === 0x73 /* s */ || ch === 0x53 /* S */ || ch === 0x77 /* w */ || ch === 0x57 /* W */ ; } // UnicodePropertyValueExpression :: // UnicodePropertyName `=` UnicodePropertyValue // LoneUnicodePropertyNameOrValue pp$9.regexp_eatUnicodePropertyValueExpression = function (state) { var start = state.pos; // UnicodePropertyName `=` UnicodePropertyValue if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { var name = state.lastStringValue; if (this.regexp_eatUnicodePropertyValue(state)) { var value = state.lastStringValue; this.regexp_validateUnicodePropertyNameAndValue(state, name, value); return true; } } state.pos = start; // LoneUnicodePropertyNameOrValue if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { var nameOrValue = state.lastStringValue; this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); return true; } return false; }; pp$9.regexp_validateUnicodePropertyNameAndValue = function (state, name, value) { if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) { state.raise("Invalid property name"); } }; pp$9.regexp_validateUnicodePropertyNameOrValue = function (state, nameOrValue) { if (data.$LONE.indexOf(nameOrValue) === -1) { state.raise("Invalid property name"); } }; // UnicodePropertyName :: // UnicodePropertyNameCharacters pp$9.regexp_eatUnicodePropertyName = function (state) { var ch = 0; state.lastStringValue = ""; while (isUnicodePropertyNameCharacter(ch = state.current())) { state.lastStringValue += codePointToString$1(ch); state.advance(); } return state.lastStringValue !== ""; }; function isUnicodePropertyNameCharacter(ch) { return isControlLetter(ch) || ch === 0x5F; /* _ */ } // UnicodePropertyValue :: // UnicodePropertyValueCharacters pp$9.regexp_eatUnicodePropertyValue = function (state) { var ch = 0; state.lastStringValue = ""; while (isUnicodePropertyValueCharacter(ch = state.current())) { state.lastStringValue += codePointToString$1(ch); state.advance(); } return state.lastStringValue !== ""; }; function isUnicodePropertyValueCharacter(ch) { return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch); } // LoneUnicodePropertyNameOrValue :: // UnicodePropertyValueCharacters pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function (state) { return this.regexp_eatUnicodePropertyValue(state); }; // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass pp$9.regexp_eatCharacterClass = function (state) { if (state.eat(0x5B /* [ */)) { state.eat(0x5E /* ^ */); this.regexp_classRanges(state); if (state.eat(0x5D /* [ */)) { return true; } // Unreachable since it threw "unterminated regular expression" error before. state.raise("Unterminated character class"); } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash pp$9.regexp_classRanges = function (state) { var this$1 = this; while (this.regexp_eatClassAtom(state)) { var left = state.lastIntValue; if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) { var right = state.lastIntValue; if (state.switchU && (left === -1 || right === -1)) { state.raise("Invalid character class"); } if (left !== -1 && right !== -1 && left > right) { state.raise("Range out of order in character class"); } } } }; // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash pp$9.regexp_eatClassAtom = function (state) { var start = state.pos; if (state.eat(0x5C /* \ */)) { if (this.regexp_eatClassEscape(state)) { return true; } if (state.switchU) { // Make the same message as V8. var ch$1 = state.current(); if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { state.raise("Invalid class escape"); } state.raise("Invalid escape"); } state.pos = start; } var ch = state.current(); if (ch !== 0x5D /* [ */) { state.lastIntValue = ch; state.advance(); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape pp$9.regexp_eatClassEscape = function (state) { var start = state.pos; if (state.eat(0x62 /* b */)) { state.lastIntValue = 0x08; /* */ return true; } if (state.switchU && state.eat(0x2D /* - */)) { state.lastIntValue = 0x2D; /* - */ return true; } if (!state.switchU && state.eat(0x63 /* c */)) { if (this.regexp_eatClassControlLetter(state)) { return true; } state.pos = start; } return this.regexp_eatCharacterClassEscape(state) || this.regexp_eatCharacterEscape(state); }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter pp$9.regexp_eatClassControlLetter = function (state) { var ch = state.current(); if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { state.lastIntValue = ch % 0x20; state.advance(); return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence pp$9.regexp_eatHexEscapeSequence = function (state) { var start = state.pos; if (state.eat(0x78 /* x */)) { if (this.regexp_eatFixedHexDigits(state, 2)) { return true; } if (state.switchU) { state.raise("Invalid escape"); } state.pos = start; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits pp$9.regexp_eatDecimalDigits = function (state) { var start = state.pos; var ch = 0; state.lastIntValue = 0; while (isDecimalDigit(ch = state.current())) { state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); state.advance(); } return state.pos !== start; }; function isDecimalDigit(ch) { return ch >= 0x30 /* 0 */ && ch <= 0x39; /* 9 */ } // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits pp$9.regexp_eatHexDigits = function (state) { var start = state.pos; var ch = 0; state.lastIntValue = 0; while (isHexDigit(ch = state.current())) { state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); state.advance(); } return state.pos !== start; }; function isHexDigit(ch) { return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ || ch >= 0x41 /* A */ && ch <= 0x46 /* F */ || ch >= 0x61 /* a */ && ch <= 0x66 /* f */; } function hexToInt(ch) { if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { return 10 + (ch - 0x41 /* A */); } if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { return 10 + (ch - 0x61 /* a */); } return ch - 0x30; /* 0 */ } // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence // Allows only 0-377(octal) i.e. 0-255(decimal). pp$9.regexp_eatLegacyOctalEscapeSequence = function (state) { if (this.regexp_eatOctalDigit(state)) { var n1 = state.lastIntValue; if (this.regexp_eatOctalDigit(state)) { var n2 = state.lastIntValue; if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; } else { state.lastIntValue = n1 * 8 + n2; } } else { state.lastIntValue = n1; } return true; } return false; }; // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit pp$9.regexp_eatOctalDigit = function (state) { var ch = state.current(); if (isOctalDigit(ch)) { state.lastIntValue = ch - 0x30; /* 0 */ state.advance(); return true; } state.lastIntValue = 0; return false; }; function isOctalDigit(ch) { return ch >= 0x30 /* 0 */ && ch <= 0x37; /* 7 */ } // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence pp$9.regexp_eatFixedHexDigits = function (state, length) { var start = state.pos; state.lastIntValue = 0; for (var i = 0; i < length; ++i) { var ch = state.current(); if (!isHexDigit(ch)) { state.pos = start; return false; } state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); state.advance(); } return true; }; // Object type used to represent tokens. Note that normally, tokens // simply exist as properties on the parser object. This is only // used for the onToken callback and the external tokenizer. var Token = function Token(p) { this.type = p.type; this.value = p.value; this.start = p.start; this.end = p.end; if (p.options.locations) { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } if (p.options.ranges) { this.range = [p.start, p.end]; } }; // ## Tokenizer var pp$8 = Parser.prototype; // Move to the next token pp$8.next = function () { if (this.options.onToken) { this.options.onToken(new Token(this)); } this.lastTokEnd = this.end; this.lastTokStart = this.start; this.lastTokEndLoc = this.endLoc; this.lastTokStartLoc = this.startLoc; this.nextToken(); }; pp$8.getToken = function () { this.next(); return new Token(this); }; // If we're in an ES6 environment, make parsers iterable if (typeof Symbol !== "undefined") { pp$8[Symbol.iterator] = function () { var this$1 = this; return { next: function next() { var token = this$1.getToken(); return { done: token.type === types.eof, value: token }; } }; }; } // Toggle strict mode. Re-reads the next number or string to please // pedantic tests (`"use strict"; 010;` should fail). pp$8.curContext = function () { return this.context[this.context.length - 1]; }; // Read a single token, updating the parser object's token-related // properties. pp$8.nextToken = function () { var curContext = this.curContext(); if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } this.start = this.pos; if (this.options.locations) { this.startLoc = this.curPosition(); } if (this.pos >= this.input.length) { return this.finishToken(types.eof); } if (curContext.override) { return curContext.override(this); } else { this.readToken(this.fullCharCodeAtPos()); } }; pp$8.readToken = function (code) { // Identifier or keyword. '\uXXXX' sequences are allowed in // identifiers, so '\' also dispatches to that. if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) { return this.readWord(); } return this.getTokenFromCode(code); }; pp$8.fullCharCodeAtPos = function () { var code = this.input.charCodeAt(this.pos); if (code <= 0xd7ff || code >= 0xe000) { return code; } var next = this.input.charCodeAt(this.pos + 1); return (code << 10) + next - 0x35fdc00; }; pp$8.skipBlockComment = function () { var this$1 = this; var startLoc = this.options.onComment && this.curPosition(); var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } this.pos = end + 2; if (this.options.locations) { lineBreakG.lastIndex = start; var match; while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { ++this$1.curLine; this$1.lineStart = match.index + match[0].length; } } if (this.options.onComment) { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.curPosition()); } }; pp$8.skipLineComment = function (startSkip) { var this$1 = this; var start = this.pos; var startLoc = this.options.onComment && this.curPosition(); var ch = this.input.charCodeAt(this.pos += startSkip); while (this.pos < this.input.length && !isNewLine(ch)) { ch = this$1.input.charCodeAt(++this$1.pos); } if (this.options.onComment) { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.curPosition()); } }; // Called at the start of the parse and after every token. Skips // whitespace and comments, and. pp$8.skipSpace = function () { var this$1 = this; loop: while (this.pos < this.input.length) { var ch = this$1.input.charCodeAt(this$1.pos); switch (ch) { case 32:case 160: // ' ' ++this$1.pos; break; case 13: if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { ++this$1.pos; } case 10:case 8232:case 8233: ++this$1.pos; if (this$1.options.locations) { ++this$1.curLine; this$1.lineStart = this$1.pos; } break; case 47: // '/' switch (this$1.input.charCodeAt(this$1.pos + 1)) { case 42: // '*' this$1.skipBlockComment(); break; case 47: this$1.skipLineComment(2); break; default: break loop; } break; default: if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { ++this$1.pos; } else { break loop; } } } }; // Called at the end of every token. Sets `end`, `val`, and // maintains `context` and `exprAllowed`, and skips the space after // the token, so that the next one's `start` will point at the // right position. pp$8.finishToken = function (type, val) { this.end = this.pos; if (this.options.locations) { this.endLoc = this.curPosition(); } var prevType = this.type; this.type = type; this.value = val; this.updateContext(prevType); }; // ### Token reading // This is the function that is called to fetch the next token. It // is somewhat obscure, because it works in character codes rather // than characters, and because operator parsing has been inlined // into it. // // All in the name of speed. // pp$8.readToken_dot = function () { var next = this.input.charCodeAt(this.pos + 1); if (next >= 48 && next <= 57) { return this.readNumber(true); } var next2 = this.input.charCodeAt(this.pos + 2); if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' this.pos += 3; return this.finishToken(types.ellipsis); } else { ++this.pos; return this.finishToken(types.dot); } }; pp$8.readToken_slash = function () { // '/' var next = this.input.charCodeAt(this.pos + 1); if (this.exprAllowed) { ++this.pos;return this.readRegexp(); } if (next === 61) { return this.finishOp(types.assign, 2); } return this.finishOp(types.slash, 1); }; pp$8.readToken_mult_modulo_exp = function (code) { // '%*' var next = this.input.charCodeAt(this.pos + 1); var size = 1; var tokentype = code === 42 ? types.star : types.modulo; // exponentiation operator ** and **= if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { ++size; tokentype = types.starstar; next = this.input.charCodeAt(this.pos + 2); } if (next === 61) { return this.finishOp(types.assign, size + 1); } return this.finishOp(tokentype, size); }; pp$8.readToken_pipe_amp = function (code) { // '|&' var next = this.input.charCodeAt(this.pos + 1); if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2); } if (next === 61) { return this.finishOp(types.assign, 2); } return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1); }; pp$8.readToken_caret = function () { // '^' var next = this.input.charCodeAt(this.pos + 1); if (next === 61) { return this.finishOp(types.assign, 2); } return this.finishOp(types.bitwiseXOR, 1); }; pp$8.readToken_plus_min = function (code) { // '+-' var next = this.input.charCodeAt(this.pos + 1); if (next === code) { if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { // A `-->` line comment this.skipLineComment(3); this.skipSpace(); return this.nextToken(); } return this.finishOp(types.incDec, 2); } if (next === 61) { return this.finishOp(types.assign, 2); } return this.finishOp(types.plusMin, 1); }; pp$8.readToken_lt_gt = function (code) { // '<>' var next = this.input.charCodeAt(this.pos + 1); var size = 1; if (next === code) { size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1); } return this.finishOp(types.bitShift, size); } if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && this.input.charCodeAt(this.pos + 3) === 45) { // ` regexps set = set.map(function (s, si, set) { return s.map(this.parse, this); }, this); this.debug(this.pattern, set); // filter out everything that didn't compile properly. set = set.filter(function (s) { return s.indexOf(false) === -1; }); this.debug(this.pattern, set); this.set = set; } Minimatch.prototype.parseNegate = parseNegate; function parseNegate() { var pattern = this.pattern; var negate = false; var options = this.options; var negateOffset = 0; if (options.nonegate) return; for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === '!'; i++) { negate = !negate; negateOffset++; } if (negateOffset) this.pattern = pattern.substr(negateOffset); this.negate = negate; } // Brace expansion: // a{b,c}d -> abd acd // a{b,}c -> abc ac // a{0..3}d -> a0d a1d a2d a3d // a{b,c{d,e}f}g -> abg acdfg acefg // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg // // Invalid sets are not expanded. // a{2..}b -> a{2..}b // a{b}c -> a{b}c minimatch.braceExpand = function (pattern, options) { return braceExpand(pattern, options); }; Minimatch.prototype.braceExpand = braceExpand; function braceExpand(pattern, options) { if (!options) { if (this instanceof Minimatch) { options = this.options; } else { options = {}; } } pattern = typeof pattern === 'undefined' ? this.pattern : pattern; if (typeof pattern === 'undefined') { throw new TypeError('undefined pattern'); } if (options.nobrace || !pattern.match(/\{.*\}/)) { // shortcut. no need to expand. return [pattern]; } return expand(pattern); } // parse a component of the expanded set. // At this point, no pattern may contain "/" in it // so we're going to return a 2d array, where each entry is the full // pattern, split on '/', and then turned into a regular expression. // A regexp is made at the end which joins each array with an // escaped /, and another full one which joins each regexp with |. // // Following the lead of Bash 4.1, note that "**" only has special meaning // when it is the *only* thing in a path portion. Otherwise, any series // of * is equivalent to a single *. Globstar behavior is enabled by // default, and can be disabled by setting options.noglobstar. Minimatch.prototype.parse = parse; var SUBPARSE = {}; function parse(pattern, isSub) { if (pattern.length > 1024 * 64) { throw new TypeError('pattern is too long'); } var options = this.options; // shortcuts if (!options.noglobstar && pattern === '**') return GLOBSTAR; if (pattern === '') return ''; var re = ''; var hasMagic = !!options.nocase; var escaping = false; // ? => one single character var patternListStack = []; var negativeLists = []; var stateChar; var inClass = false; var reClassStart = -1; var classStart = -1; // . and .. never match anything that doesn't start with ., // even when options.dot is set. var patternStart = pattern.charAt(0) === '.' ? '' // anything // not (start or / followed by . or .. followed by / or end) : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' : '(?!\\.)'; var self = this; function clearStateChar() { if (stateChar) { // we had some state-tracking character // that wasn't consumed by this pass. switch (stateChar) { case '*': re += star; hasMagic = true; break; case '?': re += qmark; hasMagic = true; break; default: re += '\\' + stateChar; break; } self.debug('clearStateChar %j %j', stateChar, re); stateChar = false; } } for (var i = 0, len = pattern.length, c; i < len && (c = pattern.charAt(i)); i++) { this.debug('%s\t%s %s %j', pattern, i, re, c); // skip over any that are escaped. if (escaping && reSpecials[c]) { re += '\\' + c; escaping = false; continue; } switch (c) { case '/': // completely not allowed, even escaped. // Should already be path-split by now. return false; case '\\': clearStateChar(); escaping = true; continue; // the various stateChar values // for the "extglob" stuff. case '?': case '*': case '+': case '@': case '!': this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); // all of those are literals inside a class, except that // the glob [!a] means [^a] in regexp if (inClass) { this.debug(' in class'); if (c === '!' && i === classStart + 1) c = '^'; re += c; continue; } // if we already have a stateChar, then it means // that there was something like ** or +? in there. // Handle the stateChar, then proceed with this one. self.debug('call clearStateChar %j', stateChar); clearStateChar(); stateChar = c; // if extglob is disabled, then +(asdf|foo) isn't a thing. // just clear the statechar *now*, rather than even diving into // the patternList stuff. if (options.noext) clearStateChar(); continue; case '(': if (inClass) { re += '('; continue; } if (!stateChar) { re += '\\('; continue; } patternListStack.push({ type: stateChar, start: i - 1, reStart: re.length, open: plTypes[stateChar].open, close: plTypes[stateChar].close }); // negation is (?:(?!js)[^/]*) re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; this.debug('plType %j %j', stateChar, re); stateChar = false; continue; case ')': if (inClass || !patternListStack.length) { re += '\\)'; continue; } clearStateChar(); hasMagic = true; var pl = patternListStack.pop(); // negation is (?:(?!js)[^/]*) // The others are (?:) re += pl.close; if (pl.type === '!') { negativeLists.push(pl); } pl.reEnd = re.length; continue; case '|': if (inClass || !patternListStack.length || escaping) { re += '\\|'; escaping = false; continue; } clearStateChar(); re += '|'; continue; // these are mostly the same in regexp and glob case '[': // swallow any state-tracking char before the [ clearStateChar(); if (inClass) { re += '\\' + c; continue; } inClass = true; classStart = i; reClassStart = re.length; re += c; continue; case ']': // a right bracket shall lose its special // meaning and represent itself in // a bracket expression if it occurs // first in the list. -- POSIX.2 2.8.3.2 if (i === classStart + 1 || !inClass) { re += '\\' + c; escaping = false; continue; } // handle the case where we left a class open. // "[z-a]" is valid, equivalent to "\[z-a\]" if (inClass) { // split where the last [ was, make sure we don't have // an invalid re. if so, re-walk the contents of the // would-be class to re-translate any characters that // were passed through as-is // TODO: It would probably be faster to determine this // without a try/catch and a new RegExp, but it's tricky // to do safely. For now, this is safe and works. var cs = pattern.substring(classStart + 1, i); try { RegExp('[' + cs + ']'); } catch (er) { // not a valid class! var sp = this.parse(cs, SUBPARSE); re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'; hasMagic = hasMagic || sp[1]; inClass = false; continue; } } // finish up the class. hasMagic = true; inClass = false; re += c; continue; default: // swallow any state char that wasn't consumed clearStateChar(); if (escaping) { // no need escaping = false; } else if (reSpecials[c] && !(c === '^' && inClass)) { re += '\\'; } re += c; } // switch } // for // handle the case where we left a class open. // "[abc" is valid, equivalent to "\[abc" if (inClass) { // split where the last [ was, and escape it // this is a huge pita. We now have to re-walk // the contents of the would-be class to re-translate // any characters that were passed through as-is cs = pattern.substr(classStart + 1); sp = this.parse(cs, SUBPARSE); re = re.substr(0, reClassStart) + '\\[' + sp[0]; hasMagic = hasMagic || sp[1]; } // handle the case where we had a +( thing at the *end* // of the pattern. // each pattern list stack adds 3 chars, and we need to go through // and escape any | chars that were passed through as-is for the regexp. // Go through and escape them, taking care not to double-escape any // | chars that were already escaped. for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { var tail = re.slice(pl.reStart + pl.open.length); this.debug('setting tail', re, pl); // maybe some even number of \, then maybe 1 \, followed by a | tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { if (!$2) { // the | isn't already escaped, so escape it. $2 = '\\'; } // need to escape all those slashes *again*, without escaping the // one that we need for escaping the | character. As it works out, // escaping an even number of slashes can be done by simply repeating // it exactly after itself. That's why this trick works. // // I am sorry that you have to see this. return $1 + $1 + $2 + '|'; }); this.debug('tail=%j\n %s', tail, tail, pl, re); var t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; hasMagic = true; re = re.slice(0, pl.reStart) + t + '\\(' + tail; } // handle trailing things that only matter at the very end. clearStateChar(); if (escaping) { // trailing \\ re += '\\\\'; } // only need to apply the nodot start if the re starts with // something that could conceivably capture a dot var addPatternStart = false; switch (re.charAt(0)) { case '.': case '[': case '(': addPatternStart = true; } // Hack to work around lack of negative lookbehind in JS // A pattern like: *.!(x).!(y|z) needs to ensure that a name // like 'a.xyz.yz' doesn't match. So, the first negative // lookahead, has to look ALL the way ahead, to the end of // the pattern. for (var n = negativeLists.length - 1; n > -1; n--) { var nl = negativeLists[n]; var nlBefore = re.slice(0, nl.reStart); var nlFirst = re.slice(nl.reStart, nl.reEnd - 8); var nlLast = re.slice(nl.reEnd - 8, nl.reEnd); var nlAfter = re.slice(nl.reEnd); nlLast += nlAfter; // Handle nested stuff like *(*.js|!(*.json)), where open parens // mean that we should *not* include the ) in the bit that is considered // "after" the negated section. var openParensBefore = nlBefore.split('(').length - 1; var cleanAfter = nlAfter; for (i = 0; i < openParensBefore; i++) { cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); } nlAfter = cleanAfter; var dollar = ''; if (nlAfter === '' && isSub !== SUBPARSE) { dollar = '$'; } var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast; re = newRe; } // if the re is not "" at this point, then we need to make sure // it doesn't match against an empty path part. // Otherwise a/* will match a/, which it should not. if (re !== '' && hasMagic) { re = '(?=.)' + re; } if (addPatternStart) { re = patternStart + re; } // parsing just a piece of a larger pattern. if (isSub === SUBPARSE) { return [re, hasMagic]; } // skip the regexp for non-magical patterns // unescape anything in it, though, so that it'll be // an exact match against a file etc. if (!hasMagic) { return globUnescape(pattern); } var flags = options.nocase ? 'i' : ''; try { var regExp = new RegExp('^' + re + '$', flags); } catch (er) { // If it was an invalid regular expression, then it can't match // anything. This trick looks for a character after the end of // the string, which is of course impossible, except in multi-line // mode, but it's not a /m regex. return new RegExp('$.'); } regExp._glob = pattern; regExp._src = re; return regExp; } minimatch.makeRe = function (pattern, options) { return new Minimatch(pattern, options || {}).makeRe(); }; Minimatch.prototype.makeRe = makeRe; function makeRe() { if (this.regexp || this.regexp === false) return this.regexp; // at this point, this.set is a 2d array of partial // pattern strings, or "**". // // It's better to use .match(). This function shouldn't // be used, really, but it's pretty convenient sometimes, // when you just want to work with a regex. var set = this.set; if (!set.length) { this.regexp = false; return this.regexp; } var options = this.options; var twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot; var flags = options.nocase ? 'i' : ''; var re = set.map(function (pattern) { return pattern.map(function (p) { return p === GLOBSTAR ? twoStar : typeof p === 'string' ? regExpEscape(p) : p._src; }).join('\\\/'); }).join('|'); // must match entire pattern // ending in a * or ** will make it less strict. re = '^(?:' + re + ')$'; // can match anything, as long as it's not this. if (this.negate) re = '^(?!' + re + ').*$'; try { this.regexp = new RegExp(re, flags); } catch (ex) { this.regexp = false; } return this.regexp; } minimatch.match = function (list, pattern, options) { options = options || {}; var mm = new Minimatch(pattern, options); list = list.filter(function (f) { return mm.match(f); }); if (mm.options.nonull && !list.length) { list.push(pattern); } return list; }; Minimatch.prototype.match = match; function match(f, partial) { this.debug('match', f, this.pattern); // short-circuit in the case of busted things. // comments, etc. if (this.comment) return false; if (this.empty) return f === ''; if (f === '/' && partial) return true; var options = this.options; // windows: need to use /, not \ if (path.sep !== '/') { f = f.split(path.sep).join('/'); } // treat the test path as a set of pathparts. f = f.split(slashSplit); this.debug(this.pattern, 'split', f); // just ONE of the pattern sets in this.set needs to match // in order for it to be valid. If negating, then just one // match means that we have failed. // Either way, return on the first hit. var set = this.set; this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment var filename; var i; for (i = f.length - 1; i >= 0; i--) { filename = f[i]; if (filename) break; } for (i = 0; i < set.length; i++) { var pattern = set[i]; var file = f; if (options.matchBase && pattern.length === 1) { file = [filename]; } var hit = this.matchOne(file, pattern, partial); if (hit) { if (options.flipNegate) return true; return !this.negate; } } // didn't get any hits. this is success if it's a negative // pattern, failure otherwise. if (options.flipNegate) return false; return this.negate; } // set partial to true to test if, for example, // "/a/b" matches the start of "/*/b/*/d" // Partial means, if you run out of file before you run // out of pattern, then that's fine, as long as all // the parts match. Minimatch.prototype.matchOne = function (file, pattern, partial) { var options = this.options; this.debug('matchOne', { 'this': this, file: file, pattern: pattern }); this.debug('matchOne', file.length, pattern.length); for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { this.debug('matchOne loop'); var p = pattern[pi]; var f = file[fi]; this.debug(pattern, p, f); // should be impossible. // some invalid regexp stuff in the set. if (p === false) return false; if (p === GLOBSTAR) { this.debug('GLOBSTAR', [pattern, p, f]); // "**" // a/**/b/**/c would match the following: // a/b/x/y/z/c // a/x/y/z/b/c // a/b/x/b/x/c // a/b/c // To do this, take the rest of the pattern after // the **, and see if it would match the file remainder. // If so, return success. // If not, the ** "swallows" a segment, and try again. // This is recursively awful. // // a/**/b/**/c matching a/b/x/y/z/c // - a matches a // - doublestar // - matchOne(b/x/y/z/c, b/**/c) // - b matches b // - doublestar // - matchOne(x/y/z/c, c) -> no // - matchOne(y/z/c, c) -> no // - matchOne(z/c, c) -> no // - matchOne(c, c) yes, hit var fr = fi; var pr = pi + 1; if (pr === pl) { this.debug('** at the end'); // a ** at the end will just swallow the rest. // We have found a match. // however, it will not swallow /.x, unless // options.dot is set. // . and .. are *never* matched by **, for explosively // exponential reasons. for (; fi < fl; fi++) { if (file[fi] === '.' || file[fi] === '..' || !options.dot && file[fi].charAt(0) === '.') return false; } return true; } // ok, let's see if we can swallow whatever we can. while (fr < fl) { var swallowee = file[fr]; this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); // XXX remove this slice. Just pass the start index. if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { this.debug('globstar found match!', fr, fl, swallowee); // found a match. return true; } else { // can't swallow "." or ".." ever. // can only swallow ".foo" when explicitly asked. if (swallowee === '.' || swallowee === '..' || !options.dot && swallowee.charAt(0) === '.') { this.debug('dot detected!', file, fr, pattern, pr); break; } // ** swallows a segment, and continue. this.debug('globstar swallow a segment, and continue'); fr++; } } // no match was found. // However, in partial mode, we can't say this is necessarily over. // If there's more *pattern* left, then if (partial) { // ran out of file this.debug('\n>>> no match, partial?', file, fr, pattern, pr); if (fr === fl) return true; } return false; } // something other than ** // non-magic patterns just have to match exactly // patterns with magic have been turned into regexps. var hit; if (typeof p === 'string') { if (options.nocase) { hit = f.toLowerCase() === p.toLowerCase(); } else { hit = f === p; } this.debug('string match', p, f, hit); } else { hit = f.match(p); this.debug('pattern match', p, f, hit); } if (!hit) return false; } // Note: ending in / means that we'll get a final "" // at the end of the pattern. This can only match a // corresponding "" at the end of the file. // If the file ends in /, then it can only match a // a pattern that ends in /, unless the pattern just // doesn't have any more for it. But, a/b/ should *not* // match "a/b/*", even though "" matches against the // [^/]*? pattern, except in partial mode, where it might // simply not be reached yet. // However, a/b/ should still satisfy a/* // now either we fell off the end of the pattern, or we're done. if (fi === fl && pi === pl) { // ran out of pattern and filename at the same time. // an exact hit! return true; } else if (fi === fl) { // ran out of file, but still had pattern left. // this is ok if we're doing the match as part of // a glob fs traversal. return partial; } else if (pi === pl) { // ran out of pattern, still have file left. // this is only acceptable if we're on the very last // empty segment of a file with a trailing slash. // a/* should match a/b/ var emptyFileEnd = fi === fl - 1 && file[fi] === ''; return emptyFileEnd; } // should be unreachable. throw new Error('wtf?'); }; // replace stuff like \* with * function globUnescape(s) { return s.replace(/\\(.)/g, '$1'); } function regExpEscape(s) { return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); } },{"brace-expansion":51,"path":96}],94:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** * Helpers. */ var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ module.exports = function (val, options) { options = options || {}; var type = typeof val === 'undefined' ? 'undefined' : _typeof(val); if (type === 'string' && val.length > 0) { return parse(val); } else if (type === 'number' && isNaN(val) === false) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } },{}],95:[function(require,module,exports){ "use strict"; /* * @version 1.4.0 * @date 2015-10-26 * @stability 3 - Stable * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite) * @license MIT License */ var naturalCompare = function naturalCompare(a, b) { var i, codeA, codeB = 1, posA = 0, posB = 0, alphabet = String.alphabet; function getCode(str, pos, code) { if (code) { for (i = pos; code = getCode(str, i), code < 76 && code > 65;) { ++i; }return +str.slice(pos - 1, i); } code = alphabet && alphabet.indexOf(str.charAt(pos)); return code > -1 ? code + 76 : (code = str.charCodeAt(pos) || 0, code < 45 || code > 127) ? code : code < 46 ? 65 // - : code < 48 ? code - 1 : code < 58 ? code + 18 // 0-9 : code < 65 ? code - 11 : code < 91 ? code + 11 // A-Z : code < 97 ? code - 37 : code < 123 ? code + 5 // a-z : code - 63; } if ((a += "") != (b += "")) for (; codeB;) { codeA = getCode(a, posA++); codeB = getCode(b, posB++); if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) { codeA = getCode(a, posA, posA); codeB = getCode(b, posB, posA = i); posB = i; } if (codeA != codeB) return codeA < codeB ? -1 : 1; } return 0; }; try { module.exports = naturalCompare; } catch (e) { String.naturalCompare = naturalCompare; } },{}],96:[function(require,module,exports){ (function (process){ 'use strict'; // .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1, // backported and transplited with Babel, with backwards-compat fixes // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // resolves . and .. elements in a path array with directory names there // must be no slashes, empty elements, or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = parts.length - 1; i >= 0; i--) { var last = parts[i]; if (last === '.') { parts.splice(i, 1); } else if (last === '..') { parts.splice(i, 1); up++; } else if (up) { parts.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (allowAboveRoot) { for (; up--; up) { parts.unshift('..'); } } return parts; } // path.resolve([from ...], to) // posix version exports.resolve = function () { var resolvedPath = '', resolvedAbsolute = false; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path = i >= 0 ? arguments[i] : process.cwd(); // Skip empty and invalid entries if (typeof path !== 'string') { throw new TypeError('Arguments to path.resolve must be strings'); } else if (!path) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charAt(0) === '/'; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function (p) { return !!p; }), !resolvedAbsolute).join('/'); return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'; }; // path.normalize(path) // posix version exports.normalize = function (path) { var isAbsolute = exports.isAbsolute(path), trailingSlash = substr(path, -1) === '/'; // Normalize the path path = normalizeArray(filter(path.split('/'), function (p) { return !!p; }), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.'; } if (path && trailingSlash) { path += '/'; } return (isAbsolute ? '/' : '') + path; }; // posix version exports.isAbsolute = function (path) { return path.charAt(0) === '/'; }; // posix version exports.join = function () { var paths = Array.prototype.slice.call(arguments, 0); return exports.normalize(filter(paths, function (p, index) { if (typeof p !== 'string') { throw new TypeError('Arguments to path.join must be strings'); } return p; }).join('/')); }; // path.relative(from, to) // posix version exports.relative = function (from, to) { from = exports.resolve(from).substr(1); to = exports.resolve(to).substr(1); function trim(arr) { var start = 0; for (; start < arr.length; start++) { if (arr[start] !== '') break; } var end = arr.length - 1; for (; end >= 0; end--) { if (arr[end] !== '') break; } if (start > end) return []; return arr.slice(start, end - start + 1); } var fromParts = trim(from.split('/')); var toParts = trim(to.split('/')); var length = Math.min(fromParts.length, toParts.length); var samePartsLength = length; for (var i = 0; i < length; i++) { if (fromParts[i] !== toParts[i]) { samePartsLength = i; break; } } var outputParts = []; for (var i = samePartsLength; i < fromParts.length; i++) { outputParts.push('..'); } outputParts = outputParts.concat(toParts.slice(samePartsLength)); return outputParts.join('/'); }; exports.sep = '/'; exports.delimiter = ':'; exports.dirname = function (path) { if (typeof path !== 'string') path = path + ''; if (path.length === 0) return '.'; var code = path.charCodeAt(0); var hasRoot = code === 47 /*/*/; var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { code = path.charCodeAt(i); if (code === 47 /*/*/) { if (!matchedSlash) { end = i; break; } } else { // We saw the first non-path separator matchedSlash = false; } } if (end === -1) return hasRoot ? '/' : '.'; if (hasRoot && end === 1) { // return '//'; // Backwards-compat fix: return '/'; } return path.slice(0, end); }; function basename(path) { if (typeof path !== 'string') path = path + ''; var start = 0; var end = -1; var matchedSlash = true; var i; for (i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { // We saw the first non-path separator, mark this as the end of our // path component matchedSlash = false; end = i + 1; } } if (end === -1) return ''; return path.slice(start, end); } // Uses a mixed approach for backwards-compatibility, as ext behavior changed // in new Node.js versions, so only basename() above is backported here exports.basename = function (path, ext) { var f = basename(path); if (ext && f.substr(-1 * ext.length) === ext) { f = f.substr(0, f.length - ext.length); } return f; }; exports.extname = function (path) { if (typeof path !== 'string') path = path + ''; var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; for (var i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === 46 /*.*/) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { return ''; } return path.slice(startDot, end); }; function filter(xs, f) { if (xs.filter) return xs.filter(f); var res = []; for (var i = 0; i < xs.length; i++) { if (f(xs[i], i, xs)) res.push(xs[i]); } return res; } // String.prototype.substr - negative index don't work in IE8 var substr = 'ab'.substr(-1) === 'b' ? function (str, start, len) { return str.substr(start, len); } : function (str, start, len) { if (start < 0) start = str.length + start; return str.substr(start, len); }; }).call(this,require('_process')) },{"_process":103}],97:[function(require,module,exports){ 'use strict'; // Generated by LiveScript 1.4.0 var apply, curry, flip, fix, over, memoize, slice$ = [].slice, toString$ = {}.toString; apply = curry$(function (f, list) { return f.apply(null, list); }); curry = function curry(f) { return curry$(f); }; flip = curry$(function (f, x, y) { return f(y, x); }); fix = function fix(f) { return function (g) { return function () { return f(g(g)).apply(null, arguments); }; }(function (g) { return function () { return f(g(g)).apply(null, arguments); }; }); }; over = curry$(function (f, g, x, y) { return f(g(x), g(y)); }); memoize = function memoize(f) { var memo; memo = {}; return function () { var args, key, arg; args = slice$.call(arguments); key = function () { var i$, ref$, len$, results$ = []; for (i$ = 0, len$ = (ref$ = args).length; i$ < len$; ++i$) { arg = ref$[i$]; results$.push(arg + toString$.call(arg).slice(8, -1)); } return results$; }().join(''); return memo[key] = key in memo ? memo[key] : f.apply(null, args); }; }; module.exports = { curry: curry, flip: flip, fix: fix, apply: apply, over: over, memoize: memoize }; function curry$(f, bound) { var context, _curry = function _curry(args) { return f.length > 1 ? function () { var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } },{}],98:[function(require,module,exports){ 'use strict'; // Generated by LiveScript 1.4.0 var each, map, compact, filter, reject, partition, find, head, first, tail, last, initial, empty, reverse, unique, uniqueBy, fold, foldl, fold1, foldl1, foldr, foldr1, unfoldr, concat, concatMap, _flatten, difference, intersection, union, countBy, groupBy, andList, orList, any, all, sort, sortWith, sortBy, sum, product, mean, average, maximum, minimum, maximumBy, minimumBy, scan, scanl, scan1, scanl1, scanr, scanr1, slice, take, drop, splitAt, takeWhile, dropWhile, span, breakList, zip, zipWith, zipAll, zipAllWith, at, elemIndex, elemIndices, findIndex, findIndices, toString$ = {}.toString, slice$ = [].slice; each = curry$(function (f, xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; f(x); } return xs; }); map = curry$(function (f, xs) { var i$, len$, x, results$ = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; results$.push(f(x)); } return results$; }); compact = function compact(xs) { var i$, len$, x, results$ = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (x) { results$.push(x); } } return results$; }; filter = curry$(function (f, xs) { var i$, len$, x, results$ = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (f(x)) { results$.push(x); } } return results$; }); reject = curry$(function (f, xs) { var i$, len$, x, results$ = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (!f(x)) { results$.push(x); } } return results$; }); partition = curry$(function (f, xs) { var passed, failed, i$, len$, x; passed = []; failed = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; (f(x) ? passed : failed).push(x); } return [passed, failed]; }); find = curry$(function (f, xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (f(x)) { return x; } } }); head = first = function first(xs) { return xs[0]; }; tail = function tail(xs) { if (!xs.length) { return; } return xs.slice(1); }; last = function last(xs) { return xs[xs.length - 1]; }; initial = function initial(xs) { if (!xs.length) { return; } return xs.slice(0, -1); }; empty = function empty(xs) { return !xs.length; }; reverse = function reverse(xs) { return xs.concat().reverse(); }; unique = function unique(xs) { var result, i$, len$, x; result = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (!in$(x, result)) { result.push(x); } } return result; }; uniqueBy = curry$(function (f, xs) { var seen, i$, len$, x, val, results$ = []; seen = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; val = f(x); if (in$(val, seen)) { continue; } seen.push(val); results$.push(x); } return results$; }); fold = foldl = curry$(function (f, memo, xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; memo = f(memo, x); } return memo; }); fold1 = foldl1 = curry$(function (f, xs) { return fold(f, xs[0], xs.slice(1)); }); foldr = curry$(function (f, memo, xs) { var i$, x; for (i$ = xs.length - 1; i$ >= 0; --i$) { x = xs[i$]; memo = f(x, memo); } return memo; }); foldr1 = curry$(function (f, xs) { return foldr(f, xs[xs.length - 1], xs.slice(0, -1)); }); unfoldr = curry$(function (f, b) { var result, x, that; result = []; x = b; while ((that = f(x)) != null) { result.push(that[0]); x = that[1]; } return result; }); concat = function concat(xss) { return [].concat.apply([], xss); }; concatMap = curry$(function (f, xs) { var x; return [].concat.apply([], function () { var i$, ref$, len$, results$ = []; for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) { x = ref$[i$]; results$.push(f(x)); } return results$; }()); }); _flatten = function flatten(xs) { var x; return [].concat.apply([], function () { var i$, ref$, len$, results$ = []; for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) { x = ref$[i$]; if (toString$.call(x).slice(8, -1) === 'Array') { results$.push(_flatten(x)); } else { results$.push(x); } } return results$; }()); }; difference = function difference(xs) { var yss, results, i$, len$, x, j$, len1$, ys; yss = slice$.call(arguments, 1); results = []; outer: for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; for (j$ = 0, len1$ = yss.length; j$ < len1$; ++j$) { ys = yss[j$]; if (in$(x, ys)) { continue outer; } } results.push(x); } return results; }; intersection = function intersection(xs) { var yss, results, i$, len$, x, j$, len1$, ys; yss = slice$.call(arguments, 1); results = []; outer: for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; for (j$ = 0, len1$ = yss.length; j$ < len1$; ++j$) { ys = yss[j$]; if (!in$(x, ys)) { continue outer; } } results.push(x); } return results; }; union = function union() { var xss, results, i$, len$, xs, j$, len1$, x; xss = slice$.call(arguments); results = []; for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) { xs = xss[i$]; for (j$ = 0, len1$ = xs.length; j$ < len1$; ++j$) { x = xs[j$]; if (!in$(x, results)) { results.push(x); } } } return results; }; countBy = curry$(function (f, xs) { var results, i$, len$, x, key; results = {}; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; key = f(x); if (key in results) { results[key] += 1; } else { results[key] = 1; } } return results; }); groupBy = curry$(function (f, xs) { var results, i$, len$, x, key; results = {}; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; key = f(x); if (key in results) { results[key].push(x); } else { results[key] = [x]; } } return results; }); andList = function andList(xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (!x) { return false; } } return true; }; orList = function orList(xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (x) { return true; } } return false; }; any = curry$(function (f, xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (f(x)) { return true; } } return false; }); all = curry$(function (f, xs) { var i$, len$, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; if (!f(x)) { return false; } } return true; }); sort = function sort(xs) { return xs.concat().sort(function (x, y) { if (x > y) { return 1; } else if (x < y) { return -1; } else { return 0; } }); }; sortWith = curry$(function (f, xs) { return xs.concat().sort(f); }); sortBy = curry$(function (f, xs) { return xs.concat().sort(function (x, y) { if (f(x) > f(y)) { return 1; } else if (f(x) < f(y)) { return -1; } else { return 0; } }); }); sum = function sum(xs) { var result, i$, len$, x; result = 0; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; result += x; } return result; }; product = function product(xs) { var result, i$, len$, x; result = 1; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; result *= x; } return result; }; mean = average = function average(xs) { var sum, i$, len$, x; sum = 0; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { x = xs[i$]; sum += x; } return sum / xs.length; }; maximum = function maximum(xs) { var max, i$, ref$, len$, x; max = xs[0]; for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) { x = ref$[i$]; if (x > max) { max = x; } } return max; }; minimum = function minimum(xs) { var min, i$, ref$, len$, x; min = xs[0]; for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) { x = ref$[i$]; if (x < min) { min = x; } } return min; }; maximumBy = curry$(function (f, xs) { var max, i$, ref$, len$, x; max = xs[0]; for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) { x = ref$[i$]; if (f(x) > f(max)) { max = x; } } return max; }); minimumBy = curry$(function (f, xs) { var min, i$, ref$, len$, x; min = xs[0]; for (i$ = 0, len$ = (ref$ = xs.slice(1)).length; i$ < len$; ++i$) { x = ref$[i$]; if (f(x) < f(min)) { min = x; } } return min; }); scan = scanl = curry$(function (f, memo, xs) { var last, x; last = memo; return [memo].concat(function () { var i$, ref$, len$, results$ = []; for (i$ = 0, len$ = (ref$ = xs).length; i$ < len$; ++i$) { x = ref$[i$]; results$.push(last = f(last, x)); } return results$; }()); }); scan1 = scanl1 = curry$(function (f, xs) { if (!xs.length) { return; } return scan(f, xs[0], xs.slice(1)); }); scanr = curry$(function (f, memo, xs) { xs = xs.concat().reverse(); return scan(f, memo, xs).reverse(); }); scanr1 = curry$(function (f, xs) { if (!xs.length) { return; } xs = xs.concat().reverse(); return scan(f, xs[0], xs.slice(1)).reverse(); }); slice = curry$(function (x, y, xs) { return xs.slice(x, y); }); take = curry$(function (n, xs) { if (n <= 0) { return xs.slice(0, 0); } else { return xs.slice(0, n); } }); drop = curry$(function (n, xs) { if (n <= 0) { return xs; } else { return xs.slice(n); } }); splitAt = curry$(function (n, xs) { return [take(n, xs), drop(n, xs)]; }); takeWhile = curry$(function (p, xs) { var len, i; len = xs.length; if (!len) { return xs; } i = 0; while (i < len && p(xs[i])) { i += 1; } return xs.slice(0, i); }); dropWhile = curry$(function (p, xs) { var len, i; len = xs.length; if (!len) { return xs; } i = 0; while (i < len && p(xs[i])) { i += 1; } return xs.slice(i); }); span = curry$(function (p, xs) { return [takeWhile(p, xs), dropWhile(p, xs)]; }); breakList = curry$(function (p, xs) { return span(compose$(p, not$), xs); }); zip = curry$(function (xs, ys) { var result, len, i$, len$, i, x; result = []; len = ys.length; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { i = i$; x = xs[i$]; if (i === len) { break; } result.push([x, ys[i]]); } return result; }); zipWith = curry$(function (f, xs, ys) { var result, len, i$, len$, i, x; result = []; len = ys.length; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { i = i$; x = xs[i$]; if (i === len) { break; } result.push(f(x, ys[i])); } return result; }); zipAll = function zipAll() { var xss, minLength, i$, len$, xs, ref$, i, lresult$, j$, results$ = []; xss = slice$.call(arguments); minLength = undefined; for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) { xs = xss[i$]; minLength <= (ref$ = xs.length) || (minLength = ref$); } for (i$ = 0; i$ < minLength; ++i$) { i = i$; lresult$ = []; for (j$ = 0, len$ = xss.length; j$ < len$; ++j$) { xs = xss[j$]; lresult$.push(xs[i]); } results$.push(lresult$); } return results$; }; zipAllWith = function zipAllWith(f) { var xss, minLength, i$, len$, xs, ref$, i, results$ = []; xss = slice$.call(arguments, 1); minLength = undefined; for (i$ = 0, len$ = xss.length; i$ < len$; ++i$) { xs = xss[i$]; minLength <= (ref$ = xs.length) || (minLength = ref$); } for (i$ = 0; i$ < minLength; ++i$) { i = i$; results$.push(f.apply(null, fn$())); } return results$; function fn$() { var i$, ref$, len$, results$ = []; for (i$ = 0, len$ = (ref$ = xss).length; i$ < len$; ++i$) { xs = ref$[i$]; results$.push(xs[i]); } return results$; } }; at = curry$(function (n, xs) { if (n < 0) { return xs[xs.length + n]; } else { return xs[n]; } }); elemIndex = curry$(function (el, xs) { var i$, len$, i, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { i = i$; x = xs[i$]; if (x === el) { return i; } } }); elemIndices = curry$(function (el, xs) { var i$, len$, i, x, results$ = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { i = i$; x = xs[i$]; if (x === el) { results$.push(i); } } return results$; }); findIndex = curry$(function (f, xs) { var i$, len$, i, x; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { i = i$; x = xs[i$]; if (f(x)) { return i; } } }); findIndices = curry$(function (f, xs) { var i$, len$, i, x, results$ = []; for (i$ = 0, len$ = xs.length; i$ < len$; ++i$) { i = i$; x = xs[i$]; if (f(x)) { results$.push(i); } } return results$; }); module.exports = { each: each, map: map, filter: filter, compact: compact, reject: reject, partition: partition, find: find, head: head, first: first, tail: tail, last: last, initial: initial, empty: empty, reverse: reverse, difference: difference, intersection: intersection, union: union, countBy: countBy, groupBy: groupBy, fold: fold, fold1: fold1, foldl: foldl, foldl1: foldl1, foldr: foldr, foldr1: foldr1, unfoldr: unfoldr, andList: andList, orList: orList, any: any, all: all, unique: unique, uniqueBy: uniqueBy, sort: sort, sortWith: sortWith, sortBy: sortBy, sum: sum, product: product, mean: mean, average: average, concat: concat, concatMap: concatMap, flatten: _flatten, maximum: maximum, minimum: minimum, maximumBy: maximumBy, minimumBy: minimumBy, scan: scan, scan1: scan1, scanl: scanl, scanl1: scanl1, scanr: scanr, scanr1: scanr1, slice: slice, take: take, drop: drop, splitAt: splitAt, takeWhile: takeWhile, dropWhile: dropWhile, span: span, breakList: breakList, zip: zip, zipWith: zipWith, zipAll: zipAll, zipAllWith: zipAllWith, at: at, elemIndex: elemIndex, elemIndices: elemIndices, findIndex: findIndex, findIndices: findIndices }; function curry$(f, bound) { var context, _curry = function _curry(args) { return f.length > 1 ? function () { var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } function in$(x, xs) { var i = -1, l = xs.length >>> 0; while (++i < l) { if (x === xs[i]) return true; }return false; } function compose$() { var functions = arguments; return function () { var i, result; result = functions[0].apply(this, arguments); for (i = 1; i < functions.length; ++i) { result = functions[i](result); } return result; }; } function not$(x) { return !x; } },{}],99:[function(require,module,exports){ "use strict"; // Generated by LiveScript 1.4.0 var max, min, negate, abs, signum, quot, rem, div, mod, recip, pi, tau, exp, sqrt, ln, pow, sin, tan, cos, asin, acos, atan, atan2, truncate, round, ceiling, floor, isItNaN, even, odd, gcd, lcm; max = curry$(function (x$, y$) { return x$ > y$ ? x$ : y$; }); min = curry$(function (x$, y$) { return x$ < y$ ? x$ : y$; }); negate = function negate(x) { return -x; }; abs = Math.abs; signum = function signum(x) { if (x < 0) { return -1; } else if (x > 0) { return 1; } else { return 0; } }; quot = curry$(function (x, y) { return ~~(x / y); }); rem = curry$(function (x$, y$) { return x$ % y$; }); div = curry$(function (x, y) { return Math.floor(x / y); }); mod = curry$(function (x$, y$) { var ref$; return (x$ % (ref$ = y$) + ref$) % ref$; }); recip = function recip(it) { return 1 / it; }; pi = Math.PI; tau = pi * 2; exp = Math.exp; sqrt = Math.sqrt; ln = Math.log; pow = curry$(function (x$, y$) { return Math.pow(x$, y$); }); sin = Math.sin; tan = Math.tan; cos = Math.cos; asin = Math.asin; acos = Math.acos; atan = Math.atan; atan2 = curry$(function (x, y) { return Math.atan2(x, y); }); truncate = function truncate(x) { return ~~x; }; round = Math.round; ceiling = Math.ceil; floor = Math.floor; isItNaN = function isItNaN(x) { return x !== x; }; even = function even(x) { return x % 2 === 0; }; odd = function odd(x) { return x % 2 !== 0; }; gcd = curry$(function (x, y) { var z; x = Math.abs(x); y = Math.abs(y); while (y !== 0) { z = x % y; x = y; y = z; } return x; }); lcm = curry$(function (x, y) { return Math.abs(Math.floor(x / gcd(x, y) * y)); }); module.exports = { max: max, min: min, negate: negate, abs: abs, signum: signum, quot: quot, rem: rem, div: div, mod: mod, recip: recip, pi: pi, tau: tau, exp: exp, sqrt: sqrt, ln: ln, pow: pow, sin: sin, tan: tan, cos: cos, acos: acos, asin: asin, atan: atan, atan2: atan2, truncate: truncate, round: round, ceiling: ceiling, floor: floor, isItNaN: isItNaN, even: even, odd: odd, gcd: gcd, lcm: lcm }; function curry$(f, bound) { var context, _curry = function _curry(args) { return f.length > 1 ? function () { var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } },{}],100:[function(require,module,exports){ "use strict"; // Generated by LiveScript 1.4.0 var values, keys, pairsToObj, objToPairs, listsToObj, objToLists, empty, each, map, compact, filter, reject, partition, find; values = function values(object) { var i$, x, results$ = []; for (i$ in object) { x = object[i$]; results$.push(x); } return results$; }; keys = function keys(object) { var x, results$ = []; for (x in object) { results$.push(x); } return results$; }; pairsToObj = function pairsToObj(object) { var i$, len$, x, resultObj$ = {}; for (i$ = 0, len$ = object.length; i$ < len$; ++i$) { x = object[i$]; resultObj$[x[0]] = x[1]; } return resultObj$; }; objToPairs = function objToPairs(object) { var key, value, results$ = []; for (key in object) { value = object[key]; results$.push([key, value]); } return results$; }; listsToObj = curry$(function (keys, values) { var i$, len$, i, key, resultObj$ = {}; for (i$ = 0, len$ = keys.length; i$ < len$; ++i$) { i = i$; key = keys[i$]; resultObj$[key] = values[i]; } return resultObj$; }); objToLists = function objToLists(object) { var keys, values, key, value; keys = []; values = []; for (key in object) { value = object[key]; keys.push(key); values.push(value); } return [keys, values]; }; empty = function empty(object) { var x; for (x in object) { return false; } return true; }; each = curry$(function (f, object) { var i$, x; for (i$ in object) { x = object[i$]; f(x); } return object; }); map = curry$(function (f, object) { var k, x, resultObj$ = {}; for (k in object) { x = object[k]; resultObj$[k] = f(x); } return resultObj$; }); compact = function compact(object) { var k, x, resultObj$ = {}; for (k in object) { x = object[k]; if (x) { resultObj$[k] = x; } } return resultObj$; }; filter = curry$(function (f, object) { var k, x, resultObj$ = {}; for (k in object) { x = object[k]; if (f(x)) { resultObj$[k] = x; } } return resultObj$; }); reject = curry$(function (f, object) { var k, x, resultObj$ = {}; for (k in object) { x = object[k]; if (!f(x)) { resultObj$[k] = x; } } return resultObj$; }); partition = curry$(function (f, object) { var passed, failed, k, x; passed = {}; failed = {}; for (k in object) { x = object[k]; (f(x) ? passed : failed)[k] = x; } return [passed, failed]; }); find = curry$(function (f, object) { var i$, x; for (i$ in object) { x = object[i$]; if (f(x)) { return x; } } }); module.exports = { values: values, keys: keys, pairsToObj: pairsToObj, objToPairs: objToPairs, listsToObj: listsToObj, objToLists: objToLists, empty: empty, each: each, map: map, filter: filter, compact: compact, reject: reject, partition: partition, find: find }; function curry$(f, bound) { var context, _curry = function _curry(args) { return f.length > 1 ? function () { var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } },{}],101:[function(require,module,exports){ 'use strict'; // Generated by LiveScript 1.4.0 var split, join, lines, unlines, words, unwords, chars, unchars, reverse, repeat, capitalize, camelize, dasherize; split = curry$(function (sep, str) { return str.split(sep); }); join = curry$(function (sep, xs) { return xs.join(sep); }); lines = function lines(str) { if (!str.length) { return []; } return str.split('\n'); }; unlines = function unlines(it) { return it.join('\n'); }; words = function words(str) { if (!str.length) { return []; } return str.split(/[ ]+/); }; unwords = function unwords(it) { return it.join(' '); }; chars = function chars(it) { return it.split(''); }; unchars = function unchars(it) { return it.join(''); }; reverse = function reverse(str) { return str.split('').reverse().join(''); }; repeat = curry$(function (n, str) { var result, i$; result = ''; for (i$ = 0; i$ < n; ++i$) { result += str; } return result; }); capitalize = function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); }; camelize = function camelize(it) { return it.replace(/[-_]+(.)?/g, function (arg$, c) { return (c != null ? c : '').toUpperCase(); }); }; dasherize = function dasherize(str) { return str.replace(/([^-A-Z])([A-Z]+)/g, function (arg$, lower, upper) { return lower + "-" + (upper.length > 1 ? upper : upper.toLowerCase()); }).replace(/^([A-Z]+)/, function (arg$, upper) { if (upper.length > 1) { return upper + "-"; } else { return upper.toLowerCase(); } }); }; module.exports = { split: split, join: join, lines: lines, unlines: unlines, words: words, unwords: unwords, chars: chars, unchars: unchars, reverse: reverse, repeat: repeat, capitalize: capitalize, camelize: camelize, dasherize: dasherize }; function curry$(f, bound) { var context, _curry = function _curry(args) { return f.length > 1 ? function () { var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } },{}],102:[function(require,module,exports){ 'use strict'; // Generated by LiveScript 1.4.0 var Func, List, Obj, Str, Num, id, isType, replicate, prelude, toString$ = {}.toString; Func = require('./Func.js'); List = require('./List.js'); Obj = require('./Obj.js'); Str = require('./Str.js'); Num = require('./Num.js'); id = function id(x) { return x; }; isType = curry$(function (type, x) { return toString$.call(x).slice(8, -1) === type; }); replicate = curry$(function (n, x) { var i$, results$ = []; for (i$ = 0; i$ < n; ++i$) { results$.push(x); } return results$; }); Str.empty = List.empty; Str.slice = List.slice; Str.take = List.take; Str.drop = List.drop; Str.splitAt = List.splitAt; Str.takeWhile = List.takeWhile; Str.dropWhile = List.dropWhile; Str.span = List.span; Str.breakStr = List.breakList; prelude = { Func: Func, List: List, Obj: Obj, Str: Str, Num: Num, id: id, isType: isType, replicate: replicate }; prelude.each = List.each; prelude.map = List.map; prelude.filter = List.filter; prelude.compact = List.compact; prelude.reject = List.reject; prelude.partition = List.partition; prelude.find = List.find; prelude.head = List.head; prelude.first = List.first; prelude.tail = List.tail; prelude.last = List.last; prelude.initial = List.initial; prelude.empty = List.empty; prelude.reverse = List.reverse; prelude.difference = List.difference; prelude.intersection = List.intersection; prelude.union = List.union; prelude.countBy = List.countBy; prelude.groupBy = List.groupBy; prelude.fold = List.fold; prelude.foldl = List.foldl; prelude.fold1 = List.fold1; prelude.foldl1 = List.foldl1; prelude.foldr = List.foldr; prelude.foldr1 = List.foldr1; prelude.unfoldr = List.unfoldr; prelude.andList = List.andList; prelude.orList = List.orList; prelude.any = List.any; prelude.all = List.all; prelude.unique = List.unique; prelude.uniqueBy = List.uniqueBy; prelude.sort = List.sort; prelude.sortWith = List.sortWith; prelude.sortBy = List.sortBy; prelude.sum = List.sum; prelude.product = List.product; prelude.mean = List.mean; prelude.average = List.average; prelude.concat = List.concat; prelude.concatMap = List.concatMap; prelude.flatten = List.flatten; prelude.maximum = List.maximum; prelude.minimum = List.minimum; prelude.maximumBy = List.maximumBy; prelude.minimumBy = List.minimumBy; prelude.scan = List.scan; prelude.scanl = List.scanl; prelude.scan1 = List.scan1; prelude.scanl1 = List.scanl1; prelude.scanr = List.scanr; prelude.scanr1 = List.scanr1; prelude.slice = List.slice; prelude.take = List.take; prelude.drop = List.drop; prelude.splitAt = List.splitAt; prelude.takeWhile = List.takeWhile; prelude.dropWhile = List.dropWhile; prelude.span = List.span; prelude.breakList = List.breakList; prelude.zip = List.zip; prelude.zipWith = List.zipWith; prelude.zipAll = List.zipAll; prelude.zipAllWith = List.zipAllWith; prelude.at = List.at; prelude.elemIndex = List.elemIndex; prelude.elemIndices = List.elemIndices; prelude.findIndex = List.findIndex; prelude.findIndices = List.findIndices; prelude.apply = Func.apply; prelude.curry = Func.curry; prelude.flip = Func.flip; prelude.fix = Func.fix; prelude.over = Func.over; prelude.split = Str.split; prelude.join = Str.join; prelude.lines = Str.lines; prelude.unlines = Str.unlines; prelude.words = Str.words; prelude.unwords = Str.unwords; prelude.chars = Str.chars; prelude.unchars = Str.unchars; prelude.repeat = Str.repeat; prelude.capitalize = Str.capitalize; prelude.camelize = Str.camelize; prelude.dasherize = Str.dasherize; prelude.values = Obj.values; prelude.keys = Obj.keys; prelude.pairsToObj = Obj.pairsToObj; prelude.objToPairs = Obj.objToPairs; prelude.listsToObj = Obj.listsToObj; prelude.objToLists = Obj.objToLists; prelude.max = Num.max; prelude.min = Num.min; prelude.negate = Num.negate; prelude.abs = Num.abs; prelude.signum = Num.signum; prelude.quot = Num.quot; prelude.rem = Num.rem; prelude.div = Num.div; prelude.mod = Num.mod; prelude.recip = Num.recip; prelude.pi = Num.pi; prelude.tau = Num.tau; prelude.exp = Num.exp; prelude.sqrt = Num.sqrt; prelude.ln = Num.ln; prelude.pow = Num.pow; prelude.sin = Num.sin; prelude.tan = Num.tan; prelude.cos = Num.cos; prelude.acos = Num.acos; prelude.asin = Num.asin; prelude.atan = Num.atan; prelude.atan2 = Num.atan2; prelude.truncate = Num.truncate; prelude.round = Num.round; prelude.ceiling = Num.ceiling; prelude.floor = Num.floor; prelude.isItNaN = Num.isItNaN; prelude.even = Num.even; prelude.odd = Num.odd; prelude.gcd = Num.gcd; prelude.lcm = Num.lcm; prelude.VERSION = '1.1.2'; module.exports = prelude; function curry$(f, bound) { var context, _curry = function _curry(args) { return f.length > 1 ? function () { var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } },{"./Func.js":97,"./List.js":98,"./Num.js":99,"./Obj.js":100,"./Str.js":101}],103:[function(require,module,exports){ 'use strict'; // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout() { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } })(); function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch (e) { try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch (e) { // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e) { try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e) { // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while (len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return []; }; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/'; }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function () { return 0; }; },{}],104:[function(require,module,exports){ /*! @author Toru Nagashima */ 'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } Object.defineProperty(exports, '__esModule', { value: true }); var ast = /*#__PURE__*/Object.freeze({}); function isIdStart(cp) { if (cp < 0x41) return false; if (cp < 0x5b) return true; if (cp < 0x61) return false; if (cp < 0x7b) return true; return isLargeIdStart(cp); } function isIdContinue(cp) { if (cp < 0x30) return false; if (cp < 0x3a) return true; if (cp < 0x41) return false; if (cp < 0x5b) return true; if (cp === 0x5f) return true; if (cp < 0x61) return false; if (cp < 0x7b) return true; return isLargeIdStart(cp) || isLargeIdContinue(cp); } function isLargeIdStart(cp) { if (cp < 0x30a1) { if (cp < 0xec0) { if (cp < 0xa35) { if (cp < 0x6e5) { if (cp < 0x37a) { if (cp < 0x294) { if (cp < 0xf8) { if (cp === 0xaa) return true; if (cp === 0xb5) return true; if (cp === 0xba) return true; if (cp < 0xc0) return false; if (cp < 0xd7) return true; if (cp < 0xd8) return false; if (cp < 0xf7) return true; return false; } if (cp < 0x1bb) return true; if (cp === 0x1bb) return true; if (cp < 0x1bc) return false; if (cp < 0x1c0) return true; if (cp < 0x1c0) return false; if (cp < 0x1c4) return true; if (cp < 0x1c4) return false; if (cp < 0x294) return true; return false; } if (cp < 0x2ec) { if (cp === 0x294) return true; if (cp < 0x295) return false; if (cp < 0x2b0) return true; if (cp < 0x2b0) return false; if (cp < 0x2c2) return true; if (cp < 0x2c6) return false; if (cp < 0x2d2) return true; if (cp < 0x2e0) return false; if (cp < 0x2e5) return true; return false; } if (cp === 0x2ec) return true; if (cp === 0x2ee) return true; if (cp < 0x370) return false; if (cp < 0x374) return true; if (cp === 0x374) return true; if (cp < 0x376) return false; if (cp < 0x378) return true; return false; } if (cp < 0x531) { if (cp < 0x38c) { if (cp === 0x37a) return true; if (cp < 0x37b) return false; if (cp < 0x37e) return true; if (cp === 0x37f) return true; if (cp === 0x386) return true; if (cp < 0x388) return false; if (cp < 0x38b) return true; return false; } if (cp === 0x38c) return true; if (cp < 0x38e) return false; if (cp < 0x3a2) return true; if (cp < 0x3a3) return false; if (cp < 0x3f6) return true; if (cp < 0x3f7) return false; if (cp < 0x482) return true; if (cp < 0x48a) return false; if (cp < 0x530) return true; return false; } if (cp < 0x620) { if (cp < 0x531) return false; if (cp < 0x557) return true; if (cp === 0x559) return true; if (cp < 0x560) return false; if (cp < 0x589) return true; if (cp < 0x5d0) return false; if (cp < 0x5eb) return true; if (cp < 0x5ef) return false; if (cp < 0x5f3) return true; return false; } if (cp < 0x640) return true; if (cp === 0x640) return true; if (cp < 0x641) return false; if (cp < 0x64b) return true; if (cp < 0x66e) return false; if (cp < 0x670) return true; if (cp < 0x671) return false; if (cp < 0x6d4) return true; if (cp === 0x6d5) return true; return false; } if (cp < 0x950) { if (cp < 0x7fa) { if (cp < 0x712) { if (cp < 0x6e5) return false; if (cp < 0x6e7) return true; if (cp < 0x6ee) return false; if (cp < 0x6f0) return true; if (cp < 0x6fa) return false; if (cp < 0x6fd) return true; if (cp === 0x6ff) return true; if (cp === 0x710) return true; return false; } if (cp < 0x730) return true; if (cp < 0x74d) return false; if (cp < 0x7a6) return true; if (cp === 0x7b1) return true; if (cp < 0x7ca) return false; if (cp < 0x7eb) return true; if (cp < 0x7f4) return false; if (cp < 0x7f6) return true; return false; } if (cp < 0x840) { if (cp === 0x7fa) return true; if (cp < 0x800) return false; if (cp < 0x816) return true; if (cp === 0x81a) return true; if (cp === 0x824) return true; if (cp === 0x828) return true; return false; } if (cp < 0x859) return true; if (cp < 0x860) return false; if (cp < 0x86b) return true; if (cp < 0x8a0) return false; if (cp < 0x8b5) return true; if (cp < 0x8b6) return false; if (cp < 0x8be) return true; if (cp < 0x904) return false; if (cp < 0x93a) return true; if (cp === 0x93d) return true; return false; } if (cp < 0x9bd) { if (cp < 0x98f) { if (cp === 0x950) return true; if (cp < 0x958) return false; if (cp < 0x962) return true; if (cp === 0x971) return true; if (cp < 0x972) return false; if (cp < 0x981) return true; if (cp < 0x985) return false; if (cp < 0x98d) return true; return false; } if (cp < 0x991) return true; if (cp < 0x993) return false; if (cp < 0x9a9) return true; if (cp < 0x9aa) return false; if (cp < 0x9b1) return true; if (cp === 0x9b2) return true; if (cp < 0x9b6) return false; if (cp < 0x9ba) return true; return false; } if (cp < 0x9fc) { if (cp === 0x9bd) return true; if (cp === 0x9ce) return true; if (cp < 0x9dc) return false; if (cp < 0x9de) return true; if (cp < 0x9df) return false; if (cp < 0x9e2) return true; if (cp < 0x9f0) return false; if (cp < 0x9f2) return true; return false; } if (cp === 0x9fc) return true; if (cp < 0xa05) return false; if (cp < 0xa0b) return true; if (cp < 0xa0f) return false; if (cp < 0xa11) return true; if (cp < 0xa13) return false; if (cp < 0xa29) return true; if (cp < 0xa2a) return false; if (cp < 0xa31) return true; if (cp < 0xa32) return false; if (cp < 0xa34) return true; return false; } if (cp < 0xc60) { if (cp < 0xb3d) { if (cp < 0xab5) { if (cp < 0xa85) { if (cp < 0xa35) return false; if (cp < 0xa37) return true; if (cp < 0xa38) return false; if (cp < 0xa3a) return true; if (cp < 0xa59) return false; if (cp < 0xa5d) return true; if (cp === 0xa5e) return true; if (cp < 0xa72) return false; if (cp < 0xa75) return true; return false; } if (cp < 0xa8e) return true; if (cp < 0xa8f) return false; if (cp < 0xa92) return true; if (cp < 0xa93) return false; if (cp < 0xaa9) return true; if (cp < 0xaaa) return false; if (cp < 0xab1) return true; if (cp < 0xab2) return false; if (cp < 0xab4) return true; return false; } if (cp < 0xb05) { if (cp < 0xab5) return false; if (cp < 0xaba) return true; if (cp === 0xabd) return true; if (cp === 0xad0) return true; if (cp < 0xae0) return false; if (cp < 0xae2) return true; if (cp === 0xaf9) return true; return false; } if (cp < 0xb0d) return true; if (cp < 0xb0f) return false; if (cp < 0xb11) return true; if (cp < 0xb13) return false; if (cp < 0xb29) return true; if (cp < 0xb2a) return false; if (cp < 0xb31) return true; if (cp < 0xb32) return false; if (cp < 0xb34) return true; if (cp < 0xb35) return false; if (cp < 0xb3a) return true; return false; } if (cp < 0xb9e) { if (cp < 0xb85) { if (cp === 0xb3d) return true; if (cp < 0xb5c) return false; if (cp < 0xb5e) return true; if (cp < 0xb5f) return false; if (cp < 0xb62) return true; if (cp === 0xb71) return true; if (cp === 0xb83) return true; return false; } if (cp < 0xb8b) return true; if (cp < 0xb8e) return false; if (cp < 0xb91) return true; if (cp < 0xb92) return false; if (cp < 0xb96) return true; if (cp < 0xb99) return false; if (cp < 0xb9b) return true; if (cp === 0xb9c) return true; return false; } if (cp < 0xc05) { if (cp < 0xb9e) return false; if (cp < 0xba0) return true; if (cp < 0xba3) return false; if (cp < 0xba5) return true; if (cp < 0xba8) return false; if (cp < 0xbab) return true; if (cp < 0xbae) return false; if (cp < 0xbba) return true; if (cp === 0xbd0) return true; return false; } if (cp < 0xc0d) return true; if (cp < 0xc0e) return false; if (cp < 0xc11) return true; if (cp < 0xc12) return false; if (cp < 0xc29) return true; if (cp < 0xc2a) return false; if (cp < 0xc3a) return true; if (cp === 0xc3d) return true; if (cp < 0xc58) return false; if (cp < 0xc5b) return true; return false; } if (cp < 0xdb3) { if (cp < 0xcf1) { if (cp < 0xcaa) { if (cp < 0xc60) return false; if (cp < 0xc62) return true; if (cp === 0xc80) return true; if (cp < 0xc85) return false; if (cp < 0xc8d) return true; if (cp < 0xc8e) return false; if (cp < 0xc91) return true; if (cp < 0xc92) return false; if (cp < 0xca9) return true; return false; } if (cp < 0xcb4) return true; if (cp < 0xcb5) return false; if (cp < 0xcba) return true; if (cp === 0xcbd) return true; if (cp === 0xcde) return true; if (cp < 0xce0) return false; if (cp < 0xce2) return true; return false; } if (cp < 0xd4e) { if (cp < 0xcf1) return false; if (cp < 0xcf3) return true; if (cp < 0xd05) return false; if (cp < 0xd0d) return true; if (cp < 0xd0e) return false; if (cp < 0xd11) return true; if (cp < 0xd12) return false; if (cp < 0xd3b) return true; if (cp === 0xd3d) return true; return false; } if (cp === 0xd4e) return true; if (cp < 0xd54) return false; if (cp < 0xd57) return true; if (cp < 0xd5f) return false; if (cp < 0xd62) return true; if (cp < 0xd7a) return false; if (cp < 0xd80) return true; if (cp < 0xd85) return false; if (cp < 0xd97) return true; if (cp < 0xd9a) return false; if (cp < 0xdb2) return true; return false; } if (cp < 0xe8a) { if (cp < 0xe40) { if (cp < 0xdb3) return false; if (cp < 0xdbc) return true; if (cp === 0xdbd) return true; if (cp < 0xdc0) return false; if (cp < 0xdc7) return true; if (cp < 0xe01) return false; if (cp < 0xe31) return true; if (cp < 0xe32) return false; if (cp < 0xe34) return true; return false; } if (cp < 0xe46) return true; if (cp === 0xe46) return true; if (cp < 0xe81) return false; if (cp < 0xe83) return true; if (cp === 0xe84) return true; if (cp < 0xe87) return false; if (cp < 0xe89) return true; return false; } if (cp < 0xea5) { if (cp === 0xe8a) return true; if (cp === 0xe8d) return true; if (cp < 0xe94) return false; if (cp < 0xe98) return true; if (cp < 0xe99) return false; if (cp < 0xea0) return true; if (cp < 0xea1) return false; if (cp < 0xea4) return true; return false; } if (cp === 0xea5) return true; if (cp === 0xea7) return true; if (cp < 0xeaa) return false; if (cp < 0xeac) return true; if (cp < 0xead) return false; if (cp < 0xeb1) return true; if (cp < 0xeb2) return false; if (cp < 0xeb4) return true; if (cp === 0xebd) return true; return false; } if (cp < 0x1ce9) { if (cp < 0x166f) { if (cp < 0x10fd) { if (cp < 0x105a) { if (cp < 0xf49) { if (cp < 0xec0) return false; if (cp < 0xec5) return true; if (cp === 0xec6) return true; if (cp < 0xedc) return false; if (cp < 0xee0) return true; if (cp === 0xf00) return true; if (cp < 0xf40) return false; if (cp < 0xf48) return true; return false; } if (cp < 0xf6d) return true; if (cp < 0xf88) return false; if (cp < 0xf8d) return true; if (cp < 0x1000) return false; if (cp < 0x102b) return true; if (cp === 0x103f) return true; if (cp < 0x1050) return false; if (cp < 0x1056) return true; return false; } if (cp < 0x108e) { if (cp < 0x105a) return false; if (cp < 0x105e) return true; if (cp === 0x1061) return true; if (cp < 0x1065) return false; if (cp < 0x1067) return true; if (cp < 0x106e) return false; if (cp < 0x1071) return true; if (cp < 0x1075) return false; if (cp < 0x1082) return true; return false; } if (cp === 0x108e) return true; if (cp < 0x10a0) return false; if (cp < 0x10c6) return true; if (cp === 0x10c7) return true; if (cp === 0x10cd) return true; if (cp < 0x10d0) return false; if (cp < 0x10fb) return true; if (cp === 0x10fc) return true; return false; } if (cp < 0x12b8) { if (cp < 0x125a) { if (cp < 0x10fd) return false; if (cp < 0x1100) return true; if (cp < 0x1100) return false; if (cp < 0x1249) return true; if (cp < 0x124a) return false; if (cp < 0x124e) return true; if (cp < 0x1250) return false; if (cp < 0x1257) return true; if (cp === 0x1258) return true; return false; } if (cp < 0x125e) return true; if (cp < 0x1260) return false; if (cp < 0x1289) return true; if (cp < 0x128a) return false; if (cp < 0x128e) return true; if (cp < 0x1290) return false; if (cp < 0x12b1) return true; if (cp < 0x12b2) return false; if (cp < 0x12b6) return true; return false; } if (cp < 0x1312) { if (cp < 0x12b8) return false; if (cp < 0x12bf) return true; if (cp === 0x12c0) return true; if (cp < 0x12c2) return false; if (cp < 0x12c6) return true; if (cp < 0x12c8) return false; if (cp < 0x12d7) return true; if (cp < 0x12d8) return false; if (cp < 0x1311) return true; return false; } if (cp < 0x1316) return true; if (cp < 0x1318) return false; if (cp < 0x135b) return true; if (cp < 0x1380) return false; if (cp < 0x1390) return true; if (cp < 0x13a0) return false; if (cp < 0x13f6) return true; if (cp < 0x13f8) return false; if (cp < 0x13fe) return true; if (cp < 0x1401) return false; if (cp < 0x166d) return true; return false; } if (cp < 0x18b0) { if (cp < 0x176e) { if (cp < 0x1700) { if (cp < 0x166f) return false; if (cp < 0x1680) return true; if (cp < 0x1681) return false; if (cp < 0x169b) return true; if (cp < 0x16a0) return false; if (cp < 0x16eb) return true; if (cp < 0x16ee) return false; if (cp < 0x16f1) return true; if (cp < 0x16f1) return false; if (cp < 0x16f9) return true; return false; } if (cp < 0x170d) return true; if (cp < 0x170e) return false; if (cp < 0x1712) return true; if (cp < 0x1720) return false; if (cp < 0x1732) return true; if (cp < 0x1740) return false; if (cp < 0x1752) return true; if (cp < 0x1760) return false; if (cp < 0x176d) return true; return false; } if (cp < 0x1843) { if (cp < 0x176e) return false; if (cp < 0x1771) return true; if (cp < 0x1780) return false; if (cp < 0x17b4) return true; if (cp === 0x17d7) return true; if (cp === 0x17dc) return true; if (cp < 0x1820) return false; if (cp < 0x1843) return true; return false; } if (cp === 0x1843) return true; if (cp < 0x1844) return false; if (cp < 0x1879) return true; if (cp < 0x1880) return false; if (cp < 0x1885) return true; if (cp < 0x1885) return false; if (cp < 0x1887) return true; if (cp < 0x1887) return false; if (cp < 0x18a9) return true; if (cp === 0x18aa) return true; return false; } if (cp < 0x1b45) { if (cp < 0x19b0) { if (cp < 0x18b0) return false; if (cp < 0x18f6) return true; if (cp < 0x1900) return false; if (cp < 0x191f) return true; if (cp < 0x1950) return false; if (cp < 0x196e) return true; if (cp < 0x1970) return false; if (cp < 0x1975) return true; if (cp < 0x1980) return false; if (cp < 0x19ac) return true; return false; } if (cp < 0x19ca) return true; if (cp < 0x1a00) return false; if (cp < 0x1a17) return true; if (cp < 0x1a20) return false; if (cp < 0x1a55) return true; if (cp === 0x1aa7) return true; if (cp < 0x1b05) return false; if (cp < 0x1b34) return true; return false; } if (cp < 0x1c4d) { if (cp < 0x1b45) return false; if (cp < 0x1b4c) return true; if (cp < 0x1b83) return false; if (cp < 0x1ba1) return true; if (cp < 0x1bae) return false; if (cp < 0x1bb0) return true; if (cp < 0x1bba) return false; if (cp < 0x1be6) return true; if (cp < 0x1c00) return false; if (cp < 0x1c24) return true; return false; } if (cp < 0x1c50) return true; if (cp < 0x1c5a) return false; if (cp < 0x1c78) return true; if (cp < 0x1c78) return false; if (cp < 0x1c7e) return true; if (cp < 0x1c80) return false; if (cp < 0x1c89) return true; if (cp < 0x1c90) return false; if (cp < 0x1cbb) return true; if (cp < 0x1cbd) return false; if (cp < 0x1cc0) return true; return false; } if (cp < 0x212f) { if (cp < 0x1fc2) { if (cp < 0x1f18) { if (cp < 0x1d6b) { if (cp < 0x1ce9) return false; if (cp < 0x1ced) return true; if (cp < 0x1cee) return false; if (cp < 0x1cf2) return true; if (cp < 0x1cf5) return false; if (cp < 0x1cf7) return true; if (cp < 0x1d00) return false; if (cp < 0x1d2c) return true; if (cp < 0x1d2c) return false; if (cp < 0x1d6b) return true; return false; } if (cp < 0x1d78) return true; if (cp === 0x1d78) return true; if (cp < 0x1d79) return false; if (cp < 0x1d9b) return true; if (cp < 0x1d9b) return false; if (cp < 0x1dc0) return true; if (cp < 0x1e00) return false; if (cp < 0x1f16) return true; return false; } if (cp < 0x1f5b) { if (cp < 0x1f18) return false; if (cp < 0x1f1e) return true; if (cp < 0x1f20) return false; if (cp < 0x1f46) return true; if (cp < 0x1f48) return false; if (cp < 0x1f4e) return true; if (cp < 0x1f50) return false; if (cp < 0x1f58) return true; if (cp === 0x1f59) return true; return false; } if (cp === 0x1f5b) return true; if (cp === 0x1f5d) return true; if (cp < 0x1f5f) return false; if (cp < 0x1f7e) return true; if (cp < 0x1f80) return false; if (cp < 0x1fb5) return true; if (cp < 0x1fb6) return false; if (cp < 0x1fbd) return true; if (cp === 0x1fbe) return true; return false; } if (cp < 0x2102) { if (cp < 0x1ff2) { if (cp < 0x1fc2) return false; if (cp < 0x1fc5) return true; if (cp < 0x1fc6) return false; if (cp < 0x1fcd) return true; if (cp < 0x1fd0) return false; if (cp < 0x1fd4) return true; if (cp < 0x1fd6) return false; if (cp < 0x1fdc) return true; if (cp < 0x1fe0) return false; if (cp < 0x1fed) return true; return false; } if (cp < 0x1ff5) return true; if (cp < 0x1ff6) return false; if (cp < 0x1ffd) return true; if (cp === 0x2071) return true; if (cp === 0x207f) return true; if (cp < 0x2090) return false; if (cp < 0x209d) return true; return false; } if (cp < 0x2119) { if (cp === 0x2102) return true; if (cp === 0x2107) return true; if (cp < 0x210a) return false; if (cp < 0x2114) return true; if (cp === 0x2115) return true; if (cp === 0x2118) return true; return false; } if (cp < 0x211e) return true; if (cp === 0x2124) return true; if (cp === 0x2126) return true; if (cp === 0x2128) return true; if (cp < 0x212a) return false; if (cp < 0x212e) return true; if (cp === 0x212e) return true; return false; } if (cp < 0x2d80) { if (cp < 0x2c30) { if (cp < 0x214e) { if (cp < 0x212f) return false; if (cp < 0x2135) return true; if (cp < 0x2135) return false; if (cp < 0x2139) return true; if (cp === 0x2139) return true; if (cp < 0x213c) return false; if (cp < 0x2140) return true; if (cp < 0x2145) return false; if (cp < 0x214a) return true; return false; } if (cp === 0x214e) return true; if (cp < 0x2160) return false; if (cp < 0x2183) return true; if (cp < 0x2183) return false; if (cp < 0x2185) return true; if (cp < 0x2185) return false; if (cp < 0x2189) return true; if (cp < 0x2c00) return false; if (cp < 0x2c2f) return true; return false; } if (cp < 0x2cf2) { if (cp < 0x2c30) return false; if (cp < 0x2c5f) return true; if (cp < 0x2c60) return false; if (cp < 0x2c7c) return true; if (cp < 0x2c7c) return false; if (cp < 0x2c7e) return true; if (cp < 0x2c7e) return false; if (cp < 0x2ce5) return true; if (cp < 0x2ceb) return false; if (cp < 0x2cef) return true; return false; } if (cp < 0x2cf4) return true; if (cp < 0x2d00) return false; if (cp < 0x2d26) return true; if (cp === 0x2d27) return true; if (cp === 0x2d2d) return true; if (cp < 0x2d30) return false; if (cp < 0x2d68) return true; if (cp === 0x2d6f) return true; return false; } if (cp < 0x3006) { if (cp < 0x2dc0) { if (cp < 0x2d80) return false; if (cp < 0x2d97) return true; if (cp < 0x2da0) return false; if (cp < 0x2da7) return true; if (cp < 0x2da8) return false; if (cp < 0x2daf) return true; if (cp < 0x2db0) return false; if (cp < 0x2db7) return true; if (cp < 0x2db8) return false; if (cp < 0x2dbf) return true; return false; } if (cp < 0x2dc7) return true; if (cp < 0x2dc8) return false; if (cp < 0x2dcf) return true; if (cp < 0x2dd0) return false; if (cp < 0x2dd7) return true; if (cp < 0x2dd8) return false; if (cp < 0x2ddf) return true; if (cp === 0x3005) return true; return false; } if (cp < 0x303b) { if (cp === 0x3006) return true; if (cp === 0x3007) return true; if (cp < 0x3021) return false; if (cp < 0x302a) return true; if (cp < 0x3031) return false; if (cp < 0x3036) return true; if (cp < 0x3038) return false; if (cp < 0x303b) return true; return false; } if (cp === 0x303b) return true; if (cp === 0x303c) return true; if (cp < 0x3041) return false; if (cp < 0x3097) return true; if (cp < 0x309b) return false; if (cp < 0x309d) return true; if (cp < 0x309d) return false; if (cp < 0x309f) return true; if (cp === 0x309f) return true; return false; } if (cp < 0x10b60) { if (cp < 0xd7b0) { if (cp < 0xa882) { if (cp < 0xa67f) { if (cp < 0xa015) { if (cp < 0x31a0) { if (cp < 0x30a1) return false; if (cp < 0x30fb) return true; if (cp < 0x30fc) return false; if (cp < 0x30ff) return true; if (cp === 0x30ff) return true; if (cp < 0x3105) return false; if (cp < 0x3130) return true; if (cp < 0x3131) return false; if (cp < 0x318f) return true; return false; } if (cp < 0x31bb) return true; if (cp < 0x31f0) return false; if (cp < 0x3200) return true; if (cp < 0x3400) return false; if (cp < 0x4db6) return true; if (cp < 0x4e00) return false; if (cp < 0x9ff0) return true; if (cp < 0xa000) return false; if (cp < 0xa015) return true; return false; } if (cp < 0xa60c) { if (cp === 0xa015) return true; if (cp < 0xa016) return false; if (cp < 0xa48d) return true; if (cp < 0xa4d0) return false; if (cp < 0xa4f8) return true; if (cp < 0xa4f8) return false; if (cp < 0xa4fe) return true; if (cp < 0xa500) return false; if (cp < 0xa60c) return true; return false; } if (cp === 0xa60c) return true; if (cp < 0xa610) return false; if (cp < 0xa620) return true; if (cp < 0xa62a) return false; if (cp < 0xa62c) return true; if (cp < 0xa640) return false; if (cp < 0xa66e) return true; if (cp === 0xa66e) return true; return false; } if (cp < 0xa78b) { if (cp < 0xa717) { if (cp === 0xa67f) return true; if (cp < 0xa680) return false; if (cp < 0xa69c) return true; if (cp < 0xa69c) return false; if (cp < 0xa69e) return true; if (cp < 0xa6a0) return false; if (cp < 0xa6e6) return true; if (cp < 0xa6e6) return false; if (cp < 0xa6f0) return true; return false; } if (cp < 0xa720) return true; if (cp < 0xa722) return false; if (cp < 0xa770) return true; if (cp === 0xa770) return true; if (cp < 0xa771) return false; if (cp < 0xa788) return true; if (cp === 0xa788) return true; return false; } if (cp < 0xa7fa) { if (cp < 0xa78b) return false; if (cp < 0xa78f) return true; if (cp === 0xa78f) return true; if (cp < 0xa790) return false; if (cp < 0xa7ba) return true; if (cp === 0xa7f7) return true; if (cp < 0xa7f8) return false; if (cp < 0xa7fa) return true; return false; } if (cp === 0xa7fa) return true; if (cp < 0xa7fb) return false; if (cp < 0xa802) return true; if (cp < 0xa803) return false; if (cp < 0xa806) return true; if (cp < 0xa807) return false; if (cp < 0xa80b) return true; if (cp < 0xa80c) return false; if (cp < 0xa823) return true; if (cp < 0xa840) return false; if (cp < 0xa874) return true; return false; } if (cp < 0xaab1) { if (cp < 0xa9e6) { if (cp < 0xa930) { if (cp < 0xa882) return false; if (cp < 0xa8b4) return true; if (cp < 0xa8f2) return false; if (cp < 0xa8f8) return true; if (cp === 0xa8fb) return true; if (cp < 0xa8fd) return false; if (cp < 0xa8ff) return true; if (cp < 0xa90a) return false; if (cp < 0xa926) return true; return false; } if (cp < 0xa947) return true; if (cp < 0xa960) return false; if (cp < 0xa97d) return true; if (cp < 0xa984) return false; if (cp < 0xa9b3) return true; if (cp === 0xa9cf) return true; if (cp < 0xa9e0) return false; if (cp < 0xa9e5) return true; return false; } if (cp < 0xaa44) { if (cp === 0xa9e6) return true; if (cp < 0xa9e7) return false; if (cp < 0xa9f0) return true; if (cp < 0xa9fa) return false; if (cp < 0xa9ff) return true; if (cp < 0xaa00) return false; if (cp < 0xaa29) return true; if (cp < 0xaa40) return false; if (cp < 0xaa43) return true; return false; } if (cp < 0xaa4c) return true; if (cp < 0xaa60) return false; if (cp < 0xaa70) return true; if (cp === 0xaa70) return true; if (cp < 0xaa71) return false; if (cp < 0xaa77) return true; if (cp === 0xaa7a) return true; if (cp < 0xaa7e) return false; if (cp < 0xaab0) return true; return false; } if (cp < 0xab01) { if (cp < 0xaadb) { if (cp === 0xaab1) return true; if (cp < 0xaab5) return false; if (cp < 0xaab7) return true; if (cp < 0xaab9) return false; if (cp < 0xaabe) return true; if (cp === 0xaac0) return true; if (cp === 0xaac2) return true; return false; } if (cp < 0xaadd) return true; if (cp === 0xaadd) return true; if (cp < 0xaae0) return false; if (cp < 0xaaeb) return true; if (cp === 0xaaf2) return true; if (cp < 0xaaf3) return false; if (cp < 0xaaf5) return true; return false; } if (cp < 0xab30) { if (cp < 0xab01) return false; if (cp < 0xab07) return true; if (cp < 0xab09) return false; if (cp < 0xab0f) return true; if (cp < 0xab11) return false; if (cp < 0xab17) return true; if (cp < 0xab20) return false; if (cp < 0xab27) return true; if (cp < 0xab28) return false; if (cp < 0xab2f) return true; return false; } if (cp < 0xab5b) return true; if (cp < 0xab5c) return false; if (cp < 0xab60) return true; if (cp < 0xab60) return false; if (cp < 0xab66) return true; if (cp < 0xab70) return false; if (cp < 0xabc0) return true; if (cp < 0xabc0) return false; if (cp < 0xabe3) return true; if (cp < 0xac00) return false; if (cp < 0xd7a4) return true; return false; } if (cp < 0x1032d) { if (cp < 0xff41) { if (cp < 0xfb3e) { if (cp < 0xfb13) { if (cp < 0xd7b0) return false; if (cp < 0xd7c7) return true; if (cp < 0xd7cb) return false; if (cp < 0xd7fc) return true; if (cp < 0xf900) return false; if (cp < 0xfa6e) return true; if (cp < 0xfa70) return false; if (cp < 0xfada) return true; if (cp < 0xfb00) return false; if (cp < 0xfb07) return true; return false; } if (cp < 0xfb18) return true; if (cp === 0xfb1d) return true; if (cp < 0xfb1f) return false; if (cp < 0xfb29) return true; if (cp < 0xfb2a) return false; if (cp < 0xfb37) return true; if (cp < 0xfb38) return false; if (cp < 0xfb3d) return true; return false; } if (cp < 0xfd50) { if (cp === 0xfb3e) return true; if (cp < 0xfb40) return false; if (cp < 0xfb42) return true; if (cp < 0xfb43) return false; if (cp < 0xfb45) return true; if (cp < 0xfb46) return false; if (cp < 0xfbb2) return true; if (cp < 0xfbd3) return false; if (cp < 0xfd3e) return true; return false; } if (cp < 0xfd90) return true; if (cp < 0xfd92) return false; if (cp < 0xfdc8) return true; if (cp < 0xfdf0) return false; if (cp < 0xfdfc) return true; if (cp < 0xfe70) return false; if (cp < 0xfe75) return true; if (cp < 0xfe76) return false; if (cp < 0xfefd) return true; if (cp < 0xff21) return false; if (cp < 0xff3b) return true; return false; } if (cp < 0x10000) { if (cp < 0xffa0) { if (cp < 0xff41) return false; if (cp < 0xff5b) return true; if (cp < 0xff66) return false; if (cp < 0xff70) return true; if (cp === 0xff70) return true; if (cp < 0xff71) return false; if (cp < 0xff9e) return true; if (cp < 0xff9e) return false; if (cp < 0xffa0) return true; return false; } if (cp < 0xffbf) return true; if (cp < 0xffc2) return false; if (cp < 0xffc8) return true; if (cp < 0xffca) return false; if (cp < 0xffd0) return true; if (cp < 0xffd2) return false; if (cp < 0xffd8) return true; if (cp < 0xffda) return false; if (cp < 0xffdd) return true; return false; } if (cp < 0x10050) { if (cp < 0x10000) return false; if (cp < 0x1000c) return true; if (cp < 0x1000d) return false; if (cp < 0x10027) return true; if (cp < 0x10028) return false; if (cp < 0x1003b) return true; if (cp < 0x1003c) return false; if (cp < 0x1003e) return true; if (cp < 0x1003f) return false; if (cp < 0x1004e) return true; return false; } if (cp < 0x1005e) return true; if (cp < 0x10080) return false; if (cp < 0x100fb) return true; if (cp < 0x10140) return false; if (cp < 0x10175) return true; if (cp < 0x10280) return false; if (cp < 0x1029d) return true; if (cp < 0x102a0) return false; if (cp < 0x102d1) return true; if (cp < 0x10300) return false; if (cp < 0x10320) return true; return false; } if (cp < 0x10837) { if (cp < 0x10450) { if (cp < 0x10380) { if (cp < 0x1032d) return false; if (cp < 0x10341) return true; if (cp === 0x10341) return true; if (cp < 0x10342) return false; if (cp < 0x1034a) return true; if (cp === 0x1034a) return true; if (cp < 0x10350) return false; if (cp < 0x10376) return true; return false; } if (cp < 0x1039e) return true; if (cp < 0x103a0) return false; if (cp < 0x103c4) return true; if (cp < 0x103c8) return false; if (cp < 0x103d0) return true; if (cp < 0x103d1) return false; if (cp < 0x103d6) return true; if (cp < 0x10400) return false; if (cp < 0x10450) return true; return false; } if (cp < 0x10600) { if (cp < 0x10450) return false; if (cp < 0x1049e) return true; if (cp < 0x104b0) return false; if (cp < 0x104d4) return true; if (cp < 0x104d8) return false; if (cp < 0x104fc) return true; if (cp < 0x10500) return false; if (cp < 0x10528) return true; if (cp < 0x10530) return false; if (cp < 0x10564) return true; return false; } if (cp < 0x10737) return true; if (cp < 0x10740) return false; if (cp < 0x10756) return true; if (cp < 0x10760) return false; if (cp < 0x10768) return true; if (cp < 0x10800) return false; if (cp < 0x10806) return true; if (cp === 0x10808) return true; if (cp < 0x1080a) return false; if (cp < 0x10836) return true; return false; } if (cp < 0x109be) { if (cp < 0x108e0) { if (cp < 0x10837) return false; if (cp < 0x10839) return true; if (cp === 0x1083c) return true; if (cp < 0x1083f) return false; if (cp < 0x10856) return true; if (cp < 0x10860) return false; if (cp < 0x10877) return true; if (cp < 0x10880) return false; if (cp < 0x1089f) return true; return false; } if (cp < 0x108f3) return true; if (cp < 0x108f4) return false; if (cp < 0x108f6) return true; if (cp < 0x10900) return false; if (cp < 0x10916) return true; if (cp < 0x10920) return false; if (cp < 0x1093a) return true; if (cp < 0x10980) return false; if (cp < 0x109b8) return true; return false; } if (cp < 0x10a60) { if (cp < 0x109be) return false; if (cp < 0x109c0) return true; if (cp === 0x10a00) return true; if (cp < 0x10a10) return false; if (cp < 0x10a14) return true; if (cp < 0x10a15) return false; if (cp < 0x10a18) return true; if (cp < 0x10a19) return false; if (cp < 0x10a36) return true; return false; } if (cp < 0x10a7d) return true; if (cp < 0x10a80) return false; if (cp < 0x10a9d) return true; if (cp < 0x10ac0) return false; if (cp < 0x10ac8) return true; if (cp < 0x10ac9) return false; if (cp < 0x10ae5) return true; if (cp < 0x10b00) return false; if (cp < 0x10b36) return true; if (cp < 0x10b40) return false; if (cp < 0x10b56) return true; return false; } if (cp < 0x16e40) { if (cp < 0x11580) { if (cp < 0x11213) { if (cp < 0x11083) { if (cp < 0x10d00) { if (cp < 0x10b60) return false; if (cp < 0x10b73) return true; if (cp < 0x10b80) return false; if (cp < 0x10b92) return true; if (cp < 0x10c00) return false; if (cp < 0x10c49) return true; if (cp < 0x10c80) return false; if (cp < 0x10cb3) return true; if (cp < 0x10cc0) return false; if (cp < 0x10cf3) return true; return false; } if (cp < 0x10d24) return true; if (cp < 0x10f00) return false; if (cp < 0x10f1d) return true; if (cp === 0x10f27) return true; if (cp < 0x10f30) return false; if (cp < 0x10f46) return true; if (cp < 0x11003) return false; if (cp < 0x11038) return true; return false; } if (cp < 0x11176) { if (cp < 0x11083) return false; if (cp < 0x110b0) return true; if (cp < 0x110d0) return false; if (cp < 0x110e9) return true; if (cp < 0x11103) return false; if (cp < 0x11127) return true; if (cp === 0x11144) return true; if (cp < 0x11150) return false; if (cp < 0x11173) return true; return false; } if (cp === 0x11176) return true; if (cp < 0x11183) return false; if (cp < 0x111b3) return true; if (cp < 0x111c1) return false; if (cp < 0x111c5) return true; if (cp === 0x111da) return true; if (cp === 0x111dc) return true; if (cp < 0x11200) return false; if (cp < 0x11212) return true; return false; } if (cp < 0x1132a) { if (cp < 0x1129f) { if (cp < 0x11213) return false; if (cp < 0x1122c) return true; if (cp < 0x11280) return false; if (cp < 0x11287) return true; if (cp === 0x11288) return true; if (cp < 0x1128a) return false; if (cp < 0x1128e) return true; if (cp < 0x1128f) return false; if (cp < 0x1129e) return true; return false; } if (cp < 0x112a9) return true; if (cp < 0x112b0) return false; if (cp < 0x112df) return true; if (cp < 0x11305) return false; if (cp < 0x1130d) return true; if (cp < 0x1130f) return false; if (cp < 0x11311) return true; if (cp < 0x11313) return false; if (cp < 0x11329) return true; return false; } if (cp < 0x1135d) { if (cp < 0x1132a) return false; if (cp < 0x11331) return true; if (cp < 0x11332) return false; if (cp < 0x11334) return true; if (cp < 0x11335) return false; if (cp < 0x1133a) return true; if (cp === 0x1133d) return true; if (cp === 0x11350) return true; return false; } if (cp < 0x11362) return true; if (cp < 0x11400) return false; if (cp < 0x11435) return true; if (cp < 0x11447) return false; if (cp < 0x1144b) return true; if (cp < 0x11480) return false; if (cp < 0x114b0) return true; if (cp < 0x114c4) return false; if (cp < 0x114c6) return true; if (cp === 0x114c7) return true; return false; } if (cp < 0x11d00) { if (cp < 0x11a0b) { if (cp < 0x11700) { if (cp < 0x11580) return false; if (cp < 0x115af) return true; if (cp < 0x115d8) return false; if (cp < 0x115dc) return true; if (cp < 0x11600) return false; if (cp < 0x11630) return true; if (cp === 0x11644) return true; if (cp < 0x11680) return false; if (cp < 0x116ab) return true; return false; } if (cp < 0x1171b) return true; if (cp < 0x11800) return false; if (cp < 0x1182c) return true; if (cp < 0x118a0) return false; if (cp < 0x118e0) return true; if (cp === 0x118ff) return true; if (cp === 0x11a00) return true; return false; } if (cp < 0x11a9d) { if (cp < 0x11a0b) return false; if (cp < 0x11a33) return true; if (cp === 0x11a3a) return true; if (cp === 0x11a50) return true; if (cp < 0x11a5c) return false; if (cp < 0x11a84) return true; if (cp < 0x11a86) return false; if (cp < 0x11a8a) return true; return false; } if (cp === 0x11a9d) return true; if (cp < 0x11ac0) return false; if (cp < 0x11af9) return true; if (cp < 0x11c00) return false; if (cp < 0x11c09) return true; if (cp < 0x11c0a) return false; if (cp < 0x11c2f) return true; if (cp === 0x11c40) return true; if (cp < 0x11c72) return false; if (cp < 0x11c90) return true; return false; } if (cp < 0x12400) { if (cp < 0x11d67) { if (cp < 0x11d00) return false; if (cp < 0x11d07) return true; if (cp < 0x11d08) return false; if (cp < 0x11d0a) return true; if (cp < 0x11d0b) return false; if (cp < 0x11d31) return true; if (cp === 0x11d46) return true; if (cp < 0x11d60) return false; if (cp < 0x11d66) return true; return false; } if (cp < 0x11d69) return true; if (cp < 0x11d6a) return false; if (cp < 0x11d8a) return true; if (cp === 0x11d98) return true; if (cp < 0x11ee0) return false; if (cp < 0x11ef3) return true; if (cp < 0x12000) return false; if (cp < 0x1239a) return true; return false; } if (cp < 0x16a40) { if (cp < 0x12400) return false; if (cp < 0x1246f) return true; if (cp < 0x12480) return false; if (cp < 0x12544) return true; if (cp < 0x13000) return false; if (cp < 0x1342f) return true; if (cp < 0x14400) return false; if (cp < 0x14647) return true; if (cp < 0x16800) return false; if (cp < 0x16a39) return true; return false; } if (cp < 0x16a5f) return true; if (cp < 0x16ad0) return false; if (cp < 0x16aee) return true; if (cp < 0x16b00) return false; if (cp < 0x16b30) return true; if (cp < 0x16b40) return false; if (cp < 0x16b44) return true; if (cp < 0x16b63) return false; if (cp < 0x16b78) return true; if (cp < 0x16b7d) return false; if (cp < 0x16b90) return true; return false; } if (cp < 0x1d7c4) { if (cp < 0x1d4bd) { if (cp < 0x1bc70) { if (cp < 0x17000) { if (cp < 0x16e40) return false; if (cp < 0x16e80) return true; if (cp < 0x16f00) return false; if (cp < 0x16f45) return true; if (cp === 0x16f50) return true; if (cp < 0x16f93) return false; if (cp < 0x16fa0) return true; if (cp < 0x16fe0) return false; if (cp < 0x16fe2) return true; return false; } if (cp < 0x187f2) return true; if (cp < 0x18800) return false; if (cp < 0x18af3) return true; if (cp < 0x1b000) return false; if (cp < 0x1b11f) return true; if (cp < 0x1b170) return false; if (cp < 0x1b2fc) return true; if (cp < 0x1bc00) return false; if (cp < 0x1bc6b) return true; return false; } if (cp < 0x1d49e) { if (cp < 0x1bc70) return false; if (cp < 0x1bc7d) return true; if (cp < 0x1bc80) return false; if (cp < 0x1bc89) return true; if (cp < 0x1bc90) return false; if (cp < 0x1bc9a) return true; if (cp < 0x1d400) return false; if (cp < 0x1d455) return true; if (cp < 0x1d456) return false; if (cp < 0x1d49d) return true; return false; } if (cp < 0x1d4a0) return true; if (cp === 0x1d4a2) return true; if (cp < 0x1d4a5) return false; if (cp < 0x1d4a7) return true; if (cp < 0x1d4a9) return false; if (cp < 0x1d4ad) return true; if (cp < 0x1d4ae) return false; if (cp < 0x1d4ba) return true; if (cp === 0x1d4bb) return true; return false; } if (cp < 0x1d552) { if (cp < 0x1d51e) { if (cp < 0x1d4bd) return false; if (cp < 0x1d4c4) return true; if (cp < 0x1d4c5) return false; if (cp < 0x1d506) return true; if (cp < 0x1d507) return false; if (cp < 0x1d50b) return true; if (cp < 0x1d50d) return false; if (cp < 0x1d515) return true; if (cp < 0x1d516) return false; if (cp < 0x1d51d) return true; return false; } if (cp < 0x1d53a) return true; if (cp < 0x1d53b) return false; if (cp < 0x1d53f) return true; if (cp < 0x1d540) return false; if (cp < 0x1d545) return true; if (cp === 0x1d546) return true; if (cp < 0x1d54a) return false; if (cp < 0x1d551) return true; return false; } if (cp < 0x1d716) { if (cp < 0x1d552) return false; if (cp < 0x1d6a6) return true; if (cp < 0x1d6a8) return false; if (cp < 0x1d6c1) return true; if (cp < 0x1d6c2) return false; if (cp < 0x1d6db) return true; if (cp < 0x1d6dc) return false; if (cp < 0x1d6fb) return true; if (cp < 0x1d6fc) return false; if (cp < 0x1d715) return true; return false; } if (cp < 0x1d735) return true; if (cp < 0x1d736) return false; if (cp < 0x1d74f) return true; if (cp < 0x1d750) return false; if (cp < 0x1d76f) return true; if (cp < 0x1d770) return false; if (cp < 0x1d789) return true; if (cp < 0x1d78a) return false; if (cp < 0x1d7a9) return true; if (cp < 0x1d7aa) return false; if (cp < 0x1d7c3) return true; return false; } if (cp < 0x1ee5b) { if (cp < 0x1ee39) { if (cp < 0x1ee21) { if (cp < 0x1d7c4) return false; if (cp < 0x1d7cc) return true; if (cp < 0x1e800) return false; if (cp < 0x1e8c5) return true; if (cp < 0x1e900) return false; if (cp < 0x1e944) return true; if (cp < 0x1ee00) return false; if (cp < 0x1ee04) return true; if (cp < 0x1ee05) return false; if (cp < 0x1ee20) return true; return false; } if (cp < 0x1ee23) return true; if (cp === 0x1ee24) return true; if (cp === 0x1ee27) return true; if (cp < 0x1ee29) return false; if (cp < 0x1ee33) return true; if (cp < 0x1ee34) return false; if (cp < 0x1ee38) return true; return false; } if (cp < 0x1ee4b) { if (cp === 0x1ee39) return true; if (cp === 0x1ee3b) return true; if (cp === 0x1ee42) return true; if (cp === 0x1ee47) return true; if (cp === 0x1ee49) return true; return false; } if (cp === 0x1ee4b) return true; if (cp < 0x1ee4d) return false; if (cp < 0x1ee50) return true; if (cp < 0x1ee51) return false; if (cp < 0x1ee53) return true; if (cp === 0x1ee54) return true; if (cp === 0x1ee57) return true; if (cp === 0x1ee59) return true; return false; } if (cp < 0x1ee80) { if (cp < 0x1ee67) { if (cp === 0x1ee5b) return true; if (cp === 0x1ee5d) return true; if (cp === 0x1ee5f) return true; if (cp < 0x1ee61) return false; if (cp < 0x1ee63) return true; if (cp === 0x1ee64) return true; return false; } if (cp < 0x1ee6b) return true; if (cp < 0x1ee6c) return false; if (cp < 0x1ee73) return true; if (cp < 0x1ee74) return false; if (cp < 0x1ee78) return true; if (cp < 0x1ee79) return false; if (cp < 0x1ee7d) return true; if (cp === 0x1ee7e) return true; return false; } if (cp < 0x20000) { if (cp < 0x1ee80) return false; if (cp < 0x1ee8a) return true; if (cp < 0x1ee8b) return false; if (cp < 0x1ee9c) return true; if (cp < 0x1eea1) return false; if (cp < 0x1eea4) return true; if (cp < 0x1eea5) return false; if (cp < 0x1eeaa) return true; if (cp < 0x1eeab) return false; if (cp < 0x1eebc) return true; return false; } if (cp < 0x2a6d7) return true; if (cp < 0x2a700) return false; if (cp < 0x2b735) return true; if (cp < 0x2b740) return false; if (cp < 0x2b81e) return true; if (cp < 0x2b820) return false; if (cp < 0x2cea2) return true; if (cp < 0x2ceb0) return false; if (cp < 0x2ebe1) return true; if (cp < 0x2f800) return false; if (cp < 0x2fa1e) return true; return false; } function isLargeIdContinue(cp) { if (cp < 0x1cd0) { if (cp < 0xd82) { if (cp < 0xa83) { if (cp < 0x93b) { if (cp < 0x6ea) { if (cp < 0x5c7) { if (cp === 0xb7) return true; if (cp < 0x300) return false; if (cp < 0x370) return true; if (cp === 0x387) return true; if (cp < 0x483) return false; if (cp < 0x488) return true; if (cp < 0x591) return false; if (cp < 0x5be) return true; if (cp === 0x5bf) return true; if (cp < 0x5c1) return false; if (cp < 0x5c3) return true; if (cp < 0x5c4) return false; if (cp < 0x5c6) return true; return false; } if (cp === 0x5c7) return true; if (cp < 0x610) return false; if (cp < 0x61b) return true; if (cp < 0x64b) return false; if (cp < 0x660) return true; if (cp < 0x660) return false; if (cp < 0x66a) return true; if (cp === 0x670) return true; if (cp < 0x6d6) return false; if (cp < 0x6dd) return true; if (cp < 0x6df) return false; if (cp < 0x6e5) return true; if (cp < 0x6e7) return false; if (cp < 0x6e9) return true; return false; } if (cp < 0x816) { if (cp < 0x6ea) return false; if (cp < 0x6ee) return true; if (cp < 0x6f0) return false; if (cp < 0x6fa) return true; if (cp === 0x711) return true; if (cp < 0x730) return false; if (cp < 0x74b) return true; if (cp < 0x7a6) return false; if (cp < 0x7b1) return true; if (cp < 0x7c0) return false; if (cp < 0x7ca) return true; if (cp < 0x7eb) return false; if (cp < 0x7f4) return true; if (cp === 0x7fd) return true; return false; } if (cp < 0x81a) return true; if (cp < 0x81b) return false; if (cp < 0x824) return true; if (cp < 0x825) return false; if (cp < 0x828) return true; if (cp < 0x829) return false; if (cp < 0x82e) return true; if (cp < 0x859) return false; if (cp < 0x85c) return true; if (cp < 0x8d3) return false; if (cp < 0x8e2) return true; if (cp < 0x8e3) return false; if (cp < 0x903) return true; if (cp === 0x903) return true; if (cp === 0x93a) return true; return false; } if (cp < 0x9cd) { if (cp < 0x962) { if (cp === 0x93b) return true; if (cp === 0x93c) return true; if (cp < 0x93e) return false; if (cp < 0x941) return true; if (cp < 0x941) return false; if (cp < 0x949) return true; if (cp < 0x949) return false; if (cp < 0x94d) return true; if (cp === 0x94d) return true; if (cp < 0x94e) return false; if (cp < 0x950) return true; if (cp < 0x951) return false; if (cp < 0x958) return true; return false; } if (cp < 0x964) return true; if (cp < 0x966) return false; if (cp < 0x970) return true; if (cp === 0x981) return true; if (cp < 0x982) return false; if (cp < 0x984) return true; if (cp === 0x9bc) return true; if (cp < 0x9be) return false; if (cp < 0x9c1) return true; if (cp < 0x9c1) return false; if (cp < 0x9c5) return true; if (cp < 0x9c7) return false; if (cp < 0x9c9) return true; if (cp < 0x9cb) return false; if (cp < 0x9cd) return true; return false; } if (cp < 0xa3e) { if (cp === 0x9cd) return true; if (cp === 0x9d7) return true; if (cp < 0x9e2) return false; if (cp < 0x9e4) return true; if (cp < 0x9e6) return false; if (cp < 0x9f0) return true; if (cp === 0x9fe) return true; if (cp < 0xa01) return false; if (cp < 0xa03) return true; if (cp === 0xa03) return true; if (cp === 0xa3c) return true; return false; } if (cp < 0xa41) return true; if (cp < 0xa41) return false; if (cp < 0xa43) return true; if (cp < 0xa47) return false; if (cp < 0xa49) return true; if (cp < 0xa4b) return false; if (cp < 0xa4e) return true; if (cp === 0xa51) return true; if (cp < 0xa66) return false; if (cp < 0xa70) return true; if (cp < 0xa70) return false; if (cp < 0xa72) return true; if (cp === 0xa75) return true; if (cp < 0xa81) return false; if (cp < 0xa83) return true; return false; } if (cp < 0xc00) { if (cp < 0xb41) { if (cp < 0xae2) { if (cp === 0xa83) return true; if (cp === 0xabc) return true; if (cp < 0xabe) return false; if (cp < 0xac1) return true; if (cp < 0xac1) return false; if (cp < 0xac6) return true; if (cp < 0xac7) return false; if (cp < 0xac9) return true; if (cp === 0xac9) return true; if (cp < 0xacb) return false; if (cp < 0xacd) return true; if (cp === 0xacd) return true; return false; } if (cp < 0xae4) return true; if (cp < 0xae6) return false; if (cp < 0xaf0) return true; if (cp < 0xafa) return false; if (cp < 0xb00) return true; if (cp === 0xb01) return true; if (cp < 0xb02) return false; if (cp < 0xb04) return true; if (cp === 0xb3c) return true; if (cp === 0xb3e) return true; if (cp === 0xb3f) return true; if (cp === 0xb40) return true; return false; } if (cp < 0xb82) { if (cp < 0xb41) return false; if (cp < 0xb45) return true; if (cp < 0xb47) return false; if (cp < 0xb49) return true; if (cp < 0xb4b) return false; if (cp < 0xb4d) return true; if (cp === 0xb4d) return true; if (cp === 0xb56) return true; if (cp === 0xb57) return true; if (cp < 0xb62) return false; if (cp < 0xb64) return true; if (cp < 0xb66) return false; if (cp < 0xb70) return true; return false; } if (cp === 0xb82) return true; if (cp < 0xbbe) return false; if (cp < 0xbc0) return true; if (cp === 0xbc0) return true; if (cp < 0xbc1) return false; if (cp < 0xbc3) return true; if (cp < 0xbc6) return false; if (cp < 0xbc9) return true; if (cp < 0xbca) return false; if (cp < 0xbcd) return true; if (cp === 0xbcd) return true; if (cp === 0xbd7) return true; if (cp < 0xbe6) return false; if (cp < 0xbf0) return true; return false; } if (cp < 0xcc7) { if (cp < 0xc62) { if (cp === 0xc00) return true; if (cp < 0xc01) return false; if (cp < 0xc04) return true; if (cp === 0xc04) return true; if (cp < 0xc3e) return false; if (cp < 0xc41) return true; if (cp < 0xc41) return false; if (cp < 0xc45) return true; if (cp < 0xc46) return false; if (cp < 0xc49) return true; if (cp < 0xc4a) return false; if (cp < 0xc4e) return true; if (cp < 0xc55) return false; if (cp < 0xc57) return true; return false; } if (cp < 0xc64) return true; if (cp < 0xc66) return false; if (cp < 0xc70) return true; if (cp === 0xc81) return true; if (cp < 0xc82) return false; if (cp < 0xc84) return true; if (cp === 0xcbc) return true; if (cp === 0xcbe) return true; if (cp === 0xcbf) return true; if (cp < 0xcc0) return false; if (cp < 0xcc5) return true; if (cp === 0xcc6) return true; return false; } if (cp < 0xd3b) { if (cp < 0xcc7) return false; if (cp < 0xcc9) return true; if (cp < 0xcca) return false; if (cp < 0xccc) return true; if (cp < 0xccc) return false; if (cp < 0xcce) return true; if (cp < 0xcd5) return false; if (cp < 0xcd7) return true; if (cp < 0xce2) return false; if (cp < 0xce4) return true; if (cp < 0xce6) return false; if (cp < 0xcf0) return true; if (cp < 0xd00) return false; if (cp < 0xd02) return true; if (cp < 0xd02) return false; if (cp < 0xd04) return true; return false; } if (cp < 0xd3d) return true; if (cp < 0xd3e) return false; if (cp < 0xd41) return true; if (cp < 0xd41) return false; if (cp < 0xd45) return true; if (cp < 0xd46) return false; if (cp < 0xd49) return true; if (cp < 0xd4a) return false; if (cp < 0xd4d) return true; if (cp === 0xd4d) return true; if (cp === 0xd57) return true; if (cp < 0xd62) return false; if (cp < 0xd64) return true; if (cp < 0xd66) return false; if (cp < 0xd70) return true; return false; } if (cp < 0x17e0) { if (cp < 0x1038) { if (cp < 0xf18) { if (cp < 0xe31) { if (cp < 0xd82) return false; if (cp < 0xd84) return true; if (cp === 0xdca) return true; if (cp < 0xdcf) return false; if (cp < 0xdd2) return true; if (cp < 0xdd2) return false; if (cp < 0xdd5) return true; if (cp === 0xdd6) return true; if (cp < 0xdd8) return false; if (cp < 0xde0) return true; if (cp < 0xde6) return false; if (cp < 0xdf0) return true; if (cp < 0xdf2) return false; if (cp < 0xdf4) return true; return false; } if (cp === 0xe31) return true; if (cp < 0xe34) return false; if (cp < 0xe3b) return true; if (cp < 0xe47) return false; if (cp < 0xe4f) return true; if (cp < 0xe50) return false; if (cp < 0xe5a) return true; if (cp === 0xeb1) return true; if (cp < 0xeb4) return false; if (cp < 0xeba) return true; if (cp < 0xebb) return false; if (cp < 0xebd) return true; if (cp < 0xec8) return false; if (cp < 0xece) return true; if (cp < 0xed0) return false; if (cp < 0xeda) return true; return false; } if (cp < 0xf80) { if (cp < 0xf18) return false; if (cp < 0xf1a) return true; if (cp < 0xf20) return false; if (cp < 0xf2a) return true; if (cp === 0xf35) return true; if (cp === 0xf37) return true; if (cp === 0xf39) return true; if (cp < 0xf3e) return false; if (cp < 0xf40) return true; if (cp < 0xf71) return false; if (cp < 0xf7f) return true; if (cp === 0xf7f) return true; return false; } if (cp < 0xf85) return true; if (cp < 0xf86) return false; if (cp < 0xf88) return true; if (cp < 0xf8d) return false; if (cp < 0xf98) return true; if (cp < 0xf99) return false; if (cp < 0xfbd) return true; if (cp === 0xfc6) return true; if (cp < 0x102b) return false; if (cp < 0x102d) return true; if (cp < 0x102d) return false; if (cp < 0x1031) return true; if (cp === 0x1031) return true; if (cp < 0x1032) return false; if (cp < 0x1038) return true; return false; } if (cp < 0x1090) { if (cp < 0x1062) { if (cp === 0x1038) return true; if (cp < 0x1039) return false; if (cp < 0x103b) return true; if (cp < 0x103b) return false; if (cp < 0x103d) return true; if (cp < 0x103d) return false; if (cp < 0x103f) return true; if (cp < 0x1040) return false; if (cp < 0x104a) return true; if (cp < 0x1056) return false; if (cp < 0x1058) return true; if (cp < 0x1058) return false; if (cp < 0x105a) return true; if (cp < 0x105e) return false; if (cp < 0x1061) return true; return false; } if (cp < 0x1065) return true; if (cp < 0x1067) return false; if (cp < 0x106e) return true; if (cp < 0x1071) return false; if (cp < 0x1075) return true; if (cp === 0x1082) return true; if (cp < 0x1083) return false; if (cp < 0x1085) return true; if (cp < 0x1085) return false; if (cp < 0x1087) return true; if (cp < 0x1087) return false; if (cp < 0x108d) return true; if (cp === 0x108d) return true; if (cp === 0x108f) return true; return false; } if (cp < 0x1772) { if (cp < 0x1090) return false; if (cp < 0x109a) return true; if (cp < 0x109a) return false; if (cp < 0x109d) return true; if (cp === 0x109d) return true; if (cp < 0x135d) return false; if (cp < 0x1360) return true; if (cp < 0x1369) return false; if (cp < 0x1372) return true; if (cp < 0x1712) return false; if (cp < 0x1715) return true; if (cp < 0x1732) return false; if (cp < 0x1735) return true; if (cp < 0x1752) return false; if (cp < 0x1754) return true; return false; } if (cp < 0x1774) return true; if (cp < 0x17b4) return false; if (cp < 0x17b6) return true; if (cp === 0x17b6) return true; if (cp < 0x17b7) return false; if (cp < 0x17be) return true; if (cp < 0x17be) return false; if (cp < 0x17c6) return true; if (cp === 0x17c6) return true; if (cp < 0x17c7) return false; if (cp < 0x17c9) return true; if (cp < 0x17c9) return false; if (cp < 0x17d4) return true; if (cp === 0x17dd) return true; return false; } if (cp < 0x1b04) { if (cp < 0x1a1b) { if (cp < 0x1930) { if (cp < 0x17e0) return false; if (cp < 0x17ea) return true; if (cp < 0x180b) return false; if (cp < 0x180e) return true; if (cp < 0x1810) return false; if (cp < 0x181a) return true; if (cp === 0x18a9) return true; if (cp < 0x1920) return false; if (cp < 0x1923) return true; if (cp < 0x1923) return false; if (cp < 0x1927) return true; if (cp < 0x1927) return false; if (cp < 0x1929) return true; if (cp < 0x1929) return false; if (cp < 0x192c) return true; return false; } if (cp < 0x1932) return true; if (cp === 0x1932) return true; if (cp < 0x1933) return false; if (cp < 0x1939) return true; if (cp < 0x1939) return false; if (cp < 0x193c) return true; if (cp < 0x1946) return false; if (cp < 0x1950) return true; if (cp < 0x19d0) return false; if (cp < 0x19da) return true; if (cp === 0x19da) return true; if (cp < 0x1a17) return false; if (cp < 0x1a19) return true; if (cp < 0x1a19) return false; if (cp < 0x1a1b) return true; return false; } if (cp < 0x1a63) { if (cp === 0x1a1b) return true; if (cp === 0x1a55) return true; if (cp === 0x1a56) return true; if (cp === 0x1a57) return true; if (cp < 0x1a58) return false; if (cp < 0x1a5f) return true; if (cp === 0x1a60) return true; if (cp === 0x1a61) return true; if (cp === 0x1a62) return true; return false; } if (cp < 0x1a65) return true; if (cp < 0x1a65) return false; if (cp < 0x1a6d) return true; if (cp < 0x1a6d) return false; if (cp < 0x1a73) return true; if (cp < 0x1a73) return false; if (cp < 0x1a7d) return true; if (cp === 0x1a7f) return true; if (cp < 0x1a80) return false; if (cp < 0x1a8a) return true; if (cp < 0x1a90) return false; if (cp < 0x1a9a) return true; if (cp < 0x1ab0) return false; if (cp < 0x1abe) return true; if (cp < 0x1b00) return false; if (cp < 0x1b04) return true; return false; } if (cp < 0x1baa) { if (cp < 0x1b43) { if (cp === 0x1b04) return true; if (cp === 0x1b34) return true; if (cp === 0x1b35) return true; if (cp < 0x1b36) return false; if (cp < 0x1b3b) return true; if (cp === 0x1b3b) return true; if (cp === 0x1b3c) return true; if (cp < 0x1b3d) return false; if (cp < 0x1b42) return true; if (cp === 0x1b42) return true; return false; } if (cp < 0x1b45) return true; if (cp < 0x1b50) return false; if (cp < 0x1b5a) return true; if (cp < 0x1b6b) return false; if (cp < 0x1b74) return true; if (cp < 0x1b80) return false; if (cp < 0x1b82) return true; if (cp === 0x1b82) return true; if (cp === 0x1ba1) return true; if (cp < 0x1ba2) return false; if (cp < 0x1ba6) return true; if (cp < 0x1ba6) return false; if (cp < 0x1ba8) return true; if (cp < 0x1ba8) return false; if (cp < 0x1baa) return true; return false; } if (cp < 0x1bee) { if (cp === 0x1baa) return true; if (cp < 0x1bab) return false; if (cp < 0x1bae) return true; if (cp < 0x1bb0) return false; if (cp < 0x1bba) return true; if (cp === 0x1be6) return true; if (cp === 0x1be7) return true; if (cp < 0x1be8) return false; if (cp < 0x1bea) return true; if (cp < 0x1bea) return false; if (cp < 0x1bed) return true; if (cp === 0x1bed) return true; return false; } if (cp === 0x1bee) return true; if (cp < 0x1bef) return false; if (cp < 0x1bf2) return true; if (cp < 0x1bf2) return false; if (cp < 0x1bf4) return true; if (cp < 0x1c24) return false; if (cp < 0x1c2c) return true; if (cp < 0x1c2c) return false; if (cp < 0x1c34) return true; if (cp < 0x1c34) return false; if (cp < 0x1c36) return true; if (cp < 0x1c36) return false; if (cp < 0x1c38) return true; if (cp < 0x1c40) return false; if (cp < 0x1c4a) return true; if (cp < 0x1c50) return false; if (cp < 0x1c5a) return true; return false; } if (cp < 0x1123e) { if (cp < 0xaab7) { if (cp < 0xa8b4) { if (cp < 0x2d7f) { if (cp < 0x1cf8) { if (cp < 0x1cd0) return false; if (cp < 0x1cd3) return true; if (cp < 0x1cd4) return false; if (cp < 0x1ce1) return true; if (cp === 0x1ce1) return true; if (cp < 0x1ce2) return false; if (cp < 0x1ce9) return true; if (cp === 0x1ced) return true; if (cp < 0x1cf2) return false; if (cp < 0x1cf4) return true; if (cp === 0x1cf4) return true; if (cp === 0x1cf7) return true; return false; } if (cp < 0x1cfa) return true; if (cp < 0x1dc0) return false; if (cp < 0x1dfa) return true; if (cp < 0x1dfb) return false; if (cp < 0x1e00) return true; if (cp < 0x203f) return false; if (cp < 0x2041) return true; if (cp === 0x2054) return true; if (cp < 0x20d0) return false; if (cp < 0x20dd) return true; if (cp === 0x20e1) return true; if (cp < 0x20e5) return false; if (cp < 0x20f1) return true; if (cp < 0x2cef) return false; if (cp < 0x2cf2) return true; return false; } if (cp < 0xa69e) { if (cp === 0x2d7f) return true; if (cp < 0x2de0) return false; if (cp < 0x2e00) return true; if (cp < 0x302a) return false; if (cp < 0x302e) return true; if (cp < 0x302e) return false; if (cp < 0x3030) return true; if (cp < 0x3099) return false; if (cp < 0x309b) return true; if (cp < 0xa620) return false; if (cp < 0xa62a) return true; if (cp === 0xa66f) return true; if (cp < 0xa674) return false; if (cp < 0xa67e) return true; return false; } if (cp < 0xa6a0) return true; if (cp < 0xa6f0) return false; if (cp < 0xa6f2) return true; if (cp === 0xa802) return true; if (cp === 0xa806) return true; if (cp === 0xa80b) return true; if (cp < 0xa823) return false; if (cp < 0xa825) return true; if (cp < 0xa825) return false; if (cp < 0xa827) return true; if (cp === 0xa827) return true; if (cp < 0xa880) return false; if (cp < 0xa882) return true; return false; } if (cp < 0xa9d0) { if (cp < 0xa952) { if (cp < 0xa8b4) return false; if (cp < 0xa8c4) return true; if (cp < 0xa8c4) return false; if (cp < 0xa8c6) return true; if (cp < 0xa8d0) return false; if (cp < 0xa8da) return true; if (cp < 0xa8e0) return false; if (cp < 0xa8f2) return true; if (cp === 0xa8ff) return true; if (cp < 0xa900) return false; if (cp < 0xa90a) return true; if (cp < 0xa926) return false; if (cp < 0xa92e) return true; if (cp < 0xa947) return false; if (cp < 0xa952) return true; return false; } if (cp < 0xa954) return true; if (cp < 0xa980) return false; if (cp < 0xa983) return true; if (cp === 0xa983) return true; if (cp === 0xa9b3) return true; if (cp < 0xa9b4) return false; if (cp < 0xa9b6) return true; if (cp < 0xa9b6) return false; if (cp < 0xa9ba) return true; if (cp < 0xa9ba) return false; if (cp < 0xa9bc) return true; if (cp === 0xa9bc) return true; if (cp < 0xa9bd) return false; if (cp < 0xa9c1) return true; return false; } if (cp < 0xaa43) { if (cp < 0xa9d0) return false; if (cp < 0xa9da) return true; if (cp === 0xa9e5) return true; if (cp < 0xa9f0) return false; if (cp < 0xa9fa) return true; if (cp < 0xaa29) return false; if (cp < 0xaa2f) return true; if (cp < 0xaa2f) return false; if (cp < 0xaa31) return true; if (cp < 0xaa31) return false; if (cp < 0xaa33) return true; if (cp < 0xaa33) return false; if (cp < 0xaa35) return true; if (cp < 0xaa35) return false; if (cp < 0xaa37) return true; return false; } if (cp === 0xaa43) return true; if (cp === 0xaa4c) return true; if (cp === 0xaa4d) return true; if (cp < 0xaa50) return false; if (cp < 0xaa5a) return true; if (cp === 0xaa7b) return true; if (cp === 0xaa7c) return true; if (cp === 0xaa7d) return true; if (cp === 0xaab0) return true; if (cp < 0xaab2) return false; if (cp < 0xaab5) return true; return false; } if (cp < 0x10d30) { if (cp < 0xfe00) { if (cp < 0xabe3) { if (cp < 0xaab7) return false; if (cp < 0xaab9) return true; if (cp < 0xaabe) return false; if (cp < 0xaac0) return true; if (cp === 0xaac1) return true; if (cp === 0xaaeb) return true; if (cp < 0xaaec) return false; if (cp < 0xaaee) return true; if (cp < 0xaaee) return false; if (cp < 0xaaf0) return true; if (cp === 0xaaf5) return true; if (cp === 0xaaf6) return true; return false; } if (cp < 0xabe5) return true; if (cp === 0xabe5) return true; if (cp < 0xabe6) return false; if (cp < 0xabe8) return true; if (cp === 0xabe8) return true; if (cp < 0xabe9) return false; if (cp < 0xabeb) return true; if (cp === 0xabec) return true; if (cp === 0xabed) return true; if (cp < 0xabf0) return false; if (cp < 0xabfa) return true; if (cp === 0xfb1e) return true; return false; } if (cp < 0x10376) { if (cp < 0xfe00) return false; if (cp < 0xfe10) return true; if (cp < 0xfe20) return false; if (cp < 0xfe30) return true; if (cp < 0xfe33) return false; if (cp < 0xfe35) return true; if (cp < 0xfe4d) return false; if (cp < 0xfe50) return true; if (cp < 0xff10) return false; if (cp < 0xff1a) return true; if (cp === 0xff3f) return true; if (cp === 0x101fd) return true; if (cp === 0x102e0) return true; return false; } if (cp < 0x1037b) return true; if (cp < 0x104a0) return false; if (cp < 0x104aa) return true; if (cp < 0x10a01) return false; if (cp < 0x10a04) return true; if (cp < 0x10a05) return false; if (cp < 0x10a07) return true; if (cp < 0x10a0c) return false; if (cp < 0x10a10) return true; if (cp < 0x10a38) return false; if (cp < 0x10a3b) return true; if (cp === 0x10a3f) return true; if (cp < 0x10ae5) return false; if (cp < 0x10ae7) return true; if (cp < 0x10d24) return false; if (cp < 0x10d28) return true; return false; } if (cp < 0x1112d) { if (cp < 0x11082) { if (cp < 0x10d30) return false; if (cp < 0x10d3a) return true; if (cp < 0x10f46) return false; if (cp < 0x10f51) return true; if (cp === 0x11000) return true; if (cp === 0x11001) return true; if (cp === 0x11002) return true; if (cp < 0x11038) return false; if (cp < 0x11047) return true; if (cp < 0x11066) return false; if (cp < 0x11070) return true; if (cp < 0x1107f) return false; if (cp < 0x11082) return true; return false; } if (cp === 0x11082) return true; if (cp < 0x110b0) return false; if (cp < 0x110b3) return true; if (cp < 0x110b3) return false; if (cp < 0x110b7) return true; if (cp < 0x110b7) return false; if (cp < 0x110b9) return true; if (cp < 0x110b9) return false; if (cp < 0x110bb) return true; if (cp < 0x110f0) return false; if (cp < 0x110fa) return true; if (cp < 0x11100) return false; if (cp < 0x11103) return true; if (cp < 0x11127) return false; if (cp < 0x1112c) return true; if (cp === 0x1112c) return true; return false; } if (cp < 0x111bf) { if (cp < 0x1112d) return false; if (cp < 0x11135) return true; if (cp < 0x11136) return false; if (cp < 0x11140) return true; if (cp < 0x11145) return false; if (cp < 0x11147) return true; if (cp === 0x11173) return true; if (cp < 0x11180) return false; if (cp < 0x11182) return true; if (cp === 0x11182) return true; if (cp < 0x111b3) return false; if (cp < 0x111b6) return true; if (cp < 0x111b6) return false; if (cp < 0x111bf) return true; return false; } if (cp < 0x111c1) return true; if (cp < 0x111c9) return false; if (cp < 0x111cd) return true; if (cp < 0x111d0) return false; if (cp < 0x111da) return true; if (cp < 0x1122c) return false; if (cp < 0x1122f) return true; if (cp < 0x1122f) return false; if (cp < 0x11232) return true; if (cp < 0x11232) return false; if (cp < 0x11234) return true; if (cp === 0x11234) return true; if (cp === 0x11235) return true; if (cp < 0x11236) return false; if (cp < 0x11238) return true; return false; } if (cp < 0x11a33) { if (cp < 0x115af) { if (cp < 0x11435) { if (cp < 0x1133e) { if (cp === 0x1123e) return true; if (cp === 0x112df) return true; if (cp < 0x112e0) return false; if (cp < 0x112e3) return true; if (cp < 0x112e3) return false; if (cp < 0x112eb) return true; if (cp < 0x112f0) return false; if (cp < 0x112fa) return true; if (cp < 0x11300) return false; if (cp < 0x11302) return true; if (cp < 0x11302) return false; if (cp < 0x11304) return true; if (cp < 0x1133b) return false; if (cp < 0x1133d) return true; return false; } if (cp < 0x11340) return true; if (cp === 0x11340) return true; if (cp < 0x11341) return false; if (cp < 0x11345) return true; if (cp < 0x11347) return false; if (cp < 0x11349) return true; if (cp < 0x1134b) return false; if (cp < 0x1134e) return true; if (cp === 0x11357) return true; if (cp < 0x11362) return false; if (cp < 0x11364) return true; if (cp < 0x11366) return false; if (cp < 0x1136d) return true; if (cp < 0x11370) return false; if (cp < 0x11375) return true; return false; } if (cp < 0x114b0) { if (cp < 0x11435) return false; if (cp < 0x11438) return true; if (cp < 0x11438) return false; if (cp < 0x11440) return true; if (cp < 0x11440) return false; if (cp < 0x11442) return true; if (cp < 0x11442) return false; if (cp < 0x11445) return true; if (cp === 0x11445) return true; if (cp === 0x11446) return true; if (cp < 0x11450) return false; if (cp < 0x1145a) return true; if (cp === 0x1145e) return true; return false; } if (cp < 0x114b3) return true; if (cp < 0x114b3) return false; if (cp < 0x114b9) return true; if (cp === 0x114b9) return true; if (cp === 0x114ba) return true; if (cp < 0x114bb) return false; if (cp < 0x114bf) return true; if (cp < 0x114bf) return false; if (cp < 0x114c1) return true; if (cp === 0x114c1) return true; if (cp < 0x114c2) return false; if (cp < 0x114c4) return true; if (cp < 0x114d0) return false; if (cp < 0x114da) return true; return false; } if (cp < 0x116ae) { if (cp < 0x11633) { if (cp < 0x115af) return false; if (cp < 0x115b2) return true; if (cp < 0x115b2) return false; if (cp < 0x115b6) return true; if (cp < 0x115b8) return false; if (cp < 0x115bc) return true; if (cp < 0x115bc) return false; if (cp < 0x115be) return true; if (cp === 0x115be) return true; if (cp < 0x115bf) return false; if (cp < 0x115c1) return true; if (cp < 0x115dc) return false; if (cp < 0x115de) return true; if (cp < 0x11630) return false; if (cp < 0x11633) return true; return false; } if (cp < 0x1163b) return true; if (cp < 0x1163b) return false; if (cp < 0x1163d) return true; if (cp === 0x1163d) return true; if (cp === 0x1163e) return true; if (cp < 0x1163f) return false; if (cp < 0x11641) return true; if (cp < 0x11650) return false; if (cp < 0x1165a) return true; if (cp === 0x116ab) return true; if (cp === 0x116ac) return true; if (cp === 0x116ad) return true; return false; } if (cp < 0x11726) { if (cp < 0x116ae) return false; if (cp < 0x116b0) return true; if (cp < 0x116b0) return false; if (cp < 0x116b6) return true; if (cp === 0x116b6) return true; if (cp === 0x116b7) return true; if (cp < 0x116c0) return false; if (cp < 0x116ca) return true; if (cp < 0x1171d) return false; if (cp < 0x11720) return true; if (cp < 0x11720) return false; if (cp < 0x11722) return true; if (cp < 0x11722) return false; if (cp < 0x11726) return true; return false; } if (cp === 0x11726) return true; if (cp < 0x11727) return false; if (cp < 0x1172c) return true; if (cp < 0x11730) return false; if (cp < 0x1173a) return true; if (cp < 0x1182c) return false; if (cp < 0x1182f) return true; if (cp < 0x1182f) return false; if (cp < 0x11838) return true; if (cp === 0x11838) return true; if (cp < 0x11839) return false; if (cp < 0x1183b) return true; if (cp < 0x118e0) return false; if (cp < 0x118ea) return true; if (cp < 0x11a01) return false; if (cp < 0x11a0b) return true; return false; } if (cp < 0x11d97) { if (cp < 0x11ca9) { if (cp < 0x11a97) { if (cp < 0x11a33) return false; if (cp < 0x11a39) return true; if (cp === 0x11a39) return true; if (cp < 0x11a3b) return false; if (cp < 0x11a3f) return true; if (cp === 0x11a47) return true; if (cp < 0x11a51) return false; if (cp < 0x11a57) return true; if (cp < 0x11a57) return false; if (cp < 0x11a59) return true; if (cp < 0x11a59) return false; if (cp < 0x11a5c) return true; if (cp < 0x11a8a) return false; if (cp < 0x11a97) return true; return false; } if (cp === 0x11a97) return true; if (cp < 0x11a98) return false; if (cp < 0x11a9a) return true; if (cp === 0x11c2f) return true; if (cp < 0x11c30) return false; if (cp < 0x11c37) return true; if (cp < 0x11c38) return false; if (cp < 0x11c3e) return true; if (cp === 0x11c3e) return true; if (cp === 0x11c3f) return true; if (cp < 0x11c50) return false; if (cp < 0x11c5a) return true; if (cp < 0x11c92) return false; if (cp < 0x11ca8) return true; return false; } if (cp < 0x11d3c) { if (cp === 0x11ca9) return true; if (cp < 0x11caa) return false; if (cp < 0x11cb1) return true; if (cp === 0x11cb1) return true; if (cp < 0x11cb2) return false; if (cp < 0x11cb4) return true; if (cp === 0x11cb4) return true; if (cp < 0x11cb5) return false; if (cp < 0x11cb7) return true; if (cp < 0x11d31) return false; if (cp < 0x11d37) return true; if (cp === 0x11d3a) return true; return false; } if (cp < 0x11d3e) return true; if (cp < 0x11d3f) return false; if (cp < 0x11d46) return true; if (cp === 0x11d47) return true; if (cp < 0x11d50) return false; if (cp < 0x11d5a) return true; if (cp < 0x11d8a) return false; if (cp < 0x11d8f) return true; if (cp < 0x11d90) return false; if (cp < 0x11d92) return true; if (cp < 0x11d93) return false; if (cp < 0x11d95) return true; if (cp === 0x11d95) return true; if (cp === 0x11d96) return true; return false; } if (cp < 0x1d242) { if (cp < 0x16f51) { if (cp === 0x11d97) return true; if (cp < 0x11da0) return false; if (cp < 0x11daa) return true; if (cp < 0x11ef3) return false; if (cp < 0x11ef5) return true; if (cp < 0x11ef5) return false; if (cp < 0x11ef7) return true; if (cp < 0x16a60) return false; if (cp < 0x16a6a) return true; if (cp < 0x16af0) return false; if (cp < 0x16af5) return true; if (cp < 0x16b30) return false; if (cp < 0x16b37) return true; if (cp < 0x16b50) return false; if (cp < 0x16b5a) return true; return false; } if (cp < 0x16f7f) return true; if (cp < 0x16f8f) return false; if (cp < 0x16f93) return true; if (cp < 0x1bc9d) return false; if (cp < 0x1bc9f) return true; if (cp < 0x1d165) return false; if (cp < 0x1d167) return true; if (cp < 0x1d167) return false; if (cp < 0x1d16a) return true; if (cp < 0x1d16d) return false; if (cp < 0x1d173) return true; if (cp < 0x1d17b) return false; if (cp < 0x1d183) return true; if (cp < 0x1d185) return false; if (cp < 0x1d18c) return true; if (cp < 0x1d1aa) return false; if (cp < 0x1d1ae) return true; return false; } if (cp < 0x1e000) { if (cp < 0x1d242) return false; if (cp < 0x1d245) return true; if (cp < 0x1d7ce) return false; if (cp < 0x1d800) return true; if (cp < 0x1da00) return false; if (cp < 0x1da37) return true; if (cp < 0x1da3b) return false; if (cp < 0x1da6d) return true; if (cp === 0x1da75) return true; if (cp === 0x1da84) return true; if (cp < 0x1da9b) return false; if (cp < 0x1daa0) return true; if (cp < 0x1daa1) return false; if (cp < 0x1dab0) return true; return false; } if (cp < 0x1e007) return true; if (cp < 0x1e008) return false; if (cp < 0x1e019) return true; if (cp < 0x1e01b) return false; if (cp < 0x1e022) return true; if (cp < 0x1e023) return false; if (cp < 0x1e025) return true; if (cp < 0x1e026) return false; if (cp < 0x1e02b) return true; if (cp < 0x1e8d0) return false; if (cp < 0x1e8d7) return true; if (cp < 0x1e944) return false; if (cp < 0x1e94b) return true; if (cp < 0x1e950) return false; if (cp < 0x1e95a) return true; if (cp < 0xe0100) return false; if (cp < 0xe01f0) return true; return false; } var PropertyData = { $LONE: new Set(["ASCII", "ASCII_Hex_Digit", "AHex", "Alphabetic", "Alpha", "Any", "Assigned", "Bidi_Control", "Bidi_C", "Bidi_Mirrored", "Bidi_M", "Case_Ignorable", "CI", "Cased", "Changes_When_Casefolded", "CWCF", "Changes_When_Casemapped", "CWCM", "Changes_When_Lowercased", "CWL", "Changes_When_NFKC_Casefolded", "CWKCF", "Changes_When_Titlecased", "CWT", "Changes_When_Uppercased", "CWU", "Dash", "Default_Ignorable_Code_Point", "DI", "Deprecated", "Dep", "Diacritic", "Dia", "Emoji", "Emoji_Component", "Emoji_Modifier", "Emoji_Modifier_Base", "Emoji_Presentation", "Extender", "Ext", "Grapheme_Base", "Gr_Base", "Grapheme_Extend", "Gr_Ext", "Hex_Digit", "Hex", "IDS_Binary_Operator", "IDSB", "IDS_Trinary_Operator", "IDST", "ID_Continue", "IDC", "ID_Start", "IDS", "Ideographic", "Ideo", "Join_Control", "Join_C", "Logical_Order_Exception", "LOE", "Lowercase", "Lower", "Math", "Noncharacter_Code_Point", "NChar", "Pattern_Syntax", "Pat_Syn", "Pattern_White_Space", "Pat_WS", "Quotation_Mark", "QMark", "Radical", "Regional_Indicator", "RI", "Sentence_Terminal", "STerm", "Soft_Dotted", "SD", "Terminal_Punctuation", "Term", "Unified_Ideograph", "UIdeo", "Uppercase", "Upper", "Variation_Selector", "VS", "White_Space", "space", "XID_Continue", "XIDC", "XID_Start", "XIDS"]), General_Category: new Set(["Cased_Letter", "LC", "Close_Punctuation", "Pe", "Connector_Punctuation", "Pc", "Control", "Cc", "cntrl", "Currency_Symbol", "Sc", "Dash_Punctuation", "Pd", "Decimal_Number", "Nd", "digit", "Enclosing_Mark", "Me", "Final_Punctuation", "Pf", "Format", "Cf", "Initial_Punctuation", "Pi", "Letter", "L", "Letter_Number", "Nl", "Line_Separator", "Zl", "Lowercase_Letter", "Ll", "Mark", "M", "Combining_Mark", "Math_Symbol", "Sm", "Modifier_Letter", "Lm", "Modifier_Symbol", "Sk", "Nonspacing_Mark", "Mn", "Number", "N", "Open_Punctuation", "Ps", "Other", "C", "Other_Letter", "Lo", "Other_Number", "No", "Other_Punctuation", "Po", "Other_Symbol", "So", "Paragraph_Separator", "Zp", "Private_Use", "Co", "Punctuation", "P", "punct", "Separator", "Z", "Space_Separator", "Zs", "Spacing_Mark", "Mc", "Surrogate", "Cs", "Symbol", "S", "Titlecase_Letter", "Lt", "Unassigned", "Cn", "Uppercase_Letter", "Lu"]), Script: new Set(["Adlam", "Adlm", "Ahom", "Anatolian_Hieroglyphs", "Hluw", "Arabic", "Arab", "Armenian", "Armn", "Avestan", "Avst", "Balinese", "Bali", "Bamum", "Bamu", "Bassa_Vah", "Bass", "Batak", "Batk", "Bengali", "Beng", "Bhaiksuki", "Bhks", "Bopomofo", "Bopo", "Brahmi", "Brah", "Braille", "Brai", "Buginese", "Bugi", "Buhid", "Buhd", "Canadian_Aboriginal", "Cans", "Carian", "Cari", "Caucasian_Albanian", "Aghb", "Chakma", "Cakm", "Cham", "Cherokee", "Cher", "Common", "Zyyy", "Coptic", "Copt", "Qaac", "Cuneiform", "Xsux", "Cypriot", "Cprt", "Cyrillic", "Cyrl", "Deseret", "Dsrt", "Devanagari", "Deva", "Duployan", "Dupl", "Egyptian_Hieroglyphs", "Egyp", "Elbasan", "Elba", "Ethiopic", "Ethi", "Georgian", "Geor", "Glagolitic", "Glag", "Gothic", "Goth", "Grantha", "Gran", "Greek", "Grek", "Gujarati", "Gujr", "Gurmukhi", "Guru", "Han", "Hani", "Hangul", "Hang", "Hanunoo", "Hano", "Hatran", "Hatr", "Hebrew", "Hebr", "Hiragana", "Hira", "Imperial_Aramaic", "Armi", "Inherited", "Zinh", "Qaai", "Inscriptional_Pahlavi", "Phli", "Inscriptional_Parthian", "Prti", "Javanese", "Java", "Kaithi", "Kthi", "Kannada", "Knda", "Katakana", "Kana", "Kayah_Li", "Kali", "Kharoshthi", "Khar", "Khmer", "Khmr", "Khojki", "Khoj", "Khudawadi", "Sind", "Lao", "Laoo", "Latin", "Latn", "Lepcha", "Lepc", "Limbu", "Limb", "Linear_A", "Lina", "Linear_B", "Linb", "Lisu", "Lycian", "Lyci", "Lydian", "Lydi", "Mahajani", "Mahj", "Malayalam", "Mlym", "Mandaic", "Mand", "Manichaean", "Mani", "Marchen", "Marc", "Masaram_Gondi", "Gonm", "Meetei_Mayek", "Mtei", "Mende_Kikakui", "Mend", "Meroitic_Cursive", "Merc", "Meroitic_Hieroglyphs", "Mero", "Miao", "Plrd", "Modi", "Mongolian", "Mong", "Mro", "Mroo", "Multani", "Mult", "Myanmar", "Mymr", "Nabataean", "Nbat", "New_Tai_Lue", "Talu", "Newa", "Nko", "Nkoo", "Nushu", "Nshu", "Ogham", "Ogam", "Ol_Chiki", "Olck", "Old_Hungarian", "Hung", "Old_Italic", "Ital", "Old_North_Arabian", "Narb", "Old_Permic", "Perm", "Old_Persian", "Xpeo", "Old_South_Arabian", "Sarb", "Old_Turkic", "Orkh", "Oriya", "Orya", "Osage", "Osge", "Osmanya", "Osma", "Pahawh_Hmong", "Hmng", "Palmyrene", "Palm", "Pau_Cin_Hau", "Pauc", "Phags_Pa", "Phag", "Phoenician", "Phnx", "Psalter_Pahlavi", "Phlp", "Rejang", "Rjng", "Runic", "Runr", "Samaritan", "Samr", "Saurashtra", "Saur", "Sharada", "Shrd", "Shavian", "Shaw", "Siddham", "Sidd", "SignWriting", "Sgnw", "Sinhala", "Sinh", "Sora_Sompeng", "Sora", "Soyombo", "Soyo", "Sundanese", "Sund", "Syloti_Nagri", "Sylo", "Syriac", "Syrc", "Tagalog", "Tglg", "Tagbanwa", "Tagb", "Tai_Le", "Tale", "Tai_Tham", "Lana", "Tai_Viet", "Tavt", "Takri", "Takr", "Tamil", "Taml", "Tangut", "Tang", "Telugu", "Telu", "Thaana", "Thaa", "Thai", "Tibetan", "Tibt", "Tifinagh", "Tfng", "Tirhuta", "Tirh", "Ugaritic", "Ugar", "Vai", "Vaii", "Warang_Citi", "Wara", "Yi", "Yiii", "Zanabazar_Square", "Zanb"]) }; PropertyData.gc = PropertyData.General_Category; PropertyData.sc = PropertyData.Script_Extensions = PropertyData.scx = PropertyData.Script; var Backspace = 0x08; var CharacterTabulation = 0x09; var LineFeed = 0x0a; var LineTabulation = 0x0b; var FormFeed = 0x0c; var CarriageReturn = 0x0d; var ExclamationMark = 0x21; var DollarSign = 0x24; var LeftParenthesis = 0x28; var RightParenthesis = 0x29; var Asterisk = 0x2a; var PlusSign = 0x2b; var Comma = 0x2c; var HyphenMinus = 0x2d; var FullStop = 0x2e; var Solidus = 0x2f; var DigitZero = 0x30; var DigitOne = 0x31; var DigitSeven = 0x37; var DigitNine = 0x39; var Colon = 0x3a; var LessThanSign = 0x3c; var EqualsSign = 0x3d; var GreaterThanSign = 0x3e; var QuestionMark = 0x3f; var LatinCapitalLetterA = 0x41; var LatinCapitalLetterB = 0x42; var LatinCapitalLetterD = 0x44; var LatinCapitalLetterF = 0x46; var LatinCapitalLetterP = 0x50; var LatinCapitalLetterS = 0x53; var LatinCapitalLetterW = 0x57; var LatinCapitalLetterZ = 0x5a; var LowLine = 0x5f; var LatinSmallLetterA = 0x61; var LatinSmallLetterB = 0x62; var LatinSmallLetterC = 0x63; var LatinSmallLetterD = 0x64; var LatinSmallLetterF = 0x66; var LatinSmallLetterG = 0x67; var LatinSmallLetterI = 0x69; var LatinSmallLetterK = 0x6b; var LatinSmallLetterM = 0x6d; var LatinSmallLetterN = 0x6e; var LatinSmallLetterP = 0x70; var LatinSmallLetterR = 0x72; var LatinSmallLetterS = 0x73; var LatinSmallLetterT = 0x74; var LatinSmallLetterU = 0x75; var LatinSmallLetterV = 0x76; var LatinSmallLetterW = 0x77; var LatinSmallLetterX = 0x78; var LatinSmallLetterY = 0x79; var LatinSmallLetterZ = 0x7a; var LeftSquareBracket = 0x5b; var ReverseSolidus = 0x5c; var RightSquareBracket = 0x5d; var CircumflexAccent = 0x5e; var LeftCurlyBracket = 0x7b; var VerticalLine = 0x7c; var RightCurlyBracket = 0x7d; var ZeroWidthNonJoiner = 0x200c; var ZeroWidthJoiner = 0x200d; var LineSeparator = 0x2028; var ParagraphSeparator = 0x2029; var MinCodePoint = 0x00; var MaxCodePoint = 0x10ffff; function isLatinLetter(code) { return code >= LatinCapitalLetterA && code <= LatinCapitalLetterZ || code >= LatinSmallLetterA && code <= LatinSmallLetterZ; } function isDecimalDigit(code) { return code >= DigitZero && code <= DigitNine; } function isOctalDigit(code) { return code >= DigitZero && code <= DigitSeven; } function isHexDigit(code) { return code >= DigitZero && code <= DigitNine || code >= LatinCapitalLetterA && code <= LatinCapitalLetterF || code >= LatinSmallLetterA && code <= LatinSmallLetterF; } function isLineTerminator(code) { return code === LineFeed || code === CarriageReturn || code === LineSeparator || code === ParagraphSeparator; } function isValidUnicode(code) { return code >= MinCodePoint && code <= MaxCodePoint; } function digitToInt(code) { if (code >= LatinSmallLetterA && code <= LatinSmallLetterF) { return code - LatinSmallLetterA + 10; } if (code >= LatinCapitalLetterA && code <= LatinCapitalLetterF) { return code - LatinCapitalLetterA + 10; } return code - DigitZero; } var legacyImpl = { at: function at(s, end, i) { return i < end ? s.charCodeAt(i) : -1; }, width: function width(c) { return 1; } }; var unicodeImpl = { at: function at(s, end, i) { return i < end ? s.codePointAt(i) : -1; }, width: function width(c) { return c > 0xffff ? 2 : 1; } }; var Reader = function () { function Reader() { _classCallCheck(this, Reader); this._impl = legacyImpl; this._s = ""; this._i = 0; this._end = 0; this._cp1 = -1; this._w1 = 1; this._cp2 = -1; this._w2 = 1; this._cp3 = -1; this._w3 = 1; this._cp4 = -1; } _createClass(Reader, [{ key: 'reset', value: function reset(source, start, end, uFlag) { this._impl = uFlag ? unicodeImpl : legacyImpl; this._s = source; this._end = end; this.rewind(start); } }, { key: 'rewind', value: function rewind(index) { var impl = this._impl; this._i = index; this._cp1 = impl.at(this._s, this._end, index); this._w1 = impl.width(this._cp1); this._cp2 = impl.at(this._s, this._end, index + this._w1); this._w2 = impl.width(this._cp2); this._cp3 = impl.at(this._s, this._end, index + this._w1 + this._w2); this._w3 = impl.width(this._cp3); this._cp4 = impl.at(this._s, this._end, index + this._w1 + this._w2 + this._w3); } }, { key: 'advance', value: function advance() { if (this._cp1 !== -1) { var impl = this._impl; this._i += this._w1; this._cp1 = this._cp2; this._w1 = this._w2; this._cp2 = this._cp3; this._w2 = impl.width(this._cp2); this._cp3 = this._cp4; this._w3 = impl.width(this._cp3); this._cp4 = impl.at(this._s, this._end, this._i + this._w1 + this._w2 + this._w3); } } }, { key: 'eat', value: function eat(cp) { if (this._cp1 === cp) { this.advance(); return true; } return false; } }, { key: 'eat2', value: function eat2(cp1, cp2) { if (this._cp1 === cp1 && this._cp2 === cp2) { this.advance(); this.advance(); return true; } return false; } }, { key: 'eat3', value: function eat3(cp1, cp2, cp3) { if (this._cp1 === cp1 && this._cp2 === cp2 && this._cp3 === cp3) { this.advance(); this.advance(); this.advance(); return true; } return false; } }, { key: 'source', get: function get() { return this._s; } }, { key: 'index', get: function get() { return this._i; } }, { key: 'currentCodePoint', get: function get() { return this._cp1; } }, { key: 'nextCodePoint', get: function get() { return this._cp2; } }, { key: 'nextCodePoint2', get: function get() { return this._cp3; } }, { key: 'nextCodePoint3', get: function get() { return this._cp4; } }]); return Reader; }(); var RegExpSyntaxError = function (_SyntaxError) { _inherits(RegExpSyntaxError, _SyntaxError); function RegExpSyntaxError(source, uFlag, index, message) { _classCallCheck(this, RegExpSyntaxError); if (source) { if (source[0] !== "/") { source = '/' + source + '/' + (uFlag ? "u" : ""); } source = ': ' + source; } var _this = _possibleConstructorReturn(this, (RegExpSyntaxError.__proto__ || Object.getPrototypeOf(RegExpSyntaxError)).call(this, 'Invalid regular expression' + source + ': ' + message)); _this.index = index; return _this; } return RegExpSyntaxError; }(SyntaxError); function isSyntaxCharacter(cp) { return cp === CircumflexAccent || cp === DollarSign || cp === ReverseSolidus || cp === FullStop || cp === Asterisk || cp === PlusSign || cp === QuestionMark || cp === LeftParenthesis || cp === RightParenthesis || cp === LeftSquareBracket || cp === RightSquareBracket || cp === LeftCurlyBracket || cp === RightCurlyBracket || cp === VerticalLine; } function isRegExpIdentifierStart(cp) { return isIdStart(cp) || cp === DollarSign || cp === LowLine; } function isRegExpIdentifierPart(cp) { return isIdContinue(cp) || cp === DollarSign || cp === LowLine || cp === ZeroWidthNonJoiner || cp === ZeroWidthJoiner; } function isUnicodePropertyNameCharacter(cp) { return isLatinLetter(cp) || cp === LowLine; } function isUnicodePropertyValueCharacter(cp) { return isUnicodePropertyNameCharacter(cp) || isDecimalDigit(cp); } function isValidUnicodeProperty(name, value) { return PropertyData.hasOwnProperty(name) && PropertyData[name].has(value); } function isValidUnicodePropertyName(name) { return PropertyData.$LONE.has(name); } var RegExpValidator = function () { function RegExpValidator(options) { _classCallCheck(this, RegExpValidator); this._reader = new Reader(); this._uFlag = false; this._nFlag = false; this._lastIntValue = 0; this._lastMinValue = 0; this._lastMaxValue = 0; this._lastStrValue = ""; this._lastKeyValue = ""; this._lastValValue = ""; this._lastAssertionIsQuantifiable = false; this._numCapturingParens = 0; this._groupNames = new Set(); this._backreferenceNames = new Set(); this._options = options || {}; } _createClass(RegExpValidator, [{ key: 'validateLiteral', value: function validateLiteral(source) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source.length; this._uFlag = this._nFlag = false; this.reset(source, start, end); this.onLiteralEnter(start); if (this.eat(Solidus) && this.eatRegExpBody() && this.eat(Solidus)) { var flagStart = this.index; var uFlag = source.indexOf("u", flagStart) !== -1; this.validateFlags(source, flagStart, end); this.validatePattern(source, start + 1, flagStart - 1, uFlag); } else if (start >= end) { this.raise("Empty"); } else { var c = String.fromCodePoint(this.currentCodePoint); this.raise('Unexpected character \'' + c + '\''); } this.onLiteralLeave(start, end); } }, { key: 'validateFlags', value: function validateFlags(source) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source.length; var existingFlags = new Set(); var global = false; var ignoreCase = false; var multiline = false; var sticky = false; var unicode = false; var dotAll = false; for (var i = start; i < end; ++i) { var flag = source.charCodeAt(i); if (existingFlags.has(flag)) { this.raise('Duplicated flag \'' + source[i] + '\''); } existingFlags.add(flag); if (flag === LatinSmallLetterG) { global = true; } else if (flag === LatinSmallLetterI) { ignoreCase = true; } else if (flag === LatinSmallLetterM) { multiline = true; } else if (flag === LatinSmallLetterU && this.ecmaVersion >= 2015) { unicode = true; } else if (flag === LatinSmallLetterY && this.ecmaVersion >= 2015) { sticky = true; } else if (flag === LatinSmallLetterS && this.ecmaVersion >= 2018) { dotAll = true; } else { this.raise('Invalid flag \'' + source[i] + '\''); } } this.onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll); } }, { key: 'validatePattern', value: function validatePattern(source) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source.length; var uFlag = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; this._uFlag = uFlag && this.ecmaVersion >= 2015; this._nFlag = uFlag && this.ecmaVersion >= 2018; this.reset(source, start, end); this.pattern(); if (!this._nFlag && this.ecmaVersion >= 2018 && this._groupNames.size > 0) { this._nFlag = true; this.rewind(start); this.pattern(); } } }, { key: 'onLiteralEnter', value: function onLiteralEnter(start) { if (this._options.onLiteralEnter) { this._options.onLiteralEnter(start); } } }, { key: 'onLiteralLeave', value: function onLiteralLeave(start, end) { if (this._options.onLiteralLeave) { this._options.onLiteralLeave(start, end); } } }, { key: 'onFlags', value: function onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll) { if (this._options.onFlags) { this._options.onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll); } } }, { key: 'onPatternEnter', value: function onPatternEnter(start) { if (this._options.onPatternEnter) { this._options.onPatternEnter(start); } } }, { key: 'onPatternLeave', value: function onPatternLeave(start, end) { if (this._options.onPatternLeave) { this._options.onPatternLeave(start, end); } } }, { key: 'onDisjunctionEnter', value: function onDisjunctionEnter(start) { if (this._options.onDisjunctionEnter) { this._options.onDisjunctionEnter(start); } } }, { key: 'onDisjunctionLeave', value: function onDisjunctionLeave(start, end) { if (this._options.onDisjunctionLeave) { this._options.onDisjunctionLeave(start, end); } } }, { key: 'onAlternativeEnter', value: function onAlternativeEnter(start, index) { if (this._options.onAlternativeEnter) { this._options.onAlternativeEnter(start, index); } } }, { key: 'onAlternativeLeave', value: function onAlternativeLeave(start, end, index) { if (this._options.onAlternativeLeave) { this._options.onAlternativeLeave(start, end, index); } } }, { key: 'onGroupEnter', value: function onGroupEnter(start) { if (this._options.onGroupEnter) { this._options.onGroupEnter(start); } } }, { key: 'onGroupLeave', value: function onGroupLeave(start, end) { if (this._options.onGroupLeave) { this._options.onGroupLeave(start, end); } } }, { key: 'onCapturingGroupEnter', value: function onCapturingGroupEnter(start, name) { if (this._options.onCapturingGroupEnter) { this._options.onCapturingGroupEnter(start, name); } } }, { key: 'onCapturingGroupLeave', value: function onCapturingGroupLeave(start, end, name) { if (this._options.onCapturingGroupLeave) { this._options.onCapturingGroupLeave(start, end, name); } } }, { key: 'onQuantifier', value: function onQuantifier(start, end, min, max, greedy) { if (this._options.onQuantifier) { this._options.onQuantifier(start, end, min, max, greedy); } } }, { key: 'onLookaroundAssertionEnter', value: function onLookaroundAssertionEnter(start, kind, negate) { if (this._options.onLookaroundAssertionEnter) { this._options.onLookaroundAssertionEnter(start, kind, negate); } } }, { key: 'onLookaroundAssertionLeave', value: function onLookaroundAssertionLeave(start, end, kind, negate) { if (this._options.onLookaroundAssertionLeave) { this._options.onLookaroundAssertionLeave(start, end, kind, negate); } } }, { key: 'onEdgeAssertion', value: function onEdgeAssertion(start, end, kind) { if (this._options.onEdgeAssertion) { this._options.onEdgeAssertion(start, end, kind); } } }, { key: 'onWordBoundaryAssertion', value: function onWordBoundaryAssertion(start, end, kind, negate) { if (this._options.onWordBoundaryAssertion) { this._options.onWordBoundaryAssertion(start, end, kind, negate); } } }, { key: 'onAnyCharacterSet', value: function onAnyCharacterSet(start, end, kind) { if (this._options.onAnyCharacterSet) { this._options.onAnyCharacterSet(start, end, kind); } } }, { key: 'onEscapeCharacterSet', value: function onEscapeCharacterSet(start, end, kind, negate) { if (this._options.onEscapeCharacterSet) { this._options.onEscapeCharacterSet(start, end, kind, negate); } } }, { key: 'onUnicodePropertyCharacterSet', value: function onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) { if (this._options.onUnicodePropertyCharacterSet) { this._options.onUnicodePropertyCharacterSet(start, end, kind, key, value, negate); } } }, { key: 'onCharacter', value: function onCharacter(start, end, value) { if (this._options.onCharacter) { this._options.onCharacter(start, end, value); } } }, { key: 'onBackreference', value: function onBackreference(start, end, ref) { if (this._options.onBackreference) { this._options.onBackreference(start, end, ref); } } }, { key: 'onCharacterClassEnter', value: function onCharacterClassEnter(start, negate) { if (this._options.onCharacterClassEnter) { this._options.onCharacterClassEnter(start, negate); } } }, { key: 'onCharacterClassLeave', value: function onCharacterClassLeave(start, end, negate) { if (this._options.onCharacterClassLeave) { this._options.onCharacterClassLeave(start, end, negate); } } }, { key: 'onCharacterClassRange', value: function onCharacterClassRange(start, end, min, max) { if (this._options.onCharacterClassRange) { this._options.onCharacterClassRange(start, end, min, max); } } }, { key: 'reset', value: function reset(source, start, end) { this._reader.reset(source, start, end, this._uFlag); } }, { key: 'rewind', value: function rewind(index) { this._reader.rewind(index); } }, { key: 'advance', value: function advance() { this._reader.advance(); } }, { key: 'eat', value: function eat(cp) { return this._reader.eat(cp); } }, { key: 'eat2', value: function eat2(cp1, cp2) { return this._reader.eat2(cp1, cp2); } }, { key: 'eat3', value: function eat3(cp1, cp2, cp3) { return this._reader.eat3(cp1, cp2, cp3); } }, { key: 'raise', value: function raise(message) { throw new RegExpSyntaxError(this.source, this._uFlag, this.index, message); } }, { key: 'eatRegExpBody', value: function eatRegExpBody() { var start = this.index; var inClass = false; var escaped = false; for (;;) { var cp = this.currentCodePoint; if (cp === -1 || isLineTerminator(cp)) { var kind = inClass ? "character class" : "regular expression"; this.raise('Unterminated ' + kind); } if (escaped) { escaped = false; } else if (cp === ReverseSolidus) { escaped = true; } else if (cp === LeftSquareBracket) { inClass = true; } else if (cp === RightSquareBracket) { inClass = false; } else if (cp === Solidus && !inClass || cp === Asterisk && this.index === start) { break; } this.advance(); } return this.index !== start; } }, { key: 'pattern', value: function pattern() { var start = this.index; this._numCapturingParens = this.countCapturingParens(); this._groupNames.clear(); this._backreferenceNames.clear(); this.onPatternEnter(start); this.disjunction(); var cp = this.currentCodePoint; if (this.currentCodePoint !== -1) { if (cp === RightParenthesis) { this.raise("Unmatched ')'"); } if (cp === ReverseSolidus) { this.raise("\\ at end of pattern"); } if (cp === RightSquareBracket || cp === RightCurlyBracket) { this.raise("Lone quantifier brackets"); } var c = String.fromCodePoint(cp); this.raise('Unexpected character \'' + c + '\''); } var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this._backreferenceNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var name = _step.value; if (!this._groupNames.has(name)) { this.raise("Invalid named capture referenced"); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } this.onPatternLeave(start, this.index); } }, { key: 'countCapturingParens', value: function countCapturingParens() { var start = this.index; var inClass = false; var escaped = false; var count = 0; var cp = 0; while ((cp = this.currentCodePoint) !== -1) { if (escaped) { escaped = false; } else if (cp === ReverseSolidus) { escaped = true; } else if (cp === LeftSquareBracket) { inClass = true; } else if (cp === RightSquareBracket) { inClass = false; } else if (cp === LeftParenthesis && !inClass && (this.nextCodePoint !== QuestionMark || this.nextCodePoint2 === LessThanSign && this.nextCodePoint3 !== EqualsSign && this.nextCodePoint3 !== ExclamationMark)) { count += 1; } this.advance(); } this.rewind(start); return count; } }, { key: 'disjunction', value: function disjunction() { var start = this.index; var i = 0; this.onDisjunctionEnter(start); this.alternative(i++); while (this.eat(VerticalLine)) { this.alternative(i++); } if (this.eatQuantifier(true)) { this.raise("Nothing to repeat"); } if (this.eat(LeftCurlyBracket)) { this.raise("Lone quantifier brackets"); } this.onDisjunctionLeave(start, this.index); } }, { key: 'alternative', value: function alternative(i) { var start = this.index; this.onAlternativeEnter(start, i); while (this.currentCodePoint !== -1 && this.eatTerm()) {} this.onAlternativeLeave(start, this.index, i); } }, { key: 'eatTerm', value: function eatTerm() { if (this.eatAssertion()) { if (this._lastAssertionIsQuantifiable) { this.eatQuantifier(); } return true; } if (this.strict ? this.eatAtom() : this.eatExtendedAtom()) { this.eatQuantifier(); return true; } return false; } }, { key: 'eatAssertion', value: function eatAssertion() { var start = this.index; this._lastAssertionIsQuantifiable = false; if (this.eat(CircumflexAccent)) { this.onEdgeAssertion(start, this.index, "start"); return true; } if (this.eat(DollarSign)) { this.onEdgeAssertion(start, this.index, "end"); return true; } if (this.eat2(ReverseSolidus, LatinCapitalLetterB)) { this.onWordBoundaryAssertion(start, this.index, "word", true); return true; } if (this.eat2(ReverseSolidus, LatinSmallLetterB)) { this.onWordBoundaryAssertion(start, this.index, "word", false); return true; } if (this.eat2(LeftParenthesis, QuestionMark)) { var lookbehind = this.ecmaVersion >= 2018 && this.eat(LessThanSign); var negate = false; if (this.eat(EqualsSign) || (negate = this.eat(ExclamationMark))) { var kind = lookbehind ? "lookbehind" : "lookahead"; this.onLookaroundAssertionEnter(start, kind, negate); this.disjunction(); if (!this.eat(RightParenthesis)) { this.raise("Unterminated group"); } this._lastAssertionIsQuantifiable = !lookbehind && !this.strict; this.onLookaroundAssertionLeave(start, this.index, kind, negate); return true; } this.rewind(start); } return false; } }, { key: 'eatQuantifier', value: function eatQuantifier() { var noError = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var start = this.index; var min = 0; var max = 0; var greedy = false; if (this.eat(Asterisk)) { min = 0; max = Number.POSITIVE_INFINITY; } else if (this.eat(PlusSign)) { min = 1; max = Number.POSITIVE_INFINITY; } else if (this.eat(QuestionMark)) { min = 0; max = 1; } else if (this.eatBracedQuantifier(noError)) { min = this._lastMinValue; max = this._lastMaxValue; } else { return false; } greedy = !this.eat(QuestionMark); if (!noError) { this.onQuantifier(start, this.index, min, max, greedy); } return true; } }, { key: 'eatBracedQuantifier', value: function eatBracedQuantifier(noError) { var start = this.index; if (this.eat(LeftCurlyBracket)) { this._lastMinValue = 0; this._lastMaxValue = Number.POSITIVE_INFINITY; if (this.eatDecimalDigits()) { this._lastMinValue = this._lastMaxValue = this._lastIntValue; if (this.eat(Comma)) { this._lastMaxValue = this.eatDecimalDigits() ? this._lastIntValue : Number.POSITIVE_INFINITY; } if (this.eat(RightCurlyBracket)) { if (!noError && this._lastMaxValue < this._lastMinValue) { this.raise("numbers out of order in {} quantifier"); } return true; } } if (!noError && this.strict) { this.raise("Incomplete quantifier"); } this.rewind(start); } return false; } }, { key: 'eatAtom', value: function eatAtom() { return this.eatPatternCharacter() || this.eatDot() || this.eatReverseSolidusAtomEscape() || this.eatCharacterClass() || this.eatUncapturingGroup() || this.eatCapturingGroup(); } }, { key: 'eatDot', value: function eatDot() { if (this.eat(FullStop)) { this.onAnyCharacterSet(this.index - 1, this.index, "any"); return true; } return false; } }, { key: 'eatReverseSolidusAtomEscape', value: function eatReverseSolidusAtomEscape() { var start = this.index; if (this.eat(ReverseSolidus)) { if (this.eatAtomEscape()) { return true; } this.rewind(start); } return false; } }, { key: 'eatUncapturingGroup', value: function eatUncapturingGroup() { var start = this.index; if (this.eat3(LeftParenthesis, QuestionMark, Colon)) { this.onGroupEnter(start); this.disjunction(); if (!this.eat(RightParenthesis)) { this.raise("Unterminated group"); } this.onGroupLeave(start, this.index); return true; } return false; } }, { key: 'eatCapturingGroup', value: function eatCapturingGroup() { var start = this.index; if (this.eat(LeftParenthesis)) { this._lastStrValue = ""; if (this.ecmaVersion >= 2018) { this.groupSpecifier(); } else if (this.currentCodePoint === QuestionMark) { this.raise("Invalid group"); } var name = this._lastStrValue || null; this.onCapturingGroupEnter(start, name); this.disjunction(); if (!this.eat(RightParenthesis)) { this.raise("Unterminated group"); } this.onCapturingGroupLeave(start, this.index, name); return true; } return false; } }, { key: 'eatExtendedAtom', value: function eatExtendedAtom() { return this.eatDot() || this.eatReverseSolidusAtomEscape() || this.eatReverseSolidusFollowedByC() || this.eatCharacterClass() || this.eatUncapturingGroup() || this.eatCapturingGroup() || this.eatInvalidBracedQuantifier() || this.eatExtendedPatternCharacter(); } }, { key: 'eatReverseSolidusFollowedByC', value: function eatReverseSolidusFollowedByC() { if (this.currentCodePoint === ReverseSolidus && this.nextCodePoint === LatinSmallLetterC) { this._lastIntValue = this.currentCodePoint; this.advance(); this.onCharacter(this.index - 1, this.index, ReverseSolidus); return true; } return false; } }, { key: 'eatInvalidBracedQuantifier', value: function eatInvalidBracedQuantifier() { if (this.eatBracedQuantifier(true)) { this.raise("Nothing to repeat"); } return false; } }, { key: 'eatSyntaxCharacter', value: function eatSyntaxCharacter() { if (isSyntaxCharacter(this.currentCodePoint)) { this._lastIntValue = this.currentCodePoint; this.advance(); return true; } return false; } }, { key: 'eatPatternCharacter', value: function eatPatternCharacter() { var start = this.index; var cp = this.currentCodePoint; if (cp !== -1 && !isSyntaxCharacter(cp)) { this.advance(); this.onCharacter(start, this.index, cp); return true; } return false; } }, { key: 'eatExtendedPatternCharacter', value: function eatExtendedPatternCharacter() { var start = this.index; var cp = this.currentCodePoint; if (cp !== -1 && cp !== CircumflexAccent && cp !== DollarSign && cp !== ReverseSolidus && cp !== FullStop && cp !== Asterisk && cp !== PlusSign && cp !== QuestionMark && cp !== LeftParenthesis && cp !== RightParenthesis && cp !== LeftSquareBracket && cp !== VerticalLine) { this.advance(); this.onCharacter(start, this.index, cp); return true; } return false; } }, { key: 'groupSpecifier', value: function groupSpecifier() { this._lastStrValue = ""; if (this.eat(QuestionMark)) { if (this.eatGroupName()) { if (!this._groupNames.has(this._lastStrValue)) { this._groupNames.add(this._lastStrValue); return; } this.raise("Duplicate capture group name"); } this.raise("Invalid group"); } } }, { key: 'eatGroupName', value: function eatGroupName() { this._lastStrValue = ""; if (this.eat(LessThanSign)) { if (this.eatRegExpIdentifierName() && this.eat(GreaterThanSign)) { return true; } this.raise("Invalid capture group name"); } return false; } }, { key: 'eatRegExpIdentifierName', value: function eatRegExpIdentifierName() { this._lastStrValue = ""; if (this.eatRegExpIdentifierStart()) { this._lastStrValue += String.fromCodePoint(this._lastIntValue); while (this.eatRegExpIdentifierPart()) { this._lastStrValue += String.fromCodePoint(this._lastIntValue); } return true; } return false; } }, { key: 'eatRegExpIdentifierStart', value: function eatRegExpIdentifierStart() { var start = this.index; var cp = this.currentCodePoint; this.advance(); if (cp === ReverseSolidus && this.eatRegExpUnicodeEscapeSequence()) { cp = this._lastIntValue; } if (isRegExpIdentifierStart(cp)) { this._lastIntValue = cp; return true; } if (this.index !== start) { this.rewind(start); } return false; } }, { key: 'eatRegExpIdentifierPart', value: function eatRegExpIdentifierPart() { var start = this.index; var cp = this.currentCodePoint; this.advance(); if (cp === ReverseSolidus && this.eatRegExpUnicodeEscapeSequence()) { cp = this._lastIntValue; } if (isRegExpIdentifierPart(cp)) { this._lastIntValue = cp; return true; } if (this.index !== start) { this.rewind(start); } return false; } }, { key: 'eatAtomEscape', value: function eatAtomEscape() { if (this.eatBackreference() || this.eatCharacterClassEscape() || this.eatCharacterEscape() || this._nFlag && this.eatKGroupName()) { return true; } if (this.strict || this._uFlag) { this.raise("Invalid escape"); } return false; } }, { key: 'eatBackreference', value: function eatBackreference() { var start = this.index; if (this.eatDecimalEscape()) { var n = this._lastIntValue; if (n <= this._numCapturingParens) { this.onBackreference(start - 1, this.index, n); return true; } if (this.strict) { this.raise("Invalid escape"); } this.rewind(start); } return false; } }, { key: 'eatKGroupName', value: function eatKGroupName() { var start = this.index; if (this.eat(LatinSmallLetterK)) { if (this.eatGroupName()) { var groupName = this._lastStrValue; this._backreferenceNames.add(groupName); this.onBackreference(start - 1, this.index, groupName); return true; } this.raise("Invalid named reference"); } return false; } }, { key: 'eatCharacterEscape', value: function eatCharacterEscape() { var start = this.index; if (this.eatControlEscape() || this.eatCControlLetter() || this.eatZero() || this.eatHexEscapeSequence() || this.eatRegExpUnicodeEscapeSequence() || !this.strict && this.eatLegacyOctalEscapeSequence() || this.eatIdentityEscape()) { this.onCharacter(start - 1, this.index, this._lastIntValue); return true; } return false; } }, { key: 'eatCControlLetter', value: function eatCControlLetter() { var start = this.index; if (this.eat(LatinSmallLetterC)) { if (this.eatControlLetter()) { return true; } this.rewind(start); } return false; } }, { key: 'eatZero', value: function eatZero() { if (this.currentCodePoint === DigitZero && !isDecimalDigit(this.nextCodePoint)) { this._lastIntValue = 0; this.advance(); return true; } return false; } }, { key: 'eatControlEscape', value: function eatControlEscape() { if (this.eat(LatinSmallLetterT)) { this._lastIntValue = CharacterTabulation; return true; } if (this.eat(LatinSmallLetterN)) { this._lastIntValue = LineFeed; return true; } if (this.eat(LatinSmallLetterV)) { this._lastIntValue = LineTabulation; return true; } if (this.eat(LatinSmallLetterF)) { this._lastIntValue = FormFeed; return true; } if (this.eat(LatinSmallLetterR)) { this._lastIntValue = CarriageReturn; return true; } return false; } }, { key: 'eatControlLetter', value: function eatControlLetter() { var cp = this.currentCodePoint; if (isLatinLetter(cp)) { this.advance(); this._lastIntValue = cp % 0x20; return true; } return false; } }, { key: 'eatRegExpUnicodeEscapeSequence', value: function eatRegExpUnicodeEscapeSequence() { var start = this.index; if (this.eat(LatinSmallLetterU)) { if (this.eatFixedHexDigits(4)) { var lead = this._lastIntValue; if (this._uFlag && lead >= 0xd800 && lead <= 0xdbff) { var leadSurrogateEnd = this.index; if (this.eat(ReverseSolidus) && this.eat(LatinSmallLetterU) && this.eatFixedHexDigits(4)) { var trail = this._lastIntValue; if (trail >= 0xdc00 && trail <= 0xdfff) { this._lastIntValue = (lead - 0xd800) * 0x400 + (trail - 0xdc00) + 0x10000; return true; } } this.rewind(leadSurrogateEnd); this._lastIntValue = lead; } return true; } if (this._uFlag && this.eat(LeftCurlyBracket) && this.eatHexDigits() && this.eat(RightCurlyBracket) && isValidUnicode(this._lastIntValue)) { return true; } if (this.strict || this._uFlag) { this.raise("Invalid unicode escape"); } this.rewind(start); } return false; } }, { key: 'eatIdentityEscape', value: function eatIdentityEscape() { if (this._uFlag) { if (this.eatSyntaxCharacter()) { return true; } if (this.eat(Solidus)) { this._lastIntValue = Solidus; return true; } return false; } if (this.isValidIdentityEscape(this.currentCodePoint)) { this._lastIntValue = this.currentCodePoint; this.advance(); return true; } return false; } }, { key: 'isValidIdentityEscape', value: function isValidIdentityEscape(cp) { if (cp === -1) { return false; } if (this.strict) { return !isIdContinue(cp); } return cp !== LatinSmallLetterC && (!this._nFlag || cp !== LatinSmallLetterK); } }, { key: 'eatDecimalEscape', value: function eatDecimalEscape() { this._lastIntValue = 0; var cp = this.currentCodePoint; if (cp >= DigitOne && cp <= DigitNine) { do { this._lastIntValue = 10 * this._lastIntValue + (cp - DigitZero); this.advance(); } while ((cp = this.currentCodePoint) >= DigitZero && cp <= DigitNine); return true; } return false; } }, { key: 'eatCharacterClassEscape', value: function eatCharacterClassEscape() { var start = this.index; if (this.eat(LatinSmallLetterD)) { this._lastIntValue = -1; this.onEscapeCharacterSet(start - 1, this.index, "digit", false); return true; } if (this.eat(LatinCapitalLetterD)) { this._lastIntValue = -1; this.onEscapeCharacterSet(start - 1, this.index, "digit", true); return true; } if (this.eat(LatinSmallLetterS)) { this._lastIntValue = -1; this.onEscapeCharacterSet(start - 1, this.index, "space", false); return true; } if (this.eat(LatinCapitalLetterS)) { this._lastIntValue = -1; this.onEscapeCharacterSet(start - 1, this.index, "space", true); return true; } if (this.eat(LatinSmallLetterW)) { this._lastIntValue = -1; this.onEscapeCharacterSet(start - 1, this.index, "word", false); return true; } if (this.eat(LatinCapitalLetterW)) { this._lastIntValue = -1; this.onEscapeCharacterSet(start - 1, this.index, "word", true); return true; } var negate = false; if (this._uFlag && this.ecmaVersion >= 2018 && (this.eat(LatinSmallLetterP) || (negate = this.eat(LatinCapitalLetterP)))) { this._lastIntValue = -1; if (this.eat(LeftCurlyBracket) && this.eatUnicodePropertyValueExpression() && this.eat(RightCurlyBracket)) { this.onUnicodePropertyCharacterSet(start - 1, this.index, "property", this._lastKeyValue, this._lastValValue || null, negate); return true; } this.raise("Invalid property name"); } return false; } }, { key: 'eatUnicodePropertyValueExpression', value: function eatUnicodePropertyValueExpression() { var start = this.index; if (this.eatUnicodePropertyName() && this.eat(EqualsSign)) { this._lastKeyValue = this._lastStrValue; if (this.eatUnicodePropertyValue()) { this._lastValValue = this._lastStrValue; if (isValidUnicodeProperty(this._lastKeyValue, this._lastValValue)) { return true; } this.raise("Invalid property name"); } } this.rewind(start); if (this.eatLoneUnicodePropertyNameOrValue()) { var nameOrValue = this._lastStrValue; if (isValidUnicodeProperty("General_Category", nameOrValue)) { this._lastKeyValue = "General_Category"; this._lastValValue = nameOrValue; return true; } if (isValidUnicodePropertyName(nameOrValue)) { this._lastKeyValue = nameOrValue; this._lastValValue = ""; return true; } this.raise("Invalid property name"); } return false; } }, { key: 'eatUnicodePropertyName', value: function eatUnicodePropertyName() { this._lastStrValue = ""; while (isUnicodePropertyNameCharacter(this.currentCodePoint)) { this._lastStrValue += String.fromCodePoint(this.currentCodePoint); this.advance(); } return this._lastStrValue !== ""; } }, { key: 'eatUnicodePropertyValue', value: function eatUnicodePropertyValue() { this._lastStrValue = ""; while (isUnicodePropertyValueCharacter(this.currentCodePoint)) { this._lastStrValue += String.fromCodePoint(this.currentCodePoint); this.advance(); } return this._lastStrValue !== ""; } }, { key: 'eatLoneUnicodePropertyNameOrValue', value: function eatLoneUnicodePropertyNameOrValue() { return this.eatUnicodePropertyValue(); } }, { key: 'eatCharacterClass', value: function eatCharacterClass() { var start = this.index; if (this.eat(LeftSquareBracket)) { var negate = this.eat(CircumflexAccent); this.onCharacterClassEnter(start, negate); this.classRanges(); if (!this.eat(RightSquareBracket)) { this.raise("Unterminated character class"); } this.onCharacterClassLeave(start, this.index, negate); return true; } return false; } }, { key: 'classRanges', value: function classRanges() { var start = this.index; while (this.eatClassAtom()) { var left = this._lastIntValue; var hyphenStart = this.index; if (this.eat(HyphenMinus)) { this.onCharacter(hyphenStart, this.index, HyphenMinus); if (this.eatClassAtom()) { var right = this._lastIntValue; if (left === -1 || right === -1) { if (this.strict) { this.raise("Invalid character class"); } } else if (left > right) { this.raise("Range out of order in character class"); } else { this.onCharacterClassRange(start, this.index, left, right); } } } start = this.index; } } }, { key: 'eatClassAtom', value: function eatClassAtom() { var start = this.index; if (this.eat(ReverseSolidus)) { if (this.eatClassEscape()) { return true; } if (this._uFlag) { this.raise("Invalid escape"); } this.rewind(start); } var cp = this.currentCodePoint; if (cp !== -1 && cp !== RightSquareBracket) { this.advance(); this._lastIntValue = cp; this.onCharacter(start, this.index, cp); return true; } return false; } }, { key: 'eatClassEscape', value: function eatClassEscape() { var start = this.index; if (this.eat(LatinSmallLetterB)) { this._lastIntValue = Backspace; this.onCharacter(start - 1, this.index, Backspace); return true; } if (this._uFlag && this.eat(HyphenMinus)) { this._lastIntValue = HyphenMinus; this.onCharacter(start - 1, this.index, HyphenMinus); return true; } if (!this._uFlag && this.eat(LatinSmallLetterC)) { if (this.eatClassControlLetter()) { this.onCharacter(start - 1, this.index, this._lastIntValue); return true; } this.rewind(start); } return this.eatCharacterClassEscape() || this.eatCharacterEscape(); } }, { key: 'eatClassControlLetter', value: function eatClassControlLetter() { var cp = this.currentCodePoint; if (isDecimalDigit(cp) || cp === LowLine) { this.advance(); this._lastIntValue = cp % 0x20; return true; } return false; } }, { key: 'eatHexEscapeSequence', value: function eatHexEscapeSequence() { var start = this.index; if (this.eat(LatinSmallLetterX)) { if (this.eatFixedHexDigits(2)) { return true; } if (this._uFlag) { this.raise("Invalid escape"); } this.rewind(start); } return false; } }, { key: 'eatDecimalDigits', value: function eatDecimalDigits() { var start = this.index; this._lastIntValue = 0; while (isDecimalDigit(this.currentCodePoint)) { this._lastIntValue = 10 * this._lastIntValue + digitToInt(this.currentCodePoint); this.advance(); } return this.index !== start; } }, { key: 'eatHexDigits', value: function eatHexDigits() { var start = this.index; this._lastIntValue = 0; while (isHexDigit(this.currentCodePoint)) { this._lastIntValue = 16 * this._lastIntValue + digitToInt(this.currentCodePoint); this.advance(); } return this.index !== start; } }, { key: 'eatLegacyOctalEscapeSequence', value: function eatLegacyOctalEscapeSequence() { if (this.eatOctalDigit()) { var n1 = this._lastIntValue; if (this.eatOctalDigit()) { var n2 = this._lastIntValue; if (n1 <= 3 && this.eatOctalDigit()) { this._lastIntValue = n1 * 64 + n2 * 8 + this._lastIntValue; } else { this._lastIntValue = n1 * 8 + n2; } } else { this._lastIntValue = n1; } return true; } return false; } }, { key: 'eatOctalDigit', value: function eatOctalDigit() { var cp = this.currentCodePoint; if (isOctalDigit(cp)) { this.advance(); this._lastIntValue = cp - DigitZero; return true; } this._lastIntValue = 0; return false; } }, { key: 'eatFixedHexDigits', value: function eatFixedHexDigits(length) { var start = this.index; this._lastIntValue = 0; for (var i = 0; i < length; ++i) { var cp = this.currentCodePoint; if (!isHexDigit(cp)) { this.rewind(start); return false; } this._lastIntValue = 16 * this._lastIntValue + digitToInt(cp); this.advance(); } return true; } }, { key: 'strict', get: function get() { return Boolean(this._options.strict || this._uFlag); } }, { key: 'ecmaVersion', get: function get() { return this._options.ecmaVersion || 2018; } }, { key: 'source', get: function get() { return this._reader.source; } }, { key: 'index', get: function get() { return this._reader.index; } }, { key: 'currentCodePoint', get: function get() { return this._reader.currentCodePoint; } }, { key: 'nextCodePoint', get: function get() { return this._reader.nextCodePoint; } }, { key: 'nextCodePoint2', get: function get() { return this._reader.nextCodePoint2; } }, { key: 'nextCodePoint3', get: function get() { return this._reader.nextCodePoint3; } }]); return RegExpValidator; }(); var DummyPattern = {}; var DummyFlags = {}; var DummyCapturingGroup = {}; var RegExpParserState = function () { function RegExpParserState(options) { _classCallCheck(this, RegExpParserState); this._node = DummyPattern; this._flags = DummyFlags; this._backreferences = []; this._capturingGroups = []; this.source = ""; this.strict = Boolean(options && options.strict); this.ecmaVersion = options && options.ecmaVersion || 2018; } _createClass(RegExpParserState, [{ key: 'onFlags', value: function onFlags(start, end, global, ignoreCase, multiline, unicode, sticky, dotAll) { this._flags = { type: "Flags", parent: null, start: start, end: end, raw: this.source.slice(start, end), global: global, ignoreCase: ignoreCase, multiline: multiline, unicode: unicode, sticky: sticky, dotAll: dotAll }; } }, { key: 'onPatternEnter', value: function onPatternEnter(start) { this._node = { type: "Pattern", parent: null, start: start, end: start, raw: "", alternatives: [] }; this._backreferences.length = 0; this._capturingGroups.length = 0; } }, { key: 'onPatternLeave', value: function onPatternLeave(start, end) { var _this2 = this; this._node.end = end; this._node.raw = this.source.slice(start, end); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { var _loop = function _loop() { var reference = _step2.value; var ref = reference.ref; var group = typeof ref === "number" ? _this2._capturingGroups[ref - 1] : _this2._capturingGroups.find(function (g) { return g.name === ref; }); reference.resolved = group; group.references.push(reference); }; for (var _iterator2 = this._backreferences[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { _loop(); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } }, { key: 'onAlternativeEnter', value: function onAlternativeEnter(start) { var parent = this._node; if (parent.type !== "Assertion" && parent.type !== "CapturingGroup" && parent.type !== "Group" && parent.type !== "Pattern") { throw new Error("UnknownError"); } this._node = { type: "Alternative", parent: parent, start: start, end: start, raw: "", elements: [] }; parent.alternatives.push(this._node); } }, { key: 'onAlternativeLeave', value: function onAlternativeLeave(start, end) { var node = this._node; if (node.type !== "Alternative") { throw new Error("UnknownError"); } node.end = end; node.raw = this.source.slice(start, end); this._node = node.parent; } }, { key: 'onGroupEnter', value: function onGroupEnter(start) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } this._node = { type: "Group", parent: parent, start: start, end: start, raw: "", alternatives: [] }; parent.elements.push(this._node); } }, { key: 'onGroupLeave', value: function onGroupLeave(start, end) { var node = this._node; if (node.type !== "Group" || node.parent.type !== "Alternative") { throw new Error("UnknownError"); } node.end = end; node.raw = this.source.slice(start, end); this._node = node.parent; } }, { key: 'onCapturingGroupEnter', value: function onCapturingGroupEnter(start, name) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } this._node = { type: "CapturingGroup", parent: parent, start: start, end: start, raw: "", name: name, alternatives: [], references: [] }; parent.elements.push(this._node); this._capturingGroups.push(this._node); } }, { key: 'onCapturingGroupLeave', value: function onCapturingGroupLeave(start, end) { var node = this._node; if (node.type !== "CapturingGroup" || node.parent.type !== "Alternative") { throw new Error("UnknownError"); } node.end = end; node.raw = this.source.slice(start, end); this._node = node.parent; } }, { key: 'onQuantifier', value: function onQuantifier(start, end, min, max, greedy) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } var element = parent.elements.pop(); if (element == null || element.type === "Quantifier" || element.type === "Assertion" && element.kind !== "lookahead") { throw new Error("UnknownError"); } var node = { type: "Quantifier", parent: parent, start: element.start, end: end, raw: this.source.slice(element.start, end), min: min, max: max, greedy: greedy, element: element }; parent.elements.push(node); element.parent = node; } }, { key: 'onLookaroundAssertionEnter', value: function onLookaroundAssertionEnter(start, kind, negate) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } this._node = { type: "Assertion", parent: parent, start: start, end: start, raw: "", kind: kind, negate: negate, alternatives: [] }; parent.elements.push(this._node); } }, { key: 'onLookaroundAssertionLeave', value: function onLookaroundAssertionLeave(start, end) { var node = this._node; if (node.type !== "Assertion" || node.parent.type !== "Alternative") { throw new Error("UnknownError"); } node.end = end; node.raw = this.source.slice(start, end); this._node = node.parent; } }, { key: 'onEdgeAssertion', value: function onEdgeAssertion(start, end, kind) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } parent.elements.push({ type: "Assertion", parent: parent, start: start, end: end, raw: this.source.slice(start, end), kind: kind }); } }, { key: 'onWordBoundaryAssertion', value: function onWordBoundaryAssertion(start, end, kind, negate) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } parent.elements.push({ type: "Assertion", parent: parent, start: start, end: end, raw: this.source.slice(start, end), kind: kind, negate: negate }); } }, { key: 'onAnyCharacterSet', value: function onAnyCharacterSet(start, end, kind) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } parent.elements.push({ type: "CharacterSet", parent: parent, start: start, end: end, raw: this.source.slice(start, end), kind: kind }); } }, { key: 'onEscapeCharacterSet', value: function onEscapeCharacterSet(start, end, kind, negate) { var parent = this._node; if (parent.type !== "Alternative" && parent.type !== "CharacterClass") { throw new Error("UnknownError"); } parent.elements.push({ type: "CharacterSet", parent: parent, start: start, end: end, raw: this.source.slice(start, end), kind: kind, negate: negate }); } }, { key: 'onUnicodePropertyCharacterSet', value: function onUnicodePropertyCharacterSet(start, end, kind, key, value, negate) { var parent = this._node; if (parent.type !== "Alternative" && parent.type !== "CharacterClass") { throw new Error("UnknownError"); } parent.elements.push({ type: "CharacterSet", parent: parent, start: start, end: end, raw: this.source.slice(start, end), kind: kind, key: key, value: value, negate: negate }); } }, { key: 'onCharacter', value: function onCharacter(start, end, value) { var parent = this._node; if (parent.type !== "Alternative" && parent.type !== "CharacterClass") { throw new Error("UnknownError"); } parent.elements.push({ type: "Character", parent: parent, start: start, end: end, raw: this.source.slice(start, end), value: value }); } }, { key: 'onBackreference', value: function onBackreference(start, end, ref) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } var node = { type: "Backreference", parent: parent, start: start, end: end, raw: this.source.slice(start, end), ref: ref, resolved: DummyCapturingGroup }; parent.elements.push(node); this._backreferences.push(node); } }, { key: 'onCharacterClassEnter', value: function onCharacterClassEnter(start, negate) { var parent = this._node; if (parent.type !== "Alternative") { throw new Error("UnknownError"); } this._node = { type: "CharacterClass", parent: parent, start: start, end: start, raw: "", negate: negate, elements: [] }; parent.elements.push(this._node); } }, { key: 'onCharacterClassLeave', value: function onCharacterClassLeave(start, end) { var node = this._node; if (node.type !== "CharacterClass" || node.parent.type !== "Alternative") { throw new Error("UnknownError"); } node.end = end; node.raw = this.source.slice(start, end); this._node = node.parent; } }, { key: 'onCharacterClassRange', value: function onCharacterClassRange(start, end) { var parent = this._node; if (parent.type !== "CharacterClass") { throw new Error("UnknownError"); } var elements = parent.elements; var max = elements.pop(); var hyphen = elements.pop(); var min = elements.pop(); if (!min || !max || !hyphen || min.type !== "Character" || max.type !== "Character" || hyphen.type !== "Character" || hyphen.value !== HyphenMinus) { throw new Error("UnknownError"); } var node = { type: "CharacterClassRange", parent: parent, start: start, end: end, raw: this.source.slice(start, end), min: min, max: max }; min.parent = node; max.parent = node; elements.push(node); } }, { key: 'pattern', get: function get() { if (this._node.type !== "Pattern") { throw new Error("UnknownError"); } return this._node; } }, { key: 'flags', get: function get() { if (this._flags.type !== "Flags") { throw new Error("UnknownError"); } return this._flags; } }]); return RegExpParserState; }(); var RegExpParser = function () { function RegExpParser(options) { _classCallCheck(this, RegExpParser); this._state = new RegExpParserState(options); this._validator = new RegExpValidator(this._state); } _createClass(RegExpParser, [{ key: 'parseLiteral', value: function parseLiteral(source) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source.length; this._state.source = source; this._validator.validateLiteral(source, start, end); var pattern = this._state.pattern; var flags = this._state.flags; var literal = { type: "RegExpLiteral", parent: null, start: start, end: end, raw: source, pattern: pattern, flags: flags }; pattern.parent = literal; flags.parent = literal; return literal; } }, { key: 'parseFlags', value: function parseFlags(source) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source.length; this._state.source = source; this._validator.validateFlags(source, start, end); return this._state.flags; } }, { key: 'parsePattern', value: function parsePattern(source) { var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : source.length; var uFlag = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; this._state.source = source; this._validator.validatePattern(source, start, end, uFlag); return this._state.pattern; } }]); return RegExpParser; }(); var RegExpVisitor = function () { function RegExpVisitor(handlers) { _classCallCheck(this, RegExpVisitor); this._handlers = handlers; } _createClass(RegExpVisitor, [{ key: 'visit', value: function visit(node) { switch (node.type) { case "Alternative": this.visitAlternative(node); break; case "Assertion": this.visitAssertion(node); break; case "Backreference": this.visitBackreference(node); break; case "CapturingGroup": this.visitCapturingGroup(node); break; case "Character": this.visitCharacter(node); break; case "CharacterClass": this.visitCharacterClass(node); break; case "CharacterClassRange": this.visitCharacterClassRange(node); break; case "CharacterSet": this.visitCharacterSet(node); break; case "Flags": this.visitFlags(node); break; case "Group": this.visitGroup(node); break; case "Pattern": this.visitPattern(node); break; case "Quantifier": this.visitQuantifier(node); break; case "RegExpLiteral": this.visitRegExpLiteral(node); break; default: throw new Error('Unknown type: ' + node.type); } } }, { key: 'visitAlternative', value: function visitAlternative(node) { if (this._handlers.onAlternativeEnter) { this._handlers.onAlternativeEnter(node); } node.elements.forEach(this.visit, this); if (this._handlers.onAlternativeLeave) { this._handlers.onAlternativeLeave(node); } } }, { key: 'visitAssertion', value: function visitAssertion(node) { if (this._handlers.onAssertionEnter) { this._handlers.onAssertionEnter(node); } if (node.kind === "lookahead" || node.kind === "lookbehind") { node.alternatives.forEach(this.visit, this); } if (this._handlers.onAssertionLeave) { this._handlers.onAssertionLeave(node); } } }, { key: 'visitBackreference', value: function visitBackreference(node) { if (this._handlers.onBackreferenceEnter) { this._handlers.onBackreferenceEnter(node); } if (this._handlers.onBackreferenceLeave) { this._handlers.onBackreferenceLeave(node); } } }, { key: 'visitCapturingGroup', value: function visitCapturingGroup(node) { if (this._handlers.onCapturingGroupEnter) { this._handlers.onCapturingGroupEnter(node); } node.alternatives.forEach(this.visit, this); if (this._handlers.onCapturingGroupLeave) { this._handlers.onCapturingGroupLeave(node); } } }, { key: 'visitCharacter', value: function visitCharacter(node) { if (this._handlers.onCharacterEnter) { this._handlers.onCharacterEnter(node); } if (this._handlers.onCharacterLeave) { this._handlers.onCharacterLeave(node); } } }, { key: 'visitCharacterClass', value: function visitCharacterClass(node) { if (this._handlers.onCharacterClassEnter) { this._handlers.onCharacterClassEnter(node); } node.elements.forEach(this.visit, this); if (this._handlers.onCharacterClassLeave) { this._handlers.onCharacterClassLeave(node); } } }, { key: 'visitCharacterClassRange', value: function visitCharacterClassRange(node) { if (this._handlers.onCharacterClassRangeEnter) { this._handlers.onCharacterClassRangeEnter(node); } this.visitCharacter(node.min); this.visitCharacter(node.max); if (this._handlers.onCharacterClassRangeLeave) { this._handlers.onCharacterClassRangeLeave(node); } } }, { key: 'visitCharacterSet', value: function visitCharacterSet(node) { if (this._handlers.onCharacterSetEnter) { this._handlers.onCharacterSetEnter(node); } if (this._handlers.onCharacterSetLeave) { this._handlers.onCharacterSetLeave(node); } } }, { key: 'visitFlags', value: function visitFlags(node) { if (this._handlers.onFlagsEnter) { this._handlers.onFlagsEnter(node); } if (this._handlers.onFlagsLeave) { this._handlers.onFlagsLeave(node); } } }, { key: 'visitGroup', value: function visitGroup(node) { if (this._handlers.onGroupEnter) { this._handlers.onGroupEnter(node); } node.alternatives.forEach(this.visit, this); if (this._handlers.onGroupLeave) { this._handlers.onGroupLeave(node); } } }, { key: 'visitPattern', value: function visitPattern(node) { if (this._handlers.onPatternEnter) { this._handlers.onPatternEnter(node); } node.alternatives.forEach(this.visit, this); if (this._handlers.onPatternLeave) { this._handlers.onPatternLeave(node); } } }, { key: 'visitQuantifier', value: function visitQuantifier(node) { if (this._handlers.onQuantifierEnter) { this._handlers.onQuantifierEnter(node); } this.visit(node.element); if (this._handlers.onQuantifierLeave) { this._handlers.onQuantifierLeave(node); } } }, { key: 'visitRegExpLiteral', value: function visitRegExpLiteral(node) { if (this._handlers.onRegExpLiteralEnter) { this._handlers.onRegExpLiteralEnter(node); } this.visitPattern(node.pattern); this.visitFlags(node.flags); if (this._handlers.onRegExpLiteralLeave) { this._handlers.onRegExpLiteralLeave(node); } } }]); return RegExpVisitor; }(); function parseRegExpLiteral(source, options) { return new RegExpParser(options).parseLiteral(String(source)); } function validateRegExpLiteral(source, options) { return new RegExpValidator(options).validateLiteral(source); } function visitRegExpAST(node, handlers) { new RegExpVisitor(handlers).visit(node); } exports.AST = ast; exports.RegExpParser = RegExpParser; exports.RegExpValidator = RegExpValidator; exports.parseRegExpLiteral = parseRegExpLiteral; exports.validateRegExpLiteral = validateRegExpLiteral; exports.visitRegExpAST = visitRegExpAST; },{}],105:[function(require,module,exports){ 'use strict'; // Generated by LiveScript 1.4.0 (function () { var ref$, any, all, isItNaN, types, defaultType, customTypes, toString$ = {}.toString; ref$ = require('prelude-ls'), any = ref$.any, all = ref$.all, isItNaN = ref$.isItNaN; types = { Number: { typeOf: 'Number', validate: function validate(it) { return !isItNaN(it); } }, NaN: { typeOf: 'Number', validate: isItNaN }, Int: { typeOf: 'Number', validate: function validate(it) { return !isItNaN(it) && it % 1 === 0; } }, Float: { typeOf: 'Number', validate: function validate(it) { return !isItNaN(it); } }, Date: { typeOf: 'Date', validate: function validate(it) { return !isItNaN(it.getTime()); } } }; defaultType = { array: 'Array', tuple: 'Array' }; function checkArray(input, type) { return all(function (it) { return checkMultiple(it, type.of); }, input); } function checkTuple(input, type) { var i, i$, ref$, len$, types; i = 0; for (i$ = 0, len$ = (ref$ = type.of).length; i$ < len$; ++i$) { types = ref$[i$]; if (!checkMultiple(input[i], types)) { return false; } i++; } return input.length <= i; } function checkFields(input, type) { var inputKeys, numInputKeys, k, numOfKeys, key, ref$, types; inputKeys = {}; numInputKeys = 0; for (k in input) { inputKeys[k] = true; numInputKeys++; } numOfKeys = 0; for (key in ref$ = type.of) { types = ref$[key]; if (!checkMultiple(input[key], types)) { return false; } if (inputKeys[key]) { numOfKeys++; } } return type.subset || numInputKeys === numOfKeys; } function checkStructure(input, type) { if (!(input instanceof Object)) { return false; } switch (type.structure) { case 'fields': return checkFields(input, type); case 'array': return checkArray(input, type); case 'tuple': return checkTuple(input, type); } } function check(input, typeObj) { var type, structure, setting, that; type = typeObj.type, structure = typeObj.structure; if (type) { if (type === '*') { return true; } setting = customTypes[type] || types[type]; if (setting) { return setting.typeOf === toString$.call(input).slice(8, -1) && setting.validate(input); } else { return type === toString$.call(input).slice(8, -1) && (!structure || checkStructure(input, typeObj)); } } else if (structure) { if (that = defaultType[structure]) { if (that !== toString$.call(input).slice(8, -1)) { return false; } } return checkStructure(input, typeObj); } else { throw new Error("No type defined. Input: " + input + "."); } } function checkMultiple(input, types) { if (toString$.call(types).slice(8, -1) !== 'Array') { throw new Error("Types must be in an array. Input: " + input + "."); } return any(function (it) { return check(input, it); }, types); } module.exports = function (parsedType, input, options) { options == null && (options = {}); customTypes = options.customTypes || {}; return checkMultiple(input, parsedType); }; }).call(undefined); },{"prelude-ls":102}],106:[function(require,module,exports){ 'use strict'; // Generated by LiveScript 1.4.0 (function () { var VERSION, parseType, parsedTypeCheck, typeCheck; VERSION = '0.3.2'; parseType = require('./parse-type'); parsedTypeCheck = require('./check'); typeCheck = function typeCheck(type, input, options) { return parsedTypeCheck(parseType(type), input, options); }; module.exports = { VERSION: VERSION, typeCheck: typeCheck, parsedTypeCheck: parsedTypeCheck, parseType: parseType }; }).call(undefined); },{"./check":105,"./parse-type":107}],107:[function(require,module,exports){ "use strict"; // Generated by LiveScript 1.4.0 (function () { var identifierRegex, tokenRegex; identifierRegex = /[\$\w]+/; function peek(tokens) { var token; token = tokens[0]; if (token == null) { throw new Error('Unexpected end of input.'); } return token; } function consumeIdent(tokens) { var token; token = peek(tokens); if (!identifierRegex.test(token)) { throw new Error("Expected text, got '" + token + "' instead."); } return tokens.shift(); } function consumeOp(tokens, op) { var token; token = peek(tokens); if (token !== op) { throw new Error("Expected '" + op + "', got '" + token + "' instead."); } return tokens.shift(); } function maybeConsumeOp(tokens, op) { var token; token = tokens[0]; if (token === op) { return tokens.shift(); } else { return null; } } function consumeArray(tokens) { var types; consumeOp(tokens, '['); if (peek(tokens) === ']') { throw new Error("Must specify type of Array - eg. [Type], got [] instead."); } types = consumeTypes(tokens); consumeOp(tokens, ']'); return { structure: 'array', of: types }; } function consumeTuple(tokens) { var components; components = []; consumeOp(tokens, '('); if (peek(tokens) === ')') { throw new Error("Tuple must be of at least length 1 - eg. (Type), got () instead."); } for (;;) { components.push(consumeTypes(tokens)); maybeConsumeOp(tokens, ','); if (')' === peek(tokens)) { break; } } consumeOp(tokens, ')'); return { structure: 'tuple', of: components }; } function consumeFields(tokens) { var fields, subset, ref$, key, types; fields = {}; consumeOp(tokens, '{'); subset = false; for (;;) { if (maybeConsumeOp(tokens, '...')) { subset = true; break; } ref$ = consumeField(tokens), key = ref$[0], types = ref$[1]; fields[key] = types; maybeConsumeOp(tokens, ','); if ('}' === peek(tokens)) { break; } } consumeOp(tokens, '}'); return { structure: 'fields', of: fields, subset: subset }; } function consumeField(tokens) { var key, types; key = consumeIdent(tokens); consumeOp(tokens, ':'); types = consumeTypes(tokens); return [key, types]; } function maybeConsumeStructure(tokens) { switch (tokens[0]) { case '[': return consumeArray(tokens); case '(': return consumeTuple(tokens); case '{': return consumeFields(tokens); } } function consumeType(tokens) { var token, wildcard, type, structure; token = peek(tokens); wildcard = token === '*'; if (wildcard || identifierRegex.test(token)) { type = wildcard ? consumeOp(tokens, '*') : consumeIdent(tokens); structure = maybeConsumeStructure(tokens); if (structure) { return structure.type = type, structure; } else { return { type: type }; } } else { structure = maybeConsumeStructure(tokens); if (!structure) { throw new Error("Unexpected character: " + token); } return structure; } } function consumeTypes(tokens) { var lookahead, types, typesSoFar, typeObj, type; if ('::' === peek(tokens)) { throw new Error("No comment before comment separator '::' found."); } lookahead = tokens[1]; if (lookahead != null && lookahead === '::') { tokens.shift(); tokens.shift(); } types = []; typesSoFar = {}; if ('Maybe' === peek(tokens)) { tokens.shift(); types = [{ type: 'Undefined' }, { type: 'Null' }]; typesSoFar = { Undefined: true, Null: true }; } for (;;) { typeObj = consumeType(tokens), type = typeObj.type; if (!typesSoFar[type]) { types.push(typeObj); } typesSoFar[type] = true; if (!maybeConsumeOp(tokens, '|')) { break; } } return types; } tokenRegex = RegExp('\\.\\.\\.|::|->|' + identifierRegex.source + '|\\S', 'g'); module.exports = function (input) { var tokens, e; if (!input.length) { throw new Error('No type specified.'); } tokens = input.match(tokenRegex) || []; if (in$('->', tokens)) { throw new Error("Function types are not supported.\ To validate that something is a function, you may use 'Function'."); } try { return consumeTypes(tokens); } catch (e$) { e = e$; throw new Error(e.message + " - Remaining tokens: " + JSON.stringify(tokens) + " - Initial input: '" + input + "'"); } }; function in$(x, xs) { var i = -1, l = xs.length >>> 0; while (++i < l) { if (x === xs[i]) return true; }return false; } }).call(undefined); },{}],108:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** @license URI.js v4.2.1 (c) 2011 Gary Court. License: http://github.com/garycourt/uri-js */ (function (global, factory) { (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : factory(global.URI = global.URI || {}); })(undefined, function (exports) { 'use strict'; function merge() { for (var _len = arguments.length, sets = Array(_len), _key = 0; _key < _len; _key++) { sets[_key] = arguments[_key]; } if (sets.length > 1) { sets[0] = sets[0].slice(0, -1); var xl = sets.length - 1; for (var x = 1; x < xl; ++x) { sets[x] = sets[x].slice(1, -1); } sets[xl] = sets[xl].slice(1); return sets.join(''); } else { return sets[0]; } } function subexp(str) { return "(?:" + str + ")"; } function typeOf(o) { return o === undefined ? "undefined" : o === null ? "null" : Object.prototype.toString.call(o).split(" ").pop().split("]").shift().toLowerCase(); } function toUpperCase(str) { return str.toUpperCase(); } function toArray(obj) { return obj !== undefined && obj !== null ? obj instanceof Array ? obj : typeof obj.length !== "number" || obj.split || obj.setInterval || obj.call ? [obj] : Array.prototype.slice.call(obj) : []; } function assign(target, source) { var obj = target; if (source) { for (var key in source) { obj[key] = source[key]; } } return obj; } function buildExps(isIRI) { var ALPHA$$ = "[A-Za-z]", CR$ = "[\\x0D]", DIGIT$$ = "[0-9]", DQUOTE$$ = "[\\x22]", HEXDIG$$ = merge(DIGIT$$, "[A-Fa-f]"), //case-insensitive LF$$ = "[\\x0A]", SP$$ = "[\\x20]", PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)), //expanded GEN_DELIMS$$ = "[\\:\\/\\?\\#\\[\\]\\@]", SUB_DELIMS$$ = "[\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=]", RESERVED$$ = merge(GEN_DELIMS$$, SUB_DELIMS$$), UCSCHAR$$ = isIRI ? '[\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]' : "[]", //subset, excludes bidi control characters IPRIVATE$$ = isIRI ? '[\\uE000-\\uF8FF]' : "[]", //subset UNRESERVED$$ = merge(ALPHA$$, DIGIT$$, "[\\-\\.\\_\\~]", UCSCHAR$$), SCHEME$ = subexp(ALPHA$$ + merge(ALPHA$$, DIGIT$$, "[\\+\\-\\.]") + "*"), USERINFO$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]")) + "*"), DEC_OCTET$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("[1-9]" + DIGIT$$) + "|" + DIGIT$$), DEC_OCTET_RELAXED$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("0?[1-9]" + DIGIT$$) + "|0?0?" + DIGIT$$), //relaxed parsing rules IPV4ADDRESS$ = subexp(DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$), H16$ = subexp(HEXDIG$$ + "{1,4}"), LS32$ = subexp(subexp(H16$ + "\\:" + H16$) + "|" + IPV4ADDRESS$), IPV6ADDRESS1$ = subexp(subexp(H16$ + "\\:") + "{6}" + LS32$), // 6( h16 ":" ) ls32 IPV6ADDRESS2$ = subexp("\\:\\:" + subexp(H16$ + "\\:") + "{5}" + LS32$), // "::" 5( h16 ":" ) ls32 IPV6ADDRESS3$ = subexp(subexp(H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{4}" + LS32$), //[ h16 ] "::" 4( h16 ":" ) ls32 IPV6ADDRESS4$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,1}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{3}" + LS32$), //[ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 IPV6ADDRESS5$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,2}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{2}" + LS32$), //[ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 IPV6ADDRESS6$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,3}" + H16$) + "?\\:\\:" + H16$ + "\\:" + LS32$), //[ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 IPV6ADDRESS7$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,4}" + H16$) + "?\\:\\:" + LS32$), //[ *4( h16 ":" ) h16 ] "::" ls32 IPV6ADDRESS8$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,5}" + H16$) + "?\\:\\:" + H16$), //[ *5( h16 ":" ) h16 ] "::" h16 IPV6ADDRESS9$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,6}" + H16$) + "?\\:\\:"), //[ *6( h16 ":" ) h16 ] "::" IPV6ADDRESS$ = subexp([IPV6ADDRESS1$, IPV6ADDRESS2$, IPV6ADDRESS3$, IPV6ADDRESS4$, IPV6ADDRESS5$, IPV6ADDRESS6$, IPV6ADDRESS7$, IPV6ADDRESS8$, IPV6ADDRESS9$].join("|")), ZONEID$ = subexp(subexp(UNRESERVED$$ + "|" + PCT_ENCODED$) + "+"), //RFC 6874 IPV6ADDRZ$ = subexp(IPV6ADDRESS$ + "\\%25" + ZONEID$), //RFC 6874 IPV6ADDRZ_RELAXED$ = subexp(IPV6ADDRESS$ + subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + ZONEID$), //RFC 6874, with relaxed parsing rules IPVFUTURE$ = subexp("[vV]" + HEXDIG$$ + "+\\." + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]") + "+"), IP_LITERAL$ = subexp("\\[" + subexp(IPV6ADDRZ_RELAXED$ + "|" + IPV6ADDRESS$ + "|" + IPVFUTURE$) + "\\]"), //RFC 6874 REG_NAME$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$)) + "*"), HOST$ = subexp(IP_LITERAL$ + "|" + IPV4ADDRESS$ + "(?!" + REG_NAME$ + ")" + "|" + REG_NAME$), PORT$ = subexp(DIGIT$$ + "*"), AUTHORITY$ = subexp(subexp(USERINFO$ + "@") + "?" + HOST$ + subexp("\\:" + PORT$) + "?"), PCHAR$ = subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@]")), SEGMENT$ = subexp(PCHAR$ + "*"), SEGMENT_NZ$ = subexp(PCHAR$ + "+"), SEGMENT_NZ_NC$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\@]")) + "+"), PATH_ABEMPTY$ = subexp(subexp("\\/" + SEGMENT$) + "*"), PATH_ABSOLUTE$ = subexp("\\/" + subexp(SEGMENT_NZ$ + PATH_ABEMPTY$) + "?"), //simplified PATH_NOSCHEME$ = subexp(SEGMENT_NZ_NC$ + PATH_ABEMPTY$), //simplified PATH_ROOTLESS$ = subexp(SEGMENT_NZ$ + PATH_ABEMPTY$), //simplified PATH_EMPTY$ = "(?!" + PCHAR$ + ")", PATH$ = subexp(PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), QUERY$ = subexp(subexp(PCHAR$ + "|" + merge("[\\/\\?]", IPRIVATE$$)) + "*"), FRAGMENT$ = subexp(subexp(PCHAR$ + "|[\\/\\?]") + "*"), HIER_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), RELATIVE_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$), RELATIVE$ = subexp(RELATIVE_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), URI_REFERENCE$ = subexp(URI$ + "|" + RELATIVE$), ABSOLUTE_URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?"), GENERIC_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", RELATIVE_REF$ = "^(){0}" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", ABSOLUTE_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?$", SAMEDOC_REF$ = "^" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", AUTHORITY_REF$ = "^" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?$"; return { NOT_SCHEME: new RegExp(merge("[^]", ALPHA$$, DIGIT$$, "[\\+\\-\\.]"), "g"), NOT_USERINFO: new RegExp(merge("[^\\%\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_HOST: new RegExp(merge("[^\\%\\[\\]\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_PATH: new RegExp(merge("[^\\%\\/\\:\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_PATH_NOSCHEME: new RegExp(merge("[^\\%\\/\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"), NOT_QUERY: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]", IPRIVATE$$), "g"), NOT_FRAGMENT: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]"), "g"), ESCAPE: new RegExp(merge("[^]", UNRESERVED$$, SUB_DELIMS$$), "g"), UNRESERVED: new RegExp(UNRESERVED$$, "g"), OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$, RESERVED$$), "g"), PCT_ENCODED: new RegExp(PCT_ENCODED$, "g"), IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"), IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$") //RFC 6874, with relaxed parsing rules }; } var URI_PROTOCOL = buildExps(false); var IRI_PROTOCOL = buildExps(true); var slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var toConsumableArray = function toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; }return arr2; } else { return Array.from(arr); } }; /** Highest positive signed 32-bit float value */ var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ var base = 36; var tMin = 1; var tMax = 26; var skew = 38; var damp = 700; var initialBias = 72; var initialN = 128; // 0x80 var delimiter = '-'; // '\x2D' /** Regular expressions */ var regexPunycode = /^xn--/; var regexNonASCII = /[^\0-\x7E]/; // non-ASCII chars var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators /** Error messages */ var errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }; /** Convenience shortcuts */ var baseMinusTMin = base - tMin; var floor = Math.floor; var stringFromCharCode = String.fromCharCode; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error$1(type) { throw new RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var result = []; var length = array.length; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = []; var counter = 0; var length = string.length; while (counter < length) { var value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // It's a high surrogate, and there is a next character. var extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // It's an unmatched surrogate; only append this code unit, in case the // next code unit is the high surrogate of a surrogate pair. output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ var ucs2encode = function ucs2encode(array) { return String.fromCodePoint.apply(String, toConsumableArray(array)); }; /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ var basicToDigit = function basicToDigit(codePoint) { if (codePoint - 0x30 < 0x0A) { return codePoint - 0x16; } if (codePoint - 0x41 < 0x1A) { return codePoint - 0x41; } if (codePoint - 0x61 < 0x1A) { return codePoint - 0x61; } return base; }; /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ var digitToBasic = function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); }; /** * Bias adaptation function as per section 3.4 of RFC 3492. * https://tools.ietf.org/html/rfc3492#section-3.4 * @private */ var adapt = function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (; /* no initialization */delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); }; /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ var decode = function decode(input) { // Don't use UCS-2. var output = []; var inputLength = input.length; var i = 0; var n = initialN; var bias = initialBias; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. var basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (var j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error$1('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (var index = basic > 0 ? basic + 1 : 0; index < inputLength;) /* no final expression */{ // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. var oldi = i; for (var w = 1, k = base;; /* no condition */k += base) { if (index >= inputLength) { error$1('invalid-input'); } var digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error$1('overflow'); } i += digit * w; var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; if (digit < t) { break; } var baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error$1('overflow'); } w *= baseMinusT; } var out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error$1('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output. output.splice(i++, 0, n); } return String.fromCodePoint.apply(String, output); }; /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ var encode = function encode(input) { var output = []; // Convert the input in UCS-2 to an array of Unicode code points. input = ucs2decode(input); // Cache the length. var inputLength = input.length; // Initialize the state. var n = initialN; var delta = 0; var bias = initialBias; // Handle the basic code points. var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = input[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _currentValue2 = _step.value; if (_currentValue2 < 0x80) { output.push(stringFromCharCode(_currentValue2)); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var basicLength = output.length; var handledCPCount = basicLength; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string with a delimiter unless it's empty. if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: var m = maxInt; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = input[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var currentValue = _step2.value; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow. } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } var handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error$1('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = input[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _currentValue = _step3.value; if (_currentValue < n && ++delta > maxInt) { error$1('overflow'); } if (_currentValue == n) { // Represent delta as a generalized variable-length integer. var q = delta; for (var k = base;; /* no condition */k += base) { var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; if (q < t) { break; } var qMinusT = q - t; var baseMinusT = base - t; output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } ++delta; ++n; } return output.join(''); }; /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ var toUnicode = function toUnicode(input) { return mapDomain(input, function (string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); }; /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ var toASCII = function toASCII(input) { return mapDomain(input, function (string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); }; /*--------------------------------------------------------------------------*/ /** Define the public API */ var punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '2.1.0', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** * URI.js * * @fileoverview An RFC 3986 compliant, scheme extendable URI parsing/validating/resolving library for JavaScript. * @author Gary Court * @see http://github.com/garycourt/uri-js */ /** * Copyright 2011 Gary Court. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY GARY COURT ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of Gary Court. */ var SCHEMES = {}; function pctEncChar(chr) { var c = chr.charCodeAt(0); var e = void 0; if (c < 16) e = "%0" + c.toString(16).toUpperCase();else if (c < 128) e = "%" + c.toString(16).toUpperCase();else if (c < 2048) e = "%" + (c >> 6 | 192).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase();else e = "%" + (c >> 12 | 224).toString(16).toUpperCase() + "%" + (c >> 6 & 63 | 128).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase(); return e; } function pctDecChars(str) { var newStr = ""; var i = 0; var il = str.length; while (i < il) { var c = parseInt(str.substr(i + 1, 2), 16); if (c < 128) { newStr += String.fromCharCode(c); i += 3; } else if (c >= 194 && c < 224) { if (il - i >= 6) { var c2 = parseInt(str.substr(i + 4, 2), 16); newStr += String.fromCharCode((c & 31) << 6 | c2 & 63); } else { newStr += str.substr(i, 6); } i += 6; } else if (c >= 224) { if (il - i >= 9) { var _c = parseInt(str.substr(i + 4, 2), 16); var c3 = parseInt(str.substr(i + 7, 2), 16); newStr += String.fromCharCode((c & 15) << 12 | (_c & 63) << 6 | c3 & 63); } else { newStr += str.substr(i, 9); } i += 9; } else { newStr += str.substr(i, 3); i += 3; } } return newStr; } function _normalizeComponentEncoding(components, protocol) { function decodeUnreserved(str) { var decStr = pctDecChars(str); return !decStr.match(protocol.UNRESERVED) ? str : decStr; } if (components.scheme) components.scheme = String(components.scheme).replace(protocol.PCT_ENCODED, decodeUnreserved).toLowerCase().replace(protocol.NOT_SCHEME, ""); if (components.userinfo !== undefined) components.userinfo = String(components.userinfo).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_USERINFO, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.host !== undefined) components.host = String(components.host).replace(protocol.PCT_ENCODED, decodeUnreserved).toLowerCase().replace(protocol.NOT_HOST, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.path !== undefined) components.path = String(components.path).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(components.scheme ? protocol.NOT_PATH : protocol.NOT_PATH_NOSCHEME, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.query !== undefined) components.query = String(components.query).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_QUERY, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); if (components.fragment !== undefined) components.fragment = String(components.fragment).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_FRAGMENT, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); return components; } function _stripLeadingZeros(str) { return str.replace(/^0*(.*)/, "$1") || "0"; } function _normalizeIPv4(host, protocol) { var matches = host.match(protocol.IPV4ADDRESS) || []; var _matches = slicedToArray(matches, 2), address = _matches[1]; if (address) { return address.split(".").map(_stripLeadingZeros).join("."); } else { return host; } } function _normalizeIPv6(host, protocol) { var matches = host.match(protocol.IPV6ADDRESS) || []; var _matches2 = slicedToArray(matches, 3), address = _matches2[1], zone = _matches2[2]; if (address) { var _address$toLowerCase$ = address.toLowerCase().split('::').reverse(), _address$toLowerCase$2 = slicedToArray(_address$toLowerCase$, 2), last = _address$toLowerCase$2[0], first = _address$toLowerCase$2[1]; var firstFields = first ? first.split(":").map(_stripLeadingZeros) : []; var lastFields = last.split(":").map(_stripLeadingZeros); var isLastFieldIPv4Address = protocol.IPV4ADDRESS.test(lastFields[lastFields.length - 1]); var fieldCount = isLastFieldIPv4Address ? 7 : 8; var lastFieldsStart = lastFields.length - fieldCount; var fields = Array(fieldCount); for (var x = 0; x < fieldCount; ++x) { fields[x] = firstFields[x] || lastFields[lastFieldsStart + x] || ''; } if (isLastFieldIPv4Address) { fields[fieldCount - 1] = _normalizeIPv4(fields[fieldCount - 1], protocol); } var allZeroFields = fields.reduce(function (acc, field, index) { if (!field || field === "0") { var lastLongest = acc[acc.length - 1]; if (lastLongest && lastLongest.index + lastLongest.length === index) { lastLongest.length++; } else { acc.push({ index: index, length: 1 }); } } return acc; }, []); var longestZeroFields = allZeroFields.sort(function (a, b) { return b.length - a.length; })[0]; var newHost = void 0; if (longestZeroFields && longestZeroFields.length > 1) { var newFirst = fields.slice(0, longestZeroFields.index); var newLast = fields.slice(longestZeroFields.index + longestZeroFields.length); newHost = newFirst.join(":") + "::" + newLast.join(":"); } else { newHost = fields.join(":"); } if (zone) { newHost += "%" + zone; } return newHost; } else { return host; } } var URI_PARSE = /^(?:([^:\/?#]+):)?(?:\/\/((?:([^\/?#@]*)@)?(\[[^\/?#\]]+\]|[^\/?#:]*)(?:\:(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i; var NO_MATCH_IS_UNDEFINED = "".match(/(){0}/)[1] === undefined; function parse(uriString) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var components = {}; var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL; if (options.reference === "suffix") uriString = (options.scheme ? options.scheme + ":" : "") + "//" + uriString; var matches = uriString.match(URI_PARSE); if (matches) { if (NO_MATCH_IS_UNDEFINED) { //store each component components.scheme = matches[1]; components.userinfo = matches[3]; components.host = matches[4]; components.port = parseInt(matches[5], 10); components.path = matches[6] || ""; components.query = matches[7]; components.fragment = matches[8]; //fix port number if (isNaN(components.port)) { components.port = matches[5]; } } else { //IE FIX for improper RegExp matching //store each component components.scheme = matches[1] || undefined; components.userinfo = uriString.indexOf("@") !== -1 ? matches[3] : undefined; components.host = uriString.indexOf("//") !== -1 ? matches[4] : undefined; components.port = parseInt(matches[5], 10); components.path = matches[6] || ""; components.query = uriString.indexOf("?") !== -1 ? matches[7] : undefined; components.fragment = uriString.indexOf("#") !== -1 ? matches[8] : undefined; //fix port number if (isNaN(components.port)) { components.port = uriString.match(/\/\/(?:.|\n)*\:(?:\/|\?|\#|$)/) ? matches[4] : undefined; } } if (components.host) { //normalize IP hosts components.host = _normalizeIPv6(_normalizeIPv4(components.host, protocol), protocol); } //determine reference type if (components.scheme === undefined && components.userinfo === undefined && components.host === undefined && components.port === undefined && !components.path && components.query === undefined) { components.reference = "same-document"; } else if (components.scheme === undefined) { components.reference = "relative"; } else if (components.fragment === undefined) { components.reference = "absolute"; } else { components.reference = "uri"; } //check for reference errors if (options.reference && options.reference !== "suffix" && options.reference !== components.reference) { components.error = components.error || "URI is not a " + options.reference + " reference."; } //find scheme handler var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()]; //check if scheme can't handle IRIs if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) { //if host component is a domain name if (components.host && (options.domainHost || schemeHandler && schemeHandler.domainHost)) { //convert Unicode IDN -> ASCII IDN try { components.host = punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()); } catch (e) { components.error = components.error || "Host's domain name can not be converted to ASCII via punycode: " + e; } } //convert IRI -> URI _normalizeComponentEncoding(components, URI_PROTOCOL); } else { //normalize encodings _normalizeComponentEncoding(components, protocol); } //perform scheme specific parsing if (schemeHandler && schemeHandler.parse) { schemeHandler.parse(components, options); } } else { components.error = components.error || "URI can not be parsed."; } return components; } function _recomposeAuthority(components, options) { var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL; var uriTokens = []; if (components.userinfo !== undefined) { uriTokens.push(components.userinfo); uriTokens.push("@"); } if (components.host !== undefined) { //normalize IP hosts, add brackets and escape zone separator for IPv6 uriTokens.push(_normalizeIPv6(_normalizeIPv4(String(components.host), protocol), protocol).replace(protocol.IPV6ADDRESS, function (_, $1, $2) { return "[" + $1 + ($2 ? "%25" + $2 : "") + "]"; })); } if (typeof components.port === "number") { uriTokens.push(":"); uriTokens.push(components.port.toString(10)); } return uriTokens.length ? uriTokens.join("") : undefined; } var RDS1 = /^\.\.?\//; var RDS2 = /^\/\.(\/|$)/; var RDS3 = /^\/\.\.(\/|$)/; var RDS5 = /^\/?(?:.|\n)*?(?=\/|$)/; function removeDotSegments(input) { var output = []; while (input.length) { if (input.match(RDS1)) { input = input.replace(RDS1, ""); } else if (input.match(RDS2)) { input = input.replace(RDS2, "/"); } else if (input.match(RDS3)) { input = input.replace(RDS3, "/"); output.pop(); } else if (input === "." || input === "..") { input = ""; } else { var im = input.match(RDS5); if (im) { var s = im[0]; input = input.slice(s.length); output.push(s); } else { throw new Error("Unexpected dot segment condition"); } } } return output.join(""); } function serialize(components) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var protocol = options.iri ? IRI_PROTOCOL : URI_PROTOCOL; var uriTokens = []; //find scheme handler var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()]; //perform scheme specific serialization if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(components, options); if (components.host) { //if host component is an IPv6 address if (protocol.IPV6ADDRESS.test(components.host)) {} //TODO: normalize IPv6 address as per RFC 5952 //if host component is a domain name else if (options.domainHost || schemeHandler && schemeHandler.domainHost) { //convert IDN via punycode try { components.host = !options.iri ? punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()) : punycode.toUnicode(components.host); } catch (e) { components.error = components.error || "Host's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e; } } } //normalize encoding _normalizeComponentEncoding(components, protocol); if (options.reference !== "suffix" && components.scheme) { uriTokens.push(components.scheme); uriTokens.push(":"); } var authority = _recomposeAuthority(components, options); if (authority !== undefined) { if (options.reference !== "suffix") { uriTokens.push("//"); } uriTokens.push(authority); if (components.path && components.path.charAt(0) !== "/") { uriTokens.push("/"); } } if (components.path !== undefined) { var s = components.path; if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) { s = removeDotSegments(s); } if (authority === undefined) { s = s.replace(/^\/\//, "/%2F"); //don't allow the path to start with "//" } uriTokens.push(s); } if (components.query !== undefined) { uriTokens.push("?"); uriTokens.push(components.query); } if (components.fragment !== undefined) { uriTokens.push("#"); uriTokens.push(components.fragment); } return uriTokens.join(""); //merge tokens into a string } function resolveComponents(base, relative) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var skipNormalization = arguments[3]; var target = {}; if (!skipNormalization) { base = parse(serialize(base, options), options); //normalize base components relative = parse(serialize(relative, options), options); //normalize relative components } options = options || {}; if (!options.tolerant && relative.scheme) { target.scheme = relative.scheme; //target.authority = relative.authority; target.userinfo = relative.userinfo; target.host = relative.host; target.port = relative.port; target.path = removeDotSegments(relative.path || ""); target.query = relative.query; } else { if (relative.userinfo !== undefined || relative.host !== undefined || relative.port !== undefined) { //target.authority = relative.authority; target.userinfo = relative.userinfo; target.host = relative.host; target.port = relative.port; target.path = removeDotSegments(relative.path || ""); target.query = relative.query; } else { if (!relative.path) { target.path = base.path; if (relative.query !== undefined) { target.query = relative.query; } else { target.query = base.query; } } else { if (relative.path.charAt(0) === "/") { target.path = removeDotSegments(relative.path); } else { if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) { target.path = "/" + relative.path; } else if (!base.path) { target.path = relative.path; } else { target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path; } target.path = removeDotSegments(target.path); } target.query = relative.query; } //target.authority = base.authority; target.userinfo = base.userinfo; target.host = base.host; target.port = base.port; } target.scheme = base.scheme; } target.fragment = relative.fragment; return target; } function resolve(baseURI, relativeURI, options) { var schemelessOptions = assign({ scheme: 'null' }, options); return serialize(resolveComponents(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true), schemelessOptions); } function normalize(uri, options) { if (typeof uri === "string") { uri = serialize(parse(uri, options), options); } else if (typeOf(uri) === "object") { uri = parse(serialize(uri, options), options); } return uri; } function equal(uriA, uriB, options) { if (typeof uriA === "string") { uriA = serialize(parse(uriA, options), options); } else if (typeOf(uriA) === "object") { uriA = serialize(uriA, options); } if (typeof uriB === "string") { uriB = serialize(parse(uriB, options), options); } else if (typeOf(uriB) === "object") { uriB = serialize(uriB, options); } return uriA === uriB; } function escapeComponent(str, options) { return str && str.toString().replace(!options || !options.iri ? URI_PROTOCOL.ESCAPE : IRI_PROTOCOL.ESCAPE, pctEncChar); } function unescapeComponent(str, options) { return str && str.toString().replace(!options || !options.iri ? URI_PROTOCOL.PCT_ENCODED : IRI_PROTOCOL.PCT_ENCODED, pctDecChars); } var handler = { scheme: "http", domainHost: true, parse: function parse(components, options) { //report missing host if (!components.host) { components.error = components.error || "HTTP URIs must have a host."; } return components; }, serialize: function serialize(components, options) { //normalize the default port if (components.port === (String(components.scheme).toLowerCase() !== "https" ? 80 : 443) || components.port === "") { components.port = undefined; } //normalize the empty path if (!components.path) { components.path = "/"; } //NOTE: We do not parse query strings for HTTP URIs //as WWW Form Url Encoded query strings are part of the HTML4+ spec, //and not the HTTP spec. return components; } }; var handler$1 = { scheme: "https", domainHost: handler.domainHost, parse: handler.parse, serialize: handler.serialize }; var O = {}; var isIRI = true; //RFC 3986 var UNRESERVED$$ = "[A-Za-z0-9\\-\\.\\_\\~" + (isIRI ? '\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF' : "") + "]"; var HEXDIG$$ = "[0-9A-Fa-f]"; //case-insensitive var PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)); //expanded //RFC 5322, except these symbols as per RFC 6068: @ : / ? # [ ] & ; = //const ATEXT$$ = "[A-Za-z0-9\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~]"; //const WSP$$ = "[\\x20\\x09]"; //const OBS_QTEXT$$ = "[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]"; //(%d1-8 / %d11-12 / %d14-31 / %d127) //const QTEXT$$ = merge("[\\x21\\x23-\\x5B\\x5D-\\x7E]", OBS_QTEXT$$); //%d33 / %d35-91 / %d93-126 / obs-qtext //const VCHAR$$ = "[\\x21-\\x7E]"; //const WSP$$ = "[\\x20\\x09]"; //const OBS_QP$ = subexp("\\\\" + merge("[\\x00\\x0D\\x0A]", OBS_QTEXT$$)); //%d0 / CR / LF / obs-qtext //const FWS$ = subexp(subexp(WSP$$ + "*" + "\\x0D\\x0A") + "?" + WSP$$ + "+"); //const QUOTED_PAIR$ = subexp(subexp("\\\\" + subexp(VCHAR$$ + "|" + WSP$$)) + "|" + OBS_QP$); //const QUOTED_STRING$ = subexp('\\"' + subexp(FWS$ + "?" + QCONTENT$) + "*" + FWS$ + "?" + '\\"'); var ATEXT$$ = "[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]"; var QTEXT$$ = "[\\!\\$\\%\\'\\(\\)\\*\\+\\,\\-\\.0-9\\<\\>A-Z\\x5E-\\x7E]"; var VCHAR$$ = merge(QTEXT$$, "[\\\"\\\\]"); var SOME_DELIMS$$ = "[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"; var UNRESERVED = new RegExp(UNRESERVED$$, "g"); var PCT_ENCODED = new RegExp(PCT_ENCODED$, "g"); var NOT_LOCAL_PART = new RegExp(merge("[^]", ATEXT$$, "[\\.]", '[\\"]', VCHAR$$), "g"); var NOT_HFNAME = new RegExp(merge("[^]", UNRESERVED$$, SOME_DELIMS$$), "g"); var NOT_HFVALUE = NOT_HFNAME; function decodeUnreserved(str) { var decStr = pctDecChars(str); return !decStr.match(UNRESERVED) ? str : decStr; } var handler$2 = { scheme: "mailto", parse: function parse$$1(components, options) { var mailtoComponents = components; var to = mailtoComponents.to = mailtoComponents.path ? mailtoComponents.path.split(",") : []; mailtoComponents.path = undefined; if (mailtoComponents.query) { var unknownHeaders = false; var headers = {}; var hfields = mailtoComponents.query.split("&"); for (var x = 0, xl = hfields.length; x < xl; ++x) { var hfield = hfields[x].split("="); switch (hfield[0]) { case "to": var toAddrs = hfield[1].split(","); for (var _x = 0, _xl = toAddrs.length; _x < _xl; ++_x) { to.push(toAddrs[_x]); } break; case "subject": mailtoComponents.subject = unescapeComponent(hfield[1], options); break; case "body": mailtoComponents.body = unescapeComponent(hfield[1], options); break; default: unknownHeaders = true; headers[unescapeComponent(hfield[0], options)] = unescapeComponent(hfield[1], options); break; } } if (unknownHeaders) mailtoComponents.headers = headers; } mailtoComponents.query = undefined; for (var _x2 = 0, _xl2 = to.length; _x2 < _xl2; ++_x2) { var addr = to[_x2].split("@"); addr[0] = unescapeComponent(addr[0]); if (!options.unicodeSupport) { //convert Unicode IDN -> ASCII IDN try { addr[1] = punycode.toASCII(unescapeComponent(addr[1], options).toLowerCase()); } catch (e) { mailtoComponents.error = mailtoComponents.error || "Email address's domain name can not be converted to ASCII via punycode: " + e; } } else { addr[1] = unescapeComponent(addr[1], options).toLowerCase(); } to[_x2] = addr.join("@"); } return mailtoComponents; }, serialize: function serialize$$1(mailtoComponents, options) { var components = mailtoComponents; var to = toArray(mailtoComponents.to); if (to) { for (var x = 0, xl = to.length; x < xl; ++x) { var toAddr = String(to[x]); var atIdx = toAddr.lastIndexOf("@"); var localPart = toAddr.slice(0, atIdx).replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_LOCAL_PART, pctEncChar); var domain = toAddr.slice(atIdx + 1); //convert IDN via punycode try { domain = !options.iri ? punycode.toASCII(unescapeComponent(domain, options).toLowerCase()) : punycode.toUnicode(domain); } catch (e) { components.error = components.error || "Email address's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e; } to[x] = localPart + "@" + domain; } components.path = to.join(","); } var headers = mailtoComponents.headers = mailtoComponents.headers || {}; if (mailtoComponents.subject) headers["subject"] = mailtoComponents.subject; if (mailtoComponents.body) headers["body"] = mailtoComponents.body; var fields = []; for (var name in headers) { if (headers[name] !== O[name]) { fields.push(name.replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFNAME, pctEncChar) + "=" + headers[name].replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFVALUE, pctEncChar)); } } if (fields.length) { components.query = fields.join("&"); } return components; } }; var URN_PARSE = /^([^\:]+)\:(.*)/; //RFC 2141 var handler$3 = { scheme: "urn", parse: function parse$$1(components, options) { var matches = components.path && components.path.match(URN_PARSE); var urnComponents = components; if (matches) { var scheme = options.scheme || urnComponents.scheme || "urn"; var nid = matches[1].toLowerCase(); var nss = matches[2]; var urnScheme = scheme + ":" + (options.nid || nid); var schemeHandler = SCHEMES[urnScheme]; urnComponents.nid = nid; urnComponents.nss = nss; urnComponents.path = undefined; if (schemeHandler) { urnComponents = schemeHandler.parse(urnComponents, options); } } else { urnComponents.error = urnComponents.error || "URN can not be parsed."; } return urnComponents; }, serialize: function serialize$$1(urnComponents, options) { var scheme = options.scheme || urnComponents.scheme || "urn"; var nid = urnComponents.nid; var urnScheme = scheme + ":" + (options.nid || nid); var schemeHandler = SCHEMES[urnScheme]; if (schemeHandler) { urnComponents = schemeHandler.serialize(urnComponents, options); } var uriComponents = urnComponents; var nss = urnComponents.nss; uriComponents.path = (nid || options.nid) + ":" + nss; return uriComponents; } }; var UUID = /^[0-9A-Fa-f]{8}(?:\-[0-9A-Fa-f]{4}){3}\-[0-9A-Fa-f]{12}$/; //RFC 4122 var handler$4 = { scheme: "urn:uuid", parse: function parse(urnComponents, options) { var uuidComponents = urnComponents; uuidComponents.uuid = uuidComponents.nss; uuidComponents.nss = undefined; if (!options.tolerant && (!uuidComponents.uuid || !uuidComponents.uuid.match(UUID))) { uuidComponents.error = uuidComponents.error || "UUID is not valid."; } return uuidComponents; }, serialize: function serialize(uuidComponents, options) { var urnComponents = uuidComponents; //normalize UUID urnComponents.nss = (uuidComponents.uuid || "").toLowerCase(); return urnComponents; } }; SCHEMES[handler.scheme] = handler; SCHEMES[handler$1.scheme] = handler$1; SCHEMES[handler$2.scheme] = handler$2; SCHEMES[handler$3.scheme] = handler$3; SCHEMES[handler$4.scheme] = handler$4; exports.SCHEMES = SCHEMES; exports.pctEncChar = pctEncChar; exports.pctDecChars = pctDecChars; exports.parse = parse; exports.removeDotSegments = removeDotSegments; exports.serialize = serialize; exports.resolveComponents = resolveComponents; exports.resolve = resolve; exports.normalize = normalize; exports.equal = equal; exports.escapeComponent = escapeComponent; exports.unescapeComponent = unescapeComponent; Object.defineProperty(exports, '__esModule', { value: true }); }); },{}],109:[function(require,module,exports){ arguments[4][48][0].apply(exports,arguments) },{"dup":48}],110:[function(require,module,exports){ arguments[4][49][0].apply(exports,arguments) },{"./support/isBuffer":109,"_process":103,"dup":49,"inherits":87}],111:[function(require,module,exports){ module.exports={ "name": "eslint", "version": "5.11.1", "author": "Nicholas C. Zakas ", "description": "An AST-based pattern checker for JavaScript.", "bin": { "eslint": "./bin/eslint.js" }, "main": "./lib/api.js", "scripts": { "test": "node Makefile.js test", "lint": "node Makefile.js lint", "fuzz": "node Makefile.js fuzz", "generate-release": "node Makefile.js generateRelease", "generate-alpharelease": "node Makefile.js generatePrerelease -- alpha", "generate-betarelease": "node Makefile.js generatePrerelease -- beta", "generate-rcrelease": "node Makefile.js generatePrerelease -- rc", "publish-release": "node Makefile.js publishRelease", "docs": "node Makefile.js docs", "gensite": "node Makefile.js gensite", "browserify": "node Makefile.js browserify", "perf": "node Makefile.js perf", "profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js -r espree", "coveralls": "cat ./coverage/lcov.info | coveralls" }, "files": [ "LICENSE", "README.md", "bin", "conf", "lib", "messages" ], "repository": "eslint/eslint", "homepage": "https://eslint.org", "bugs": "https://github.com/eslint/eslint/issues/", "dependencies": { "@babel/code-frame": "^7.0.0", "ajv": "^6.5.3", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^2.1.0", "eslint-scope": "^4.0.0", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", "espree": "^5.0.0", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.7.0", "ignore": "^4.0.6", "imurmurhash": "^0.1.4", "inquirer": "^6.1.0", "js-yaml": "^3.12.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.5", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "pluralize": "^7.0.0", "progress": "^2.0.0", "regexpp": "^2.0.1", "require-uncached": "^1.0.3", "semver": "^5.5.1", "strip-ansi": "^4.0.0", "strip-json-comments": "^2.0.1", "table": "^5.0.2", "text-table": "^0.2.0" }, "devDependencies": { "babel-core": "^6.26.3", "babel-polyfill": "^6.26.0", "babel-preset-es2015": "^6.24.1", "babelify": "^8.0.0", "beefy": "^2.1.8", "brfs": "^2.0.0", "browserify": "^16.2.2", "chai": "^4.0.1", "cheerio": "^0.22.0", "coveralls": "^3.0.1", "dateformat": "^3.0.3", "ejs": "^2.6.1", "eslint-plugin-eslint-plugin": "^1.4.1", "eslint-plugin-node": "^8.0.0", "eslint-plugin-rulesdir": "^0.1.0", "eslint-release": "^1.2.0", "eslint-rule-composer": "^0.3.0", "eslump": "^1.6.2", "esprima": "^4.0.1", "istanbul": "^0.4.5", "jsdoc": "^3.5.5", "karma": "^3.0.0", "karma-babel-preprocessor": "^7.0.0", "karma-mocha": "^1.3.0", "karma-mocha-reporter": "^2.2.3", "karma-phantomjs-launcher": "^1.0.4", "leche": "^2.2.3", "load-perf": "^0.2.0", "markdownlint": "^0.11.0", "mocha": "^5.0.5", "mock-fs": "^4.6.0", "npm-license": "^0.3.3", "phantomjs-prebuilt": "^2.1.16", "proxyquire": "^2.0.1", "shelljs": "^0.8.2", "sinon": "^3.3.0", "temp": "^0.8.3", "through": "^2.3.8" }, "keywords": [ "ast", "lint", "javascript", "ecmascript", "espree" ], "license": "MIT", "engines": { "node": "^6.14.0 || ^8.10.0 || >=9.10.0" } } },{}],112:[function(require,module,exports){ /** * @fileoverview A class of the code path analyzer. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var assert = require("assert"), CodePath = require("./code-path"), CodePathSegment = require("./code-path-segment"), IdGenerator = require("./id-generator"), debug = require("./debug-helpers"), astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is a `case` node (not `default` node). * * @param {ASTNode} node - A `SwitchCase` node to check. * @returns {boolean} `true` if the node is a `case` node (not `default` node). */ function isCaseNode(node) { return Boolean(node.test); } /** * Checks whether the given logical operator is taken into account for the code * path analysis. * * @param {string} operator - The operator found in the LogicalExpression node * @returns {boolean} `true` if the operator is "&&" or "||" */ function isHandledLogicalOperator(operator) { return operator === "&&" || operator === "||"; } /** * Checks whether or not a given logical expression node goes different path * between the `true` case and the `false` case. * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a test of a choice statement. */ function isForkingByTrueOrFalse(node) { var parent = node.parent; switch (parent.type) { case "ConditionalExpression": case "IfStatement": case "WhileStatement": case "DoWhileStatement": case "ForStatement": return parent.test === node; case "LogicalExpression": return isHandledLogicalOperator(parent.operator); default: return false; } } /** * Gets the boolean value of a given literal node. * * This is used to detect infinity loops (e.g. `while (true) {}`). * Statements preceded by an infinity loop are unreachable if the loop didn't * have any `break` statement. * * @param {ASTNode} node - A node to get. * @returns {boolean|undefined} a boolean value if the node is a Literal node, * otherwise `undefined`. */ function getBooleanValueIfSimpleConstant(node) { if (node.type === "Literal") { return Boolean(node.value); } return void 0; } /** * Checks that a given identifier node is a reference or not. * * This is used to detect the first throwable node in a `try` block. * * @param {ASTNode} node - An Identifier node to check. * @returns {boolean} `true` if the node is a reference. */ function isIdentifierReference(node) { var parent = node.parent; switch (parent.type) { case "LabeledStatement": case "BreakStatement": case "ContinueStatement": case "ArrayPattern": case "RestElement": case "ImportSpecifier": case "ImportDefaultSpecifier": case "ImportNamespaceSpecifier": case "CatchClause": return false; case "FunctionDeclaration": case "FunctionExpression": case "ArrowFunctionExpression": case "ClassDeclaration": case "ClassExpression": case "VariableDeclarator": return parent.id !== node; case "Property": case "MethodDefinition": return parent.key !== node || parent.computed || parent.shorthand; case "AssignmentPattern": return parent.key !== node; default: return true; } } /** * Updates the current segment with the head segment. * This is similar to local branches and tracking branches of git. * * To separate the current and the head is in order to not make useless segments. * * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd" * events are fired. * * @param {CodePathAnalyzer} analyzer - The instance. * @param {ASTNode} node - The current AST node. * @returns {void} */ function forwardCurrentToHead(analyzer, node) { var codePath = analyzer.codePath; var state = CodePath.getState(codePath); var currentSegments = state.currentSegments; var headSegments = state.headSegments; var end = Math.max(currentSegments.length, headSegments.length); var i = void 0, currentSegment = void 0, headSegment = void 0; // Fires leaving events. for (i = 0; i < end; ++i) { currentSegment = currentSegments[i]; headSegment = headSegments[i]; if (currentSegment !== headSegment && currentSegment) { debug.dump("onCodePathSegmentEnd " + currentSegment.id); if (currentSegment.reachable) { analyzer.emitter.emit("onCodePathSegmentEnd", currentSegment, node); } } } // Update state. state.currentSegments = headSegments; // Fires entering events. for (i = 0; i < end; ++i) { currentSegment = currentSegments[i]; headSegment = headSegments[i]; if (currentSegment !== headSegment && headSegment) { debug.dump("onCodePathSegmentStart " + headSegment.id); CodePathSegment.markUsed(headSegment); if (headSegment.reachable) { analyzer.emitter.emit("onCodePathSegmentStart", headSegment, node); } } } } /** * Updates the current segment with empty. * This is called at the last of functions or the program. * * @param {CodePathAnalyzer} analyzer - The instance. * @param {ASTNode} node - The current AST node. * @returns {void} */ function leaveFromCurrentSegment(analyzer, node) { var state = CodePath.getState(analyzer.codePath); var currentSegments = state.currentSegments; for (var i = 0; i < currentSegments.length; ++i) { var currentSegment = currentSegments[i]; debug.dump("onCodePathSegmentEnd " + currentSegment.id); if (currentSegment.reachable) { analyzer.emitter.emit("onCodePathSegmentEnd", currentSegment, node); } } state.currentSegments = []; } /** * Updates the code path due to the position of a given node in the parent node * thereof. * * For example, if the node is `parent.consequent`, this creates a fork from the * current path. * * @param {CodePathAnalyzer} analyzer - The instance. * @param {ASTNode} node - The current AST node. * @returns {void} */ function preprocess(analyzer, node) { var codePath = analyzer.codePath; var state = CodePath.getState(codePath); var parent = node.parent; switch (parent.type) { case "LogicalExpression": if (parent.right === node && isHandledLogicalOperator(parent.operator)) { state.makeLogicalRight(); } break; case "ConditionalExpression": case "IfStatement": /* * Fork if this node is at `consequent`/`alternate`. * `popForkContext()` exists at `IfStatement:exit` and * `ConditionalExpression:exit`. */ if (parent.consequent === node) { state.makeIfConsequent(); } else if (parent.alternate === node) { state.makeIfAlternate(); } break; case "SwitchCase": if (parent.consequent[0] === node) { state.makeSwitchCaseBody(false, !parent.test); } break; case "TryStatement": if (parent.handler === node) { state.makeCatchBlock(); } else if (parent.finalizer === node) { state.makeFinallyBlock(); } break; case "WhileStatement": if (parent.test === node) { state.makeWhileTest(getBooleanValueIfSimpleConstant(node)); } else { assert(parent.body === node); state.makeWhileBody(); } break; case "DoWhileStatement": if (parent.body === node) { state.makeDoWhileBody(); } else { assert(parent.test === node); state.makeDoWhileTest(getBooleanValueIfSimpleConstant(node)); } break; case "ForStatement": if (parent.test === node) { state.makeForTest(getBooleanValueIfSimpleConstant(node)); } else if (parent.update === node) { state.makeForUpdate(); } else if (parent.body === node) { state.makeForBody(); } break; case "ForInStatement": case "ForOfStatement": if (parent.left === node) { state.makeForInOfLeft(); } else if (parent.right === node) { state.makeForInOfRight(); } else { assert(parent.body === node); state.makeForInOfBody(); } break; case "AssignmentPattern": /* * Fork if this node is at `right`. * `left` is executed always, so it uses the current path. * `popForkContext()` exists at `AssignmentPattern:exit`. */ if (parent.right === node) { state.pushForkContext(); state.forkBypassPath(); state.forkPath(); } break; default: break; } } /** * Updates the code path due to the type of a given node in entering. * * @param {CodePathAnalyzer} analyzer - The instance. * @param {ASTNode} node - The current AST node. * @returns {void} */ function processCodePathToEnter(analyzer, node) { var codePath = analyzer.codePath; var state = codePath && CodePath.getState(codePath); var parent = node.parent; switch (node.type) { case "Program": case "FunctionDeclaration": case "FunctionExpression": case "ArrowFunctionExpression": if (codePath) { // Emits onCodePathSegmentStart events if updated. forwardCurrentToHead(analyzer, node); debug.dumpState(node, state, false); } // Create the code path of this scope. codePath = analyzer.codePath = new CodePath(analyzer.idGenerator.next(), codePath, analyzer.onLooped); state = CodePath.getState(codePath); // Emits onCodePathStart events. debug.dump("onCodePathStart " + codePath.id); analyzer.emitter.emit("onCodePathStart", codePath, node); break; case "LogicalExpression": if (isHandledLogicalOperator(node.operator)) { state.pushChoiceContext(node.operator, isForkingByTrueOrFalse(node)); } break; case "ConditionalExpression": case "IfStatement": state.pushChoiceContext("test", false); break; case "SwitchStatement": state.pushSwitchContext(node.cases.some(isCaseNode), astUtils.getLabel(node)); break; case "TryStatement": state.pushTryContext(Boolean(node.finalizer)); break; case "SwitchCase": /* * Fork if this node is after the 2st node in `cases`. * It's similar to `else` blocks. * The next `test` node is processed in this path. */ if (parent.discriminant !== node && parent.cases[0] !== node) { state.forkPath(); } break; case "WhileStatement": case "DoWhileStatement": case "ForStatement": case "ForInStatement": case "ForOfStatement": state.pushLoopContext(node.type, astUtils.getLabel(node)); break; case "LabeledStatement": if (!astUtils.isBreakableStatement(node.body)) { state.pushBreakContext(false, node.label.name); } break; default: break; } // Emits onCodePathSegmentStart events if updated. forwardCurrentToHead(analyzer, node); debug.dumpState(node, state, false); } /** * Updates the code path due to the type of a given node in leaving. * * @param {CodePathAnalyzer} analyzer - The instance. * @param {ASTNode} node - The current AST node. * @returns {void} */ function processCodePathToExit(analyzer, node) { var codePath = analyzer.codePath; var state = CodePath.getState(codePath); var dontForward = false; switch (node.type) { case "IfStatement": case "ConditionalExpression": state.popChoiceContext(); break; case "LogicalExpression": if (isHandledLogicalOperator(node.operator)) { state.popChoiceContext(); } break; case "SwitchStatement": state.popSwitchContext(); break; case "SwitchCase": /* * This is the same as the process at the 1st `consequent` node in * `preprocess` function. * Must do if this `consequent` is empty. */ if (node.consequent.length === 0) { state.makeSwitchCaseBody(true, !node.test); } if (state.forkContext.reachable) { dontForward = true; } break; case "TryStatement": state.popTryContext(); break; case "BreakStatement": forwardCurrentToHead(analyzer, node); state.makeBreak(node.label && node.label.name); dontForward = true; break; case "ContinueStatement": forwardCurrentToHead(analyzer, node); state.makeContinue(node.label && node.label.name); dontForward = true; break; case "ReturnStatement": forwardCurrentToHead(analyzer, node); state.makeReturn(); dontForward = true; break; case "ThrowStatement": forwardCurrentToHead(analyzer, node); state.makeThrow(); dontForward = true; break; case "Identifier": if (isIdentifierReference(node)) { state.makeFirstThrowablePathInTryBlock(); dontForward = true; } break; case "CallExpression": case "MemberExpression": case "NewExpression": state.makeFirstThrowablePathInTryBlock(); break; case "WhileStatement": case "DoWhileStatement": case "ForStatement": case "ForInStatement": case "ForOfStatement": state.popLoopContext(); break; case "AssignmentPattern": state.popForkContext(); break; case "LabeledStatement": if (!astUtils.isBreakableStatement(node.body)) { state.popBreakContext(); } break; default: break; } // Emits onCodePathSegmentStart events if updated. if (!dontForward) { forwardCurrentToHead(analyzer, node); } debug.dumpState(node, state, true); } /** * Updates the code path to finalize the current code path. * * @param {CodePathAnalyzer} analyzer - The instance. * @param {ASTNode} node - The current AST node. * @returns {void} */ function postprocess(analyzer, node) { switch (node.type) { case "Program": case "FunctionDeclaration": case "FunctionExpression": case "ArrowFunctionExpression": { var codePath = analyzer.codePath; // Mark the current path as the final node. CodePath.getState(codePath).makeFinal(); // Emits onCodePathSegmentEnd event of the current segments. leaveFromCurrentSegment(analyzer, node); // Emits onCodePathEnd event of this code path. debug.dump("onCodePathEnd " + codePath.id); analyzer.emitter.emit("onCodePathEnd", codePath, node); debug.dumpDot(codePath); codePath = analyzer.codePath = analyzer.codePath.upper; if (codePath) { debug.dumpState(node, CodePath.getState(codePath), true); } break; } default: break; } } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * The class to analyze code paths. * This class implements the EventGenerator interface. */ var CodePathAnalyzer = function () { /** * @param {EventGenerator} eventGenerator - An event generator to wrap. */ function CodePathAnalyzer(eventGenerator) { _classCallCheck(this, CodePathAnalyzer); this.original = eventGenerator; this.emitter = eventGenerator.emitter; this.codePath = null; this.idGenerator = new IdGenerator("s"); this.currentNode = null; this.onLooped = this.onLooped.bind(this); } /** * Does the process to enter a given AST node. * This updates state of analysis and calls `enterNode` of the wrapped. * * @param {ASTNode} node - A node which is entering. * @returns {void} */ _createClass(CodePathAnalyzer, [{ key: "enterNode", value: function enterNode(node) { this.currentNode = node; // Updates the code path due to node's position in its parent node. if (node.parent) { preprocess(this, node); } /* * Updates the code path. * And emits onCodePathStart/onCodePathSegmentStart events. */ processCodePathToEnter(this, node); // Emits node events. this.original.enterNode(node); this.currentNode = null; } /** * Does the process to leave a given AST node. * This updates state of analysis and calls `leaveNode` of the wrapped. * * @param {ASTNode} node - A node which is leaving. * @returns {void} */ }, { key: "leaveNode", value: function leaveNode(node) { this.currentNode = node; /* * Updates the code path. * And emits onCodePathStart/onCodePathSegmentStart events. */ processCodePathToExit(this, node); // Emits node events. this.original.leaveNode(node); // Emits the last onCodePathStart/onCodePathSegmentStart events. postprocess(this, node); this.currentNode = null; } /** * This is called on a code path looped. * Then this raises a looped event. * * @param {CodePathSegment} fromSegment - A segment of prev. * @param {CodePathSegment} toSegment - A segment of next. * @returns {void} */ }, { key: "onLooped", value: function onLooped(fromSegment, toSegment) { if (fromSegment.reachable && toSegment.reachable) { debug.dump("onCodePathSegmentLoop " + fromSegment.id + " -> " + toSegment.id); this.emitter.emit("onCodePathSegmentLoop", fromSegment, toSegment, this.currentNode); } } }]); return CodePathAnalyzer; }(); module.exports = CodePathAnalyzer; },{"../util/ast-utils":405,"./code-path":115,"./code-path-segment":113,"./debug-helpers":116,"./id-generator":118,"assert":46}],113:[function(require,module,exports){ /** * @fileoverview A class of the code path segment. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var debug = require("./debug-helpers"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given segment is reachable. * * @param {CodePathSegment} segment - A segment to check. * @returns {boolean} `true` if the segment is reachable. */ function isReachable(segment) { return segment.reachable; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * A code path segment. */ var CodePathSegment = function () { /** * @param {string} id - An identifier. * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. * This array includes unreachable segments. * @param {boolean} reachable - A flag which shows this is reachable. */ function CodePathSegment(id, allPrevSegments, reachable) { _classCallCheck(this, CodePathSegment); /** * The identifier of this code path. * Rules use it to store additional information of each rule. * @type {string} */ this.id = id; /** * An array of the next segments. * @type {CodePathSegment[]} */ this.nextSegments = []; /** * An array of the previous segments. * @type {CodePathSegment[]} */ this.prevSegments = allPrevSegments.filter(isReachable); /** * An array of the next segments. * This array includes unreachable segments. * @type {CodePathSegment[]} */ this.allNextSegments = []; /** * An array of the previous segments. * This array includes unreachable segments. * @type {CodePathSegment[]} */ this.allPrevSegments = allPrevSegments; /** * A flag which shows this is reachable. * @type {boolean} */ this.reachable = reachable; // Internal data. Object.defineProperty(this, "internal", { value: { used: false, loopedPrevSegments: [] } }); /* istanbul ignore if */ if (debug.enabled) { this.internal.nodes = []; this.internal.exitNodes = []; } } /** * Checks a given previous segment is coming from the end of a loop. * * @param {CodePathSegment} segment - A previous segment to check. * @returns {boolean} `true` if the segment is coming from the end of a loop. */ _createClass(CodePathSegment, [{ key: "isLoopedPrevSegment", value: function isLoopedPrevSegment(segment) { return this.internal.loopedPrevSegments.indexOf(segment) !== -1; } /** * Creates the root segment. * * @param {string} id - An identifier. * @returns {CodePathSegment} The created segment. */ }], [{ key: "newRoot", value: function newRoot(id) { return new CodePathSegment(id, [], true); } /** * Creates a segment that follows given segments. * * @param {string} id - An identifier. * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. * @returns {CodePathSegment} The created segment. */ }, { key: "newNext", value: function newNext(id, allPrevSegments) { return new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), allPrevSegments.some(isReachable)); } /** * Creates an unreachable segment that follows given segments. * * @param {string} id - An identifier. * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. * @returns {CodePathSegment} The created segment. */ }, { key: "newUnreachable", value: function newUnreachable(id, allPrevSegments) { var segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false); /* * In `if (a) return a; foo();` case, the unreachable segment preceded by * the return statement is not used but must not be remove. */ CodePathSegment.markUsed(segment); return segment; } /** * Creates a segment that follows given segments. * This factory method does not connect with `allPrevSegments`. * But this inherits `reachable` flag. * * @param {string} id - An identifier. * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments. * @returns {CodePathSegment} The created segment. */ }, { key: "newDisconnected", value: function newDisconnected(id, allPrevSegments) { return new CodePathSegment(id, [], allPrevSegments.some(isReachable)); } /** * Makes a given segment being used. * * And this function registers the segment into the previous segments as a next. * * @param {CodePathSegment} segment - A segment to mark. * @returns {void} */ }, { key: "markUsed", value: function markUsed(segment) { if (segment.internal.used) { return; } segment.internal.used = true; var i = void 0; if (segment.reachable) { for (i = 0; i < segment.allPrevSegments.length; ++i) { var prevSegment = segment.allPrevSegments[i]; prevSegment.allNextSegments.push(segment); prevSegment.nextSegments.push(segment); } } else { for (i = 0; i < segment.allPrevSegments.length; ++i) { segment.allPrevSegments[i].allNextSegments.push(segment); } } } /** * Marks a previous segment as looped. * * @param {CodePathSegment} segment - A segment. * @param {CodePathSegment} prevSegment - A previous segment to mark. * @returns {void} */ }, { key: "markPrevSegmentAsLooped", value: function markPrevSegmentAsLooped(segment, prevSegment) { segment.internal.loopedPrevSegments.push(prevSegment); } /** * Replaces unused segments with the previous segments of each unused segment. * * @param {CodePathSegment[]} segments - An array of segments to replace. * @returns {CodePathSegment[]} The replaced array. */ }, { key: "flattenUnusedSegments", value: function flattenUnusedSegments(segments) { var done = Object.create(null); var retv = []; for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; // Ignores duplicated. if (done[segment.id]) { continue; } // Use previous segments if unused. if (!segment.internal.used) { for (var j = 0; j < segment.allPrevSegments.length; ++j) { var prevSegment = segment.allPrevSegments[j]; if (!done[prevSegment.id]) { done[prevSegment.id] = true; retv.push(prevSegment); } } } else { done[segment.id] = true; retv.push(segment); } } return retv; } }]); return CodePathSegment; }(); module.exports = CodePathSegment; },{"./debug-helpers":116}],114:[function(require,module,exports){ /** * @fileoverview A class to manage state of generating a code path. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var CodePathSegment = require("./code-path-segment"), ForkContext = require("./fork-context"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Adds given segments into the `dest` array. * If the `others` array does not includes the given segments, adds to the `all` * array as well. * * This adds only reachable and used segments. * * @param {CodePathSegment[]} dest - A destination array (`returnedSegments` or `thrownSegments`). * @param {CodePathSegment[]} others - Another destination array (`returnedSegments` or `thrownSegments`). * @param {CodePathSegment[]} all - The unified destination array (`finalSegments`). * @param {CodePathSegment[]} segments - Segments to add. * @returns {void} */ function addToReturnedOrThrown(dest, others, all, segments) { for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; dest.push(segment); if (others.indexOf(segment) === -1) { all.push(segment); } } } /** * Gets a loop-context for a `continue` statement. * * @param {CodePathState} state - A state to get. * @param {string} label - The label of a `continue` statement. * @returns {LoopContext} A loop-context for a `continue` statement. */ function getContinueContext(state, label) { if (!label) { return state.loopContext; } var context = state.loopContext; while (context) { if (context.label === label) { return context; } context = context.upper; } /* istanbul ignore next: foolproof (syntax error) */ return null; } /** * Gets a context for a `break` statement. * * @param {CodePathState} state - A state to get. * @param {string} label - The label of a `break` statement. * @returns {LoopContext|SwitchContext} A context for a `break` statement. */ function getBreakContext(state, label) { var context = state.breakContext; while (context) { if (label ? context.label === label : context.breakable) { return context; } context = context.upper; } /* istanbul ignore next: foolproof (syntax error) */ return null; } /** * Gets a context for a `return` statement. * * @param {CodePathState} state - A state to get. * @returns {TryContext|CodePathState} A context for a `return` statement. */ function getReturnContext(state) { var context = state.tryContext; while (context) { if (context.hasFinalizer && context.position !== "finally") { return context; } context = context.upper; } return state; } /** * Gets a context for a `throw` statement. * * @param {CodePathState} state - A state to get. * @returns {TryContext|CodePathState} A context for a `throw` statement. */ function getThrowContext(state) { var context = state.tryContext; while (context) { if (context.position === "try" || context.hasFinalizer && context.position === "catch") { return context; } context = context.upper; } return state; } /** * Removes a given element from a given array. * * @param {any[]} xs - An array to remove the specific element. * @param {any} x - An element to be removed. * @returns {void} */ function remove(xs, x) { xs.splice(xs.indexOf(x), 1); } /** * Disconnect given segments. * * This is used in a process for switch statements. * If there is the "default" chunk before other cases, the order is different * between node's and running's. * * @param {CodePathSegment[]} prevSegments - Forward segments to disconnect. * @param {CodePathSegment[]} nextSegments - Backward segments to disconnect. * @returns {void} */ function removeConnection(prevSegments, nextSegments) { for (var i = 0; i < prevSegments.length; ++i) { var prevSegment = prevSegments[i]; var nextSegment = nextSegments[i]; remove(prevSegment.nextSegments, nextSegment); remove(prevSegment.allNextSegments, nextSegment); remove(nextSegment.prevSegments, prevSegment); remove(nextSegment.allPrevSegments, prevSegment); } } /** * Creates looping path. * * @param {CodePathState} state - The instance. * @param {CodePathSegment[]} unflattenedFromSegments - Segments which are source. * @param {CodePathSegment[]} unflattenedToSegments - Segments which are destination. * @returns {void} */ function makeLooped(state, unflattenedFromSegments, unflattenedToSegments) { var fromSegments = CodePathSegment.flattenUnusedSegments(unflattenedFromSegments); var toSegments = CodePathSegment.flattenUnusedSegments(unflattenedToSegments); var end = Math.min(fromSegments.length, toSegments.length); for (var i = 0; i < end; ++i) { var fromSegment = fromSegments[i]; var toSegment = toSegments[i]; if (toSegment.reachable) { fromSegment.nextSegments.push(toSegment); } if (fromSegment.reachable) { toSegment.prevSegments.push(fromSegment); } fromSegment.allNextSegments.push(toSegment); toSegment.allPrevSegments.push(fromSegment); if (toSegment.allPrevSegments.length >= 2) { CodePathSegment.markPrevSegmentAsLooped(toSegment, fromSegment); } state.notifyLooped(fromSegment, toSegment); } } /** * Finalizes segments of `test` chunk of a ForStatement. * * - Adds `false` paths to paths which are leaving from the loop. * - Sets `true` paths to paths which go to the body. * * @param {LoopContext} context - A loop context to modify. * @param {ChoiceContext} choiceContext - A choice context of this loop. * @param {CodePathSegment[]} head - The current head paths. * @returns {void} */ function finalizeTestSegmentsOfFor(context, choiceContext, head) { if (!choiceContext.processed) { choiceContext.trueForkContext.add(head); choiceContext.falseForkContext.add(head); } if (context.test !== true) { context.brokenForkContext.addAll(choiceContext.falseForkContext); } context.endOfTestSegments = choiceContext.trueForkContext.makeNext(0, -1); } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * A class which manages state to analyze code paths. */ var CodePathState = function () { /** * @param {IdGenerator} idGenerator - An id generator to generate id for code * path segments. * @param {Function} onLooped - A callback function to notify looping. */ function CodePathState(idGenerator, onLooped) { _classCallCheck(this, CodePathState); this.idGenerator = idGenerator; this.notifyLooped = onLooped; this.forkContext = ForkContext.newRoot(idGenerator); this.choiceContext = null; this.switchContext = null; this.tryContext = null; this.loopContext = null; this.breakContext = null; this.currentSegments = []; this.initialSegment = this.forkContext.head[0]; // returnedSegments and thrownSegments push elements into finalSegments also. var final = this.finalSegments = []; var returned = this.returnedForkContext = []; var thrown = this.thrownForkContext = []; returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final); thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final); } /** * The head segments. * @type {CodePathSegment[]} */ _createClass(CodePathState, [{ key: "pushForkContext", /** * Creates and stacks new forking context. * * @param {boolean} forkLeavingPath - A flag which shows being in a * "finally" block. * @returns {ForkContext} The created context. */ value: function pushForkContext(forkLeavingPath) { this.forkContext = ForkContext.newEmpty(this.forkContext, forkLeavingPath); return this.forkContext; } /** * Pops and merges the last forking context. * @returns {ForkContext} The last context. */ }, { key: "popForkContext", value: function popForkContext() { var lastContext = this.forkContext; this.forkContext = lastContext.upper; this.forkContext.replaceHead(lastContext.makeNext(0, -1)); return lastContext; } /** * Creates a new path. * @returns {void} */ }, { key: "forkPath", value: function forkPath() { this.forkContext.add(this.parentForkContext.makeNext(-1, -1)); } /** * Creates a bypass path. * This is used for such as IfStatement which does not have "else" chunk. * * @returns {void} */ }, { key: "forkBypassPath", value: function forkBypassPath() { this.forkContext.add(this.parentForkContext.head); } //-------------------------------------------------------------------------- // ConditionalExpression, LogicalExpression, IfStatement //-------------------------------------------------------------------------- /** * Creates a context for ConditionalExpression, LogicalExpression, * IfStatement, WhileStatement, DoWhileStatement, or ForStatement. * * LogicalExpressions have cases that it goes different paths between the * `true` case and the `false` case. * * For Example: * * if (a || b) { * foo(); * } else { * bar(); * } * * In this case, `b` is evaluated always in the code path of the `else` * block, but it's not so in the code path of the `if` block. * So there are 3 paths. * * a -> foo(); * a -> b -> foo(); * a -> b -> bar(); * * @param {string} kind - A kind string. * If the new context is LogicalExpression's, this is `"&&"` or `"||"`. * If it's IfStatement's or ConditionalExpression's, this is `"test"`. * Otherwise, this is `"loop"`. * @param {boolean} isForkingAsResult - A flag that shows that goes different * paths between `true` and `false`. * @returns {void} */ }, { key: "pushChoiceContext", value: function pushChoiceContext(kind, isForkingAsResult) { this.choiceContext = { upper: this.choiceContext, kind: kind, isForkingAsResult: isForkingAsResult, trueForkContext: ForkContext.newEmpty(this.forkContext), falseForkContext: ForkContext.newEmpty(this.forkContext), processed: false }; } /** * Pops the last choice context and finalizes it. * * @returns {ChoiceContext} The popped context. */ }, { key: "popChoiceContext", value: function popChoiceContext() { var context = this.choiceContext; this.choiceContext = context.upper; var forkContext = this.forkContext; var headSegments = forkContext.head; switch (context.kind) { case "&&": case "||": /* * If any result were not transferred from child contexts, * this sets the head segments to both cases. * The head segments are the path of the right-hand operand. */ if (!context.processed) { context.trueForkContext.add(headSegments); context.falseForkContext.add(headSegments); } /* * Transfers results to upper context if this context is in * test chunk. */ if (context.isForkingAsResult) { var parentContext = this.choiceContext; parentContext.trueForkContext.addAll(context.trueForkContext); parentContext.falseForkContext.addAll(context.falseForkContext); parentContext.processed = true; return context; } break; case "test": if (!context.processed) { /* * The head segments are the path of the `if` block here. * Updates the `true` path with the end of the `if` block. */ context.trueForkContext.clear(); context.trueForkContext.add(headSegments); } else { /* * The head segments are the path of the `else` block here. * Updates the `false` path with the end of the `else` * block. */ context.falseForkContext.clear(); context.falseForkContext.add(headSegments); } break; case "loop": /* * Loops are addressed in popLoopContext(). * This is called from popLoopContext(). */ return context; /* istanbul ignore next */ default: throw new Error("unreachable"); } // Merges all paths. var prevForkContext = context.trueForkContext; prevForkContext.addAll(context.falseForkContext); forkContext.replaceHead(prevForkContext.makeNext(0, -1)); return context; } /** * Makes a code path segment of the right-hand operand of a logical * expression. * * @returns {void} */ }, { key: "makeLogicalRight", value: function makeLogicalRight() { var context = this.choiceContext; var forkContext = this.forkContext; if (context.processed) { /* * This got segments already from the child choice context. * Creates the next path from own true/false fork context. */ var prevForkContext = context.kind === "&&" ? context.trueForkContext /* kind === "||" */ : context.falseForkContext; forkContext.replaceHead(prevForkContext.makeNext(0, -1)); prevForkContext.clear(); context.processed = false; } else { /* * This did not get segments from the child choice context. * So addresses the head segments. * The head segments are the path of the left-hand operand. */ if (context.kind === "&&") { // The path does short-circuit if false. context.falseForkContext.add(forkContext.head); } else { // The path does short-circuit if true. context.trueForkContext.add(forkContext.head); } forkContext.replaceHead(forkContext.makeNext(-1, -1)); } } /** * Makes a code path segment of the `if` block. * * @returns {void} */ }, { key: "makeIfConsequent", value: function makeIfConsequent() { var context = this.choiceContext; var forkContext = this.forkContext; /* * If any result were not transferred from child contexts, * this sets the head segments to both cases. * The head segments are the path of the test expression. */ if (!context.processed) { context.trueForkContext.add(forkContext.head); context.falseForkContext.add(forkContext.head); } context.processed = false; // Creates new path from the `true` case. forkContext.replaceHead(context.trueForkContext.makeNext(0, -1)); } /** * Makes a code path segment of the `else` block. * * @returns {void} */ }, { key: "makeIfAlternate", value: function makeIfAlternate() { var context = this.choiceContext; var forkContext = this.forkContext; /* * The head segments are the path of the `if` block. * Updates the `true` path with the end of the `if` block. */ context.trueForkContext.clear(); context.trueForkContext.add(forkContext.head); context.processed = true; // Creates new path from the `false` case. forkContext.replaceHead(context.falseForkContext.makeNext(0, -1)); } //-------------------------------------------------------------------------- // SwitchStatement //-------------------------------------------------------------------------- /** * Creates a context object of SwitchStatement and stacks it. * * @param {boolean} hasCase - `true` if the switch statement has one or more * case parts. * @param {string|null} label - The label text. * @returns {void} */ }, { key: "pushSwitchContext", value: function pushSwitchContext(hasCase, label) { this.switchContext = { upper: this.switchContext, hasCase: hasCase, defaultSegments: null, defaultBodySegments: null, foundDefault: false, lastIsDefault: false, countForks: 0 }; this.pushBreakContext(true, label); } /** * Pops the last context of SwitchStatement and finalizes it. * * - Disposes all forking stack for `case` and `default`. * - Creates the next code path segment from `context.brokenForkContext`. * - If the last `SwitchCase` node is not a `default` part, creates a path * to the `default` body. * * @returns {void} */ }, { key: "popSwitchContext", value: function popSwitchContext() { var context = this.switchContext; this.switchContext = context.upper; var forkContext = this.forkContext; var brokenForkContext = this.popBreakContext().brokenForkContext; if (context.countForks === 0) { /* * When there is only one `default` chunk and there is one or more * `break` statements, even if forks are nothing, it needs to merge * those. */ if (!brokenForkContext.empty) { brokenForkContext.add(forkContext.makeNext(-1, -1)); forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); } return; } var lastSegments = forkContext.head; this.forkBypassPath(); var lastCaseSegments = forkContext.head; /* * `brokenForkContext` is used to make the next segment. * It must add the last segment into `brokenForkContext`. */ brokenForkContext.add(lastSegments); /* * A path which is failed in all case test should be connected to path * of `default` chunk. */ if (!context.lastIsDefault) { if (context.defaultBodySegments) { /* * Remove a link from `default` label to its chunk. * It's false route. */ removeConnection(context.defaultSegments, context.defaultBodySegments); makeLooped(this, lastCaseSegments, context.defaultBodySegments); } else { /* * It handles the last case body as broken if `default` chunk * does not exist. */ brokenForkContext.add(lastCaseSegments); } } // Pops the segment context stack until the entry segment. for (var i = 0; i < context.countForks; ++i) { this.forkContext = this.forkContext.upper; } /* * Creates a path from all brokenForkContext paths. * This is a path after switch statement. */ this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); } /** * Makes a code path segment for a `SwitchCase` node. * * @param {boolean} isEmpty - `true` if the body is empty. * @param {boolean} isDefault - `true` if the body is the default case. * @returns {void} */ }, { key: "makeSwitchCaseBody", value: function makeSwitchCaseBody(isEmpty, isDefault) { var context = this.switchContext; if (!context.hasCase) { return; } /* * Merge forks. * The parent fork context has two segments. * Those are from the current case and the body of the previous case. */ var parentForkContext = this.forkContext; var forkContext = this.pushForkContext(); forkContext.add(parentForkContext.makeNext(0, -1)); /* * Save `default` chunk info. * If the `default` label is not at the last, we must make a path from * the last `case` to the `default` chunk. */ if (isDefault) { context.defaultSegments = parentForkContext.head; if (isEmpty) { context.foundDefault = true; } else { context.defaultBodySegments = forkContext.head; } } else { if (!isEmpty && context.foundDefault) { context.foundDefault = false; context.defaultBodySegments = forkContext.head; } } context.lastIsDefault = isDefault; context.countForks += 1; } //-------------------------------------------------------------------------- // TryStatement //-------------------------------------------------------------------------- /** * Creates a context object of TryStatement and stacks it. * * @param {boolean} hasFinalizer - `true` if the try statement has a * `finally` block. * @returns {void} */ }, { key: "pushTryContext", value: function pushTryContext(hasFinalizer) { this.tryContext = { upper: this.tryContext, position: "try", hasFinalizer: hasFinalizer, returnedForkContext: hasFinalizer ? ForkContext.newEmpty(this.forkContext) : null, thrownForkContext: ForkContext.newEmpty(this.forkContext), lastOfTryIsReachable: false, lastOfCatchIsReachable: false }; } /** * Pops the last context of TryStatement and finalizes it. * * @returns {void} */ }, { key: "popTryContext", value: function popTryContext() { var context = this.tryContext; this.tryContext = context.upper; if (context.position === "catch") { // Merges two paths from the `try` block and `catch` block merely. this.popForkContext(); return; } /* * The following process is executed only when there is the `finally` * block. */ var returned = context.returnedForkContext; var thrown = context.thrownForkContext; if (returned.empty && thrown.empty) { return; } // Separate head to normal paths and leaving paths. var headSegments = this.forkContext.head; this.forkContext = this.forkContext.upper; var normalSegments = headSegments.slice(0, headSegments.length / 2 | 0); var leavingSegments = headSegments.slice(headSegments.length / 2 | 0); // Forwards the leaving path to upper contexts. if (!returned.empty) { getReturnContext(this).returnedForkContext.add(leavingSegments); } if (!thrown.empty) { getThrowContext(this).thrownForkContext.add(leavingSegments); } // Sets the normal path as the next. this.forkContext.replaceHead(normalSegments); /* * If both paths of the `try` block and the `catch` block are * unreachable, the next path becomes unreachable as well. */ if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) { this.forkContext.makeUnreachable(); } } /** * Makes a code path segment for a `catch` block. * * @returns {void} */ }, { key: "makeCatchBlock", value: function makeCatchBlock() { var context = this.tryContext; var forkContext = this.forkContext; var thrown = context.thrownForkContext; // Update state. context.position = "catch"; context.thrownForkContext = ForkContext.newEmpty(forkContext); context.lastOfTryIsReachable = forkContext.reachable; // Merge thrown paths. thrown.add(forkContext.head); var thrownSegments = thrown.makeNext(0, -1); // Fork to a bypass and the merged thrown path. this.pushForkContext(); this.forkBypassPath(); this.forkContext.add(thrownSegments); } /** * Makes a code path segment for a `finally` block. * * In the `finally` block, parallel paths are created. The parallel paths * are used as leaving-paths. The leaving-paths are paths from `return` * statements and `throw` statements in a `try` block or a `catch` block. * * @returns {void} */ }, { key: "makeFinallyBlock", value: function makeFinallyBlock() { var context = this.tryContext; var forkContext = this.forkContext; var returned = context.returnedForkContext; var thrown = context.thrownForkContext; var headOfLeavingSegments = forkContext.head; // Update state. if (context.position === "catch") { // Merges two paths from the `try` block and `catch` block. this.popForkContext(); forkContext = this.forkContext; context.lastOfCatchIsReachable = forkContext.reachable; } else { context.lastOfTryIsReachable = forkContext.reachable; } context.position = "finally"; if (returned.empty && thrown.empty) { // This path does not leave. return; } /* * Create a parallel segment from merging returned and thrown. * This segment will leave at the end of this finally block. */ var segments = forkContext.makeNext(-1, -1); for (var i = 0; i < forkContext.count; ++i) { var prevSegsOfLeavingSegment = [headOfLeavingSegments[i]]; for (var j = 0; j < returned.segmentsList.length; ++j) { prevSegsOfLeavingSegment.push(returned.segmentsList[j][i]); } for (var _j = 0; _j < thrown.segmentsList.length; ++_j) { prevSegsOfLeavingSegment.push(thrown.segmentsList[_j][i]); } segments.push(CodePathSegment.newNext(this.idGenerator.next(), prevSegsOfLeavingSegment)); } this.pushForkContext(true); this.forkContext.add(segments); } /** * Makes a code path segment from the first throwable node to the `catch` * block or the `finally` block. * * @returns {void} */ }, { key: "makeFirstThrowablePathInTryBlock", value: function makeFirstThrowablePathInTryBlock() { var forkContext = this.forkContext; if (!forkContext.reachable) { return; } var context = getThrowContext(this); if (context === this || context.position !== "try" || !context.thrownForkContext.empty) { return; } context.thrownForkContext.add(forkContext.head); forkContext.replaceHead(forkContext.makeNext(-1, -1)); } //-------------------------------------------------------------------------- // Loop Statements //-------------------------------------------------------------------------- /** * Creates a context object of a loop statement and stacks it. * * @param {string} type - The type of the node which was triggered. One of * `WhileStatement`, `DoWhileStatement`, `ForStatement`, `ForInStatement`, * and `ForStatement`. * @param {string|null} label - A label of the node which was triggered. * @returns {void} */ }, { key: "pushLoopContext", value: function pushLoopContext(type, label) { var forkContext = this.forkContext; var breakContext = this.pushBreakContext(true, label); switch (type) { case "WhileStatement": this.pushChoiceContext("loop", false); this.loopContext = { upper: this.loopContext, type: type, label: label, test: void 0, continueDestSegments: null, brokenForkContext: breakContext.brokenForkContext }; break; case "DoWhileStatement": this.pushChoiceContext("loop", false); this.loopContext = { upper: this.loopContext, type: type, label: label, test: void 0, entrySegments: null, continueForkContext: ForkContext.newEmpty(forkContext), brokenForkContext: breakContext.brokenForkContext }; break; case "ForStatement": this.pushChoiceContext("loop", false); this.loopContext = { upper: this.loopContext, type: type, label: label, test: void 0, endOfInitSegments: null, testSegments: null, endOfTestSegments: null, updateSegments: null, endOfUpdateSegments: null, continueDestSegments: null, brokenForkContext: breakContext.brokenForkContext }; break; case "ForInStatement": case "ForOfStatement": this.loopContext = { upper: this.loopContext, type: type, label: label, prevSegments: null, leftSegments: null, endOfLeftSegments: null, continueDestSegments: null, brokenForkContext: breakContext.brokenForkContext }; break; /* istanbul ignore next */ default: throw new Error("unknown type: \"" + type + "\""); } } /** * Pops the last context of a loop statement and finalizes it. * * @returns {void} */ }, { key: "popLoopContext", value: function popLoopContext() { var context = this.loopContext; this.loopContext = context.upper; var forkContext = this.forkContext; var brokenForkContext = this.popBreakContext().brokenForkContext; // Creates a looped path. switch (context.type) { case "WhileStatement": case "ForStatement": this.popChoiceContext(); makeLooped(this, forkContext.head, context.continueDestSegments); break; case "DoWhileStatement": { var choiceContext = this.popChoiceContext(); if (!choiceContext.processed) { choiceContext.trueForkContext.add(forkContext.head); choiceContext.falseForkContext.add(forkContext.head); } if (context.test !== true) { brokenForkContext.addAll(choiceContext.falseForkContext); } // `true` paths go to looping. var segmentsList = choiceContext.trueForkContext.segmentsList; for (var i = 0; i < segmentsList.length; ++i) { makeLooped(this, segmentsList[i], context.entrySegments); } break; } case "ForInStatement": case "ForOfStatement": brokenForkContext.add(forkContext.head); makeLooped(this, forkContext.head, context.leftSegments); break; /* istanbul ignore next */ default: throw new Error("unreachable"); } // Go next. if (brokenForkContext.empty) { forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } else { forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); } } /** * Makes a code path segment for the test part of a WhileStatement. * * @param {boolean|undefined} test - The test value (only when constant). * @returns {void} */ }, { key: "makeWhileTest", value: function makeWhileTest(test) { var context = this.loopContext; var forkContext = this.forkContext; var testSegments = forkContext.makeNext(0, -1); // Update state. context.test = test; context.continueDestSegments = testSegments; forkContext.replaceHead(testSegments); } /** * Makes a code path segment for the body part of a WhileStatement. * * @returns {void} */ }, { key: "makeWhileBody", value: function makeWhileBody() { var context = this.loopContext; var choiceContext = this.choiceContext; var forkContext = this.forkContext; if (!choiceContext.processed) { choiceContext.trueForkContext.add(forkContext.head); choiceContext.falseForkContext.add(forkContext.head); } // Update state. if (context.test !== true) { context.brokenForkContext.addAll(choiceContext.falseForkContext); } forkContext.replaceHead(choiceContext.trueForkContext.makeNext(0, -1)); } /** * Makes a code path segment for the body part of a DoWhileStatement. * * @returns {void} */ }, { key: "makeDoWhileBody", value: function makeDoWhileBody() { var context = this.loopContext; var forkContext = this.forkContext; var bodySegments = forkContext.makeNext(-1, -1); // Update state. context.entrySegments = bodySegments; forkContext.replaceHead(bodySegments); } /** * Makes a code path segment for the test part of a DoWhileStatement. * * @param {boolean|undefined} test - The test value (only when constant). * @returns {void} */ }, { key: "makeDoWhileTest", value: function makeDoWhileTest(test) { var context = this.loopContext; var forkContext = this.forkContext; context.test = test; // Creates paths of `continue` statements. if (!context.continueForkContext.empty) { context.continueForkContext.add(forkContext.head); var testSegments = context.continueForkContext.makeNext(0, -1); forkContext.replaceHead(testSegments); } } /** * Makes a code path segment for the test part of a ForStatement. * * @param {boolean|undefined} test - The test value (only when constant). * @returns {void} */ }, { key: "makeForTest", value: function makeForTest(test) { var context = this.loopContext; var forkContext = this.forkContext; var endOfInitSegments = forkContext.head; var testSegments = forkContext.makeNext(-1, -1); // Update state. context.test = test; context.endOfInitSegments = endOfInitSegments; context.continueDestSegments = context.testSegments = testSegments; forkContext.replaceHead(testSegments); } /** * Makes a code path segment for the update part of a ForStatement. * * @returns {void} */ }, { key: "makeForUpdate", value: function makeForUpdate() { var context = this.loopContext; var choiceContext = this.choiceContext; var forkContext = this.forkContext; // Make the next paths of the test. if (context.testSegments) { finalizeTestSegmentsOfFor(context, choiceContext, forkContext.head); } else { context.endOfInitSegments = forkContext.head; } // Update state. var updateSegments = forkContext.makeDisconnected(-1, -1); context.continueDestSegments = context.updateSegments = updateSegments; forkContext.replaceHead(updateSegments); } /** * Makes a code path segment for the body part of a ForStatement. * * @returns {void} */ }, { key: "makeForBody", value: function makeForBody() { var context = this.loopContext; var choiceContext = this.choiceContext; var forkContext = this.forkContext; // Update state. if (context.updateSegments) { context.endOfUpdateSegments = forkContext.head; // `update` -> `test` if (context.testSegments) { makeLooped(this, context.endOfUpdateSegments, context.testSegments); } } else if (context.testSegments) { finalizeTestSegmentsOfFor(context, choiceContext, forkContext.head); } else { context.endOfInitSegments = forkContext.head; } var bodySegments = context.endOfTestSegments; if (!bodySegments) { /* * If there is not the `test` part, the `body` path comes from the * `init` part and the `update` part. */ var prevForkContext = ForkContext.newEmpty(forkContext); prevForkContext.add(context.endOfInitSegments); if (context.endOfUpdateSegments) { prevForkContext.add(context.endOfUpdateSegments); } bodySegments = prevForkContext.makeNext(0, -1); } context.continueDestSegments = context.continueDestSegments || bodySegments; forkContext.replaceHead(bodySegments); } /** * Makes a code path segment for the left part of a ForInStatement and a * ForOfStatement. * * @returns {void} */ }, { key: "makeForInOfLeft", value: function makeForInOfLeft() { var context = this.loopContext; var forkContext = this.forkContext; var leftSegments = forkContext.makeDisconnected(-1, -1); // Update state. context.prevSegments = forkContext.head; context.leftSegments = context.continueDestSegments = leftSegments; forkContext.replaceHead(leftSegments); } /** * Makes a code path segment for the right part of a ForInStatement and a * ForOfStatement. * * @returns {void} */ }, { key: "makeForInOfRight", value: function makeForInOfRight() { var context = this.loopContext; var forkContext = this.forkContext; var temp = ForkContext.newEmpty(forkContext); temp.add(context.prevSegments); var rightSegments = temp.makeNext(-1, -1); // Update state. context.endOfLeftSegments = forkContext.head; forkContext.replaceHead(rightSegments); } /** * Makes a code path segment for the body part of a ForInStatement and a * ForOfStatement. * * @returns {void} */ }, { key: "makeForInOfBody", value: function makeForInOfBody() { var context = this.loopContext; var forkContext = this.forkContext; var temp = ForkContext.newEmpty(forkContext); temp.add(context.endOfLeftSegments); var bodySegments = temp.makeNext(-1, -1); // Make a path: `right` -> `left`. makeLooped(this, forkContext.head, context.leftSegments); // Update state. context.brokenForkContext.add(forkContext.head); forkContext.replaceHead(bodySegments); } //-------------------------------------------------------------------------- // Control Statements //-------------------------------------------------------------------------- /** * Creates new context for BreakStatement. * * @param {boolean} breakable - The flag to indicate it can break by * an unlabeled BreakStatement. * @param {string|null} label - The label of this context. * @returns {Object} The new context. */ }, { key: "pushBreakContext", value: function pushBreakContext(breakable, label) { this.breakContext = { upper: this.breakContext, breakable: breakable, label: label, brokenForkContext: ForkContext.newEmpty(this.forkContext) }; return this.breakContext; } /** * Removes the top item of the break context stack. * * @returns {Object} The removed context. */ }, { key: "popBreakContext", value: function popBreakContext() { var context = this.breakContext; var forkContext = this.forkContext; this.breakContext = context.upper; // Process this context here for other than switches and loops. if (!context.breakable) { var brokenForkContext = context.brokenForkContext; if (!brokenForkContext.empty) { brokenForkContext.add(forkContext.head); forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); } } return context; } /** * Makes a path for a `break` statement. * * It registers the head segment to a context of `break`. * It makes new unreachable segment, then it set the head with the segment. * * @param {string} label - A label of the break statement. * @returns {void} */ }, { key: "makeBreak", value: function makeBreak(label) { var forkContext = this.forkContext; if (!forkContext.reachable) { return; } var context = getBreakContext(this, label); /* istanbul ignore else: foolproof (syntax error) */ if (context) { context.brokenForkContext.add(forkContext.head); } forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } /** * Makes a path for a `continue` statement. * * It makes a looping path. * It makes new unreachable segment, then it set the head with the segment. * * @param {string} label - A label of the continue statement. * @returns {void} */ }, { key: "makeContinue", value: function makeContinue(label) { var forkContext = this.forkContext; if (!forkContext.reachable) { return; } var context = getContinueContext(this, label); /* istanbul ignore else: foolproof (syntax error) */ if (context) { if (context.continueDestSegments) { makeLooped(this, forkContext.head, context.continueDestSegments); // If the context is a for-in/of loop, this effects a break also. if (context.type === "ForInStatement" || context.type === "ForOfStatement") { context.brokenForkContext.add(forkContext.head); } } else { context.continueForkContext.add(forkContext.head); } } forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } /** * Makes a path for a `return` statement. * * It registers the head segment to a context of `return`. * It makes new unreachable segment, then it set the head with the segment. * * @returns {void} */ }, { key: "makeReturn", value: function makeReturn() { var forkContext = this.forkContext; if (forkContext.reachable) { getReturnContext(this).returnedForkContext.add(forkContext.head); forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } } /** * Makes a path for a `throw` statement. * * It registers the head segment to a context of `throw`. * It makes new unreachable segment, then it set the head with the segment. * * @returns {void} */ }, { key: "makeThrow", value: function makeThrow() { var forkContext = this.forkContext; if (forkContext.reachable) { getThrowContext(this).thrownForkContext.add(forkContext.head); forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); } } /** * Makes the final path. * @returns {void} */ }, { key: "makeFinal", value: function makeFinal() { var segments = this.currentSegments; if (segments.length > 0 && segments[0].reachable) { this.returnedForkContext.add(segments); } } }, { key: "headSegments", get: function get() { return this.forkContext.head; } /** * The parent forking context. * This is used for the root of new forks. * @type {ForkContext} */ }, { key: "parentForkContext", get: function get() { var current = this.forkContext; return current && current.upper; } }]); return CodePathState; }(); module.exports = CodePathState; },{"./code-path-segment":113,"./fork-context":117}],115:[function(require,module,exports){ /** * @fileoverview A class of the code path. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var CodePathState = require("./code-path-state"); var IdGenerator = require("./id-generator"); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * A code path. */ var CodePath = function () { /** * @param {string} id - An identifier. * @param {CodePath|null} upper - The code path of the upper function scope. * @param {Function} onLooped - A callback function to notify looping. */ function CodePath(id, upper, onLooped) { _classCallCheck(this, CodePath); /** * The identifier of this code path. * Rules use it to store additional information of each rule. * @type {string} */ this.id = id; /** * The code path of the upper function scope. * @type {CodePath|null} */ this.upper = upper; /** * The code paths of nested function scopes. * @type {CodePath[]} */ this.childCodePaths = []; // Initializes internal state. Object.defineProperty(this, "internal", { value: new CodePathState(new IdGenerator(id + "_"), onLooped) }); // Adds this into `childCodePaths` of `upper`. if (upper) { upper.childCodePaths.push(this); } } /** * Gets the state of a given code path. * * @param {CodePath} codePath - A code path to get. * @returns {CodePathState} The state of the code path. */ _createClass(CodePath, [{ key: "traverseSegments", /** * Traverses all segments in this code path. * * codePath.traverseSegments(function(segment, controller) { * // do something. * }); * * This method enumerates segments in order from the head. * * The `controller` object has two methods. * * - `controller.skip()` - Skip the following segments in this branch. * - `controller.break()` - Skip all following segments. * * @param {Object} [options] - Omittable. * @param {CodePathSegment} [options.first] - The first segment to traverse. * @param {CodePathSegment} [options.last] - The last segment to traverse. * @param {Function} callback - A callback function. * @returns {void} */ value: function traverseSegments(options, callback) { var resolvedOptions = void 0; var resolvedCallback = void 0; if (typeof options === "function") { resolvedCallback = options; resolvedOptions = {}; } else { resolvedOptions = options || {}; resolvedCallback = callback; } var startSegment = resolvedOptions.first || this.internal.initialSegment; var lastSegment = resolvedOptions.last; var item = null; var index = 0; var end = 0; var segment = null; var visited = Object.create(null); var stack = [[startSegment, 0]]; var skippedSegment = null; var broken = false; var controller = { skip: function skip() { if (stack.length <= 1) { broken = true; } else { skippedSegment = stack[stack.length - 2][0]; } }, break: function _break() { broken = true; } }; /** * Checks a given previous segment has been visited. * @param {CodePathSegment} prevSegment - A previous segment to check. * @returns {boolean} `true` if the segment has been visited. */ function isVisited(prevSegment) { return visited[prevSegment.id] || segment.isLoopedPrevSegment(prevSegment); } while (stack.length > 0) { item = stack[stack.length - 1]; segment = item[0]; index = item[1]; if (index === 0) { // Skip if this segment has been visited already. if (visited[segment.id]) { stack.pop(); continue; } // Skip if all previous segments have not been visited. if (segment !== startSegment && segment.prevSegments.length > 0 && !segment.prevSegments.every(isVisited)) { stack.pop(); continue; } // Reset the flag of skipping if all branches have been skipped. if (skippedSegment && segment.prevSegments.indexOf(skippedSegment) !== -1) { skippedSegment = null; } visited[segment.id] = true; // Call the callback when the first time. if (!skippedSegment) { resolvedCallback.call(this, segment, controller); if (segment === lastSegment) { controller.skip(); } if (broken) { break; } } } // Update the stack. end = segment.nextSegments.length - 1; if (index < end) { item[1] += 1; stack.push([segment.nextSegments[index], 0]); } else if (index === end) { item[0] = segment.nextSegments[index]; item[1] = 0; } else { stack.pop(); } } } }, { key: "initialSegment", /** * The initial code path segment. * @type {CodePathSegment} */ get: function get() { return this.internal.initialSegment; } /** * Final code path segments. * This array is a mix of `returnedSegments` and `thrownSegments`. * @type {CodePathSegment[]} */ }, { key: "finalSegments", get: function get() { return this.internal.finalSegments; } /** * Final code path segments which is with `return` statements. * This array contains the last path segment if it's reachable. * Since the reachable last path returns `undefined`. * @type {CodePathSegment[]} */ }, { key: "returnedSegments", get: function get() { return this.internal.returnedForkContext; } /** * Final code path segments which is with `throw` statements. * @type {CodePathSegment[]} */ }, { key: "thrownSegments", get: function get() { return this.internal.thrownForkContext; } /** * Current code path segments. * @type {CodePathSegment[]} */ }, { key: "currentSegments", get: function get() { return this.internal.currentSegments; } }], [{ key: "getState", value: function getState(codePath) { return codePath.internal; } }]); return CodePath; }(); module.exports = CodePath; },{"./code-path-state":114,"./id-generator":118}],116:[function(require,module,exports){ /** * @fileoverview Helpers to debug for code path analysis. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var debug = require("debug")("eslint:code-path"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets id of a given segment. * @param {CodePathSegment} segment - A segment to get. * @returns {string} Id of the segment. */ /* istanbul ignore next */ function getId(segment) { // eslint-disable-line require-jsdoc return segment.id + (segment.reachable ? "" : "!"); } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = { /** * A flag that debug dumping is enabled or not. * @type {boolean} */ enabled: debug.enabled, /** * Dumps given objects. * * @param {...any} args - objects to dump. * @returns {void} */ dump: debug, /** * Dumps the current analyzing state. * * @param {ASTNode} node - A node to dump. * @param {CodePathState} state - A state to dump. * @param {boolean} leaving - A flag whether or not it's leaving * @returns {void} */ dumpState: !debug.enabled ? debug : /* istanbul ignore next */function (node, state, leaving) { for (var i = 0; i < state.currentSegments.length; ++i) { var segInternal = state.currentSegments[i].internal; if (leaving) { segInternal.exitNodes.push(node); } else { segInternal.nodes.push(node); } } debug([state.currentSegments.map(getId).join(",") + ")", "" + node.type + (leaving ? ":exit" : "")].join(" ")); }, /** * Dumps a DOT code of a given code path. * The DOT code can be visialized with Graphvis. * * @param {CodePath} codePath - A code path to dump. * @returns {void} * @see http://www.graphviz.org * @see http://www.webgraphviz.com */ dumpDot: !debug.enabled ? debug : /* istanbul ignore next */function (codePath) { var text = "\n" + "digraph {\n" + "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" + "initial[label=\"\",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n"; if (codePath.returnedSegments.length > 0) { text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n"; } if (codePath.thrownSegments.length > 0) { text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n"; } var traceMap = Object.create(null); var arrows = this.makeDotArrows(codePath, traceMap); for (var id in traceMap) { // eslint-disable-line guard-for-in var segment = traceMap[id]; text += id + "["; if (segment.reachable) { text += "label=\""; } else { text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<>\\n"; } if (segment.internal.nodes.length > 0 || segment.internal.exitNodes.length > 0) { text += [].concat(segment.internal.nodes.map(function (node) { switch (node.type) { case "Identifier": return node.type + " (" + node.name + ")"; case "Literal": return node.type + " (" + node.value + ")"; default: return node.type; } }), segment.internal.exitNodes.map(function (node) { switch (node.type) { case "Identifier": return node.type + ":exit (" + node.name + ")"; case "Literal": return node.type + ":exit (" + node.value + ")"; default: return node.type + ":exit"; } })).join("\\n"); } else { text += "????"; } text += "\"];\n"; } text += arrows + "\n"; text += "}"; debug("DOT", text); }, /** * Makes a DOT code of a given code path. * The DOT code can be visialized with Graphvis. * * @param {CodePath} codePath - A code path to make DOT. * @param {Object} traceMap - Optional. A map to check whether or not segments had been done. * @returns {string} A DOT code of the code path. */ makeDotArrows: function makeDotArrows(codePath, traceMap) { var stack = [[codePath.initialSegment, 0]]; var done = traceMap || Object.create(null); var lastId = codePath.initialSegment.id; var text = "initial->" + codePath.initialSegment.id; while (stack.length > 0) { var item = stack.pop(); var segment = item[0]; var index = item[1]; if (done[segment.id] && index === 0) { continue; } done[segment.id] = segment; var nextSegment = segment.allNextSegments[index]; if (!nextSegment) { continue; } if (lastId === segment.id) { text += "->" + nextSegment.id; } else { text += ";\n" + segment.id + "->" + nextSegment.id; } lastId = nextSegment.id; stack.unshift([segment, 1 + index]); stack.push([nextSegment, 0]); } codePath.returnedSegments.forEach(function (finalSegment) { if (lastId === finalSegment.id) { text += "->final"; } else { text += ";\n" + finalSegment.id + "->final"; } lastId = null; }); codePath.thrownSegments.forEach(function (finalSegment) { if (lastId === finalSegment.id) { text += "->thrown"; } else { text += ";\n" + finalSegment.id + "->thrown"; } lastId = null; }); return text + ";"; } }; },{"debug":53}],117:[function(require,module,exports){ /** * @fileoverview A class to operate forking. * * This is state of forking. * This has a fork list and manages it. * * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var assert = require("assert"), CodePathSegment = require("./code-path-segment"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets whether or not a given segment is reachable. * * @param {CodePathSegment} segment - A segment to get. * @returns {boolean} `true` if the segment is reachable. */ function isReachable(segment) { return segment.reachable; } /** * Creates new segments from the specific range of `context.segmentsList`. * * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and * `end` is `-1`, this creates `[g, h]`. This `g` is from `a`, `c`, and `e`. * This `h` is from `b`, `d`, and `f`. * * @param {ForkContext} context - An instance. * @param {number} begin - The first index of the previous segments. * @param {number} end - The last index of the previous segments. * @param {Function} create - A factory function of new segments. * @returns {CodePathSegment[]} New segments. */ function makeSegments(context, begin, end, create) { var list = context.segmentsList; var normalizedBegin = begin >= 0 ? begin : list.length + begin; var normalizedEnd = end >= 0 ? end : list.length + end; var segments = []; for (var i = 0; i < context.count; ++i) { var allPrevSegments = []; for (var j = normalizedBegin; j <= normalizedEnd; ++j) { allPrevSegments.push(list[j][i]); } segments.push(create(context.idGenerator.next(), allPrevSegments)); } return segments; } /** * `segments` becomes doubly in a `finally` block. Then if a code path exits by a * control statement (such as `break`, `continue`) from the `finally` block, the * destination's segments may be half of the source segments. In that case, this * merges segments. * * @param {ForkContext} context - An instance. * @param {CodePathSegment[]} segments - Segments to merge. * @returns {CodePathSegment[]} The merged segments. */ function mergeExtraSegments(context, segments) { var currentSegments = segments; while (currentSegments.length > context.count) { var merged = []; for (var i = 0, length = currentSegments.length / 2 | 0; i < length; ++i) { merged.push(CodePathSegment.newNext(context.idGenerator.next(), [currentSegments[i], currentSegments[i + length]])); } currentSegments = merged; } return currentSegments; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * A class to manage forking. */ var ForkContext = function () { /** * @param {IdGenerator} idGenerator - An identifier generator for segments. * @param {ForkContext|null} upper - An upper fork context. * @param {number} count - A number of parallel segments. */ function ForkContext(idGenerator, upper, count) { _classCallCheck(this, ForkContext); this.idGenerator = idGenerator; this.upper = upper; this.count = count; this.segmentsList = []; } /** * The head segments. * @type {CodePathSegment[]} */ _createClass(ForkContext, [{ key: "makeNext", /** * Creates new segments from this context. * * @param {number} begin - The first index of previous segments. * @param {number} end - The last index of previous segments. * @returns {CodePathSegment[]} New segments. */ value: function makeNext(begin, end) { return makeSegments(this, begin, end, CodePathSegment.newNext); } /** * Creates new segments from this context. * The new segments is always unreachable. * * @param {number} begin - The first index of previous segments. * @param {number} end - The last index of previous segments. * @returns {CodePathSegment[]} New segments. */ }, { key: "makeUnreachable", value: function makeUnreachable(begin, end) { return makeSegments(this, begin, end, CodePathSegment.newUnreachable); } /** * Creates new segments from this context. * The new segments don't have connections for previous segments. * But these inherit the reachable flag from this context. * * @param {number} begin - The first index of previous segments. * @param {number} end - The last index of previous segments. * @returns {CodePathSegment[]} New segments. */ }, { key: "makeDisconnected", value: function makeDisconnected(begin, end) { return makeSegments(this, begin, end, CodePathSegment.newDisconnected); } /** * Adds segments into this context. * The added segments become the head. * * @param {CodePathSegment[]} segments - Segments to add. * @returns {void} */ }, { key: "add", value: function add(segments) { assert(segments.length >= this.count, segments.length + " >= " + this.count); this.segmentsList.push(mergeExtraSegments(this, segments)); } /** * Replaces the head segments with given segments. * The current head segments are removed. * * @param {CodePathSegment[]} segments - Segments to add. * @returns {void} */ }, { key: "replaceHead", value: function replaceHead(segments) { assert(segments.length >= this.count, segments.length + " >= " + this.count); this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments)); } /** * Adds all segments of a given fork context into this context. * * @param {ForkContext} context - A fork context to add. * @returns {void} */ }, { key: "addAll", value: function addAll(context) { assert(context.count === this.count); var source = context.segmentsList; for (var i = 0; i < source.length; ++i) { this.segmentsList.push(source[i]); } } /** * Clears all secments in this context. * * @returns {void} */ }, { key: "clear", value: function clear() { this.segmentsList = []; } /** * Creates the root fork context. * * @param {IdGenerator} idGenerator - An identifier generator for segments. * @returns {ForkContext} New fork context. */ }, { key: "head", get: function get() { var list = this.segmentsList; return list.length === 0 ? [] : list[list.length - 1]; } /** * A flag which shows empty. * @type {boolean} */ }, { key: "empty", get: function get() { return this.segmentsList.length === 0; } /** * A flag which shows reachable. * @type {boolean} */ }, { key: "reachable", get: function get() { var segments = this.head; return segments.length > 0 && segments.some(isReachable); } }], [{ key: "newRoot", value: function newRoot(idGenerator) { var context = new ForkContext(idGenerator, null, 1); context.add([CodePathSegment.newRoot(idGenerator.next())]); return context; } /** * Creates an empty fork context preceded by a given context. * * @param {ForkContext} parentContext - The parent fork context. * @param {boolean} forkLeavingPath - A flag which shows inside of `finally` block. * @returns {ForkContext} New fork context. */ }, { key: "newEmpty", value: function newEmpty(parentContext, forkLeavingPath) { return new ForkContext(parentContext.idGenerator, parentContext, (forkLeavingPath ? 2 : 1) * parentContext.count); } }]); return ForkContext; }(); module.exports = ForkContext; },{"./code-path-segment":113,"assert":46}],118:[function(require,module,exports){ /** * @fileoverview A class of identifiers generator for code path segments. * * Each rule uses the identifier of code path segments to store additional * information of the code path. * * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * A generator for unique ids. */ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var IdGenerator = function () { /** * @param {string} prefix - Optional. A prefix of generated ids. */ function IdGenerator(prefix) { _classCallCheck(this, IdGenerator); this.prefix = String(prefix); this.n = 0; } /** * Generates id. * * @returns {string} A generated id. */ _createClass(IdGenerator, [{ key: "next", value: function next() { this.n = 1 + this.n | 0; /* istanbul ignore if */ if (this.n < 0) { this.n = 1; } return this.prefix + this.n; } }]); return IdGenerator; }(); module.exports = IdGenerator; },{}],119:[function(require,module,exports){ /** * @fileoverview Config file operations. This file must be usable in the browser, * so no Node-specific code can be here. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var minimatch = require("minimatch"), path = require("path"); var debug = require("debug")("eslint:config-ops"); //------------------------------------------------------------------------------ // Private //------------------------------------------------------------------------------ var RULE_SEVERITY_STRINGS = ["off", "warn", "error"], RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce(function (map, value, index) { map[value] = index; return map; }, {}), VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = { /** * Creates an empty configuration object suitable for merging as a base. * @returns {Object} A configuration object. */ createEmptyConfig: function createEmptyConfig() { return { globals: {}, env: {}, rules: {}, parserOptions: {} }; }, /** * Creates an environment config based on the specified environments. * @param {Object} env The environment settings. * @param {Environments} envContext The environment context. * @returns {Object} A configuration object with the appropriate rules and globals * set. */ createEnvironmentConfig: function createEnvironmentConfig(env, envContext) { var envConfig = this.createEmptyConfig(); if (env) { envConfig.env = env; Object.keys(env).filter(function (name) { return env[name]; }).forEach(function (name) { var environment = envContext.get(name); if (environment) { debug("Creating config for environment " + name); if (environment.globals) { Object.assign(envConfig.globals, environment.globals); } if (environment.parserOptions) { Object.assign(envConfig.parserOptions, environment.parserOptions); } } }); } return envConfig; }, /** * Given a config with environment settings, applies the globals and * ecmaFeatures to the configuration and returns the result. * @param {Object} config The configuration information. * @param {Environments} envContent env context. * @returns {Object} The updated configuration information. */ applyEnvironments: function applyEnvironments(config, envContent) { if (config.env && _typeof(config.env) === "object") { debug("Apply environment settings to config"); return this.merge(this.createEnvironmentConfig(config.env, envContent), config); } return config; }, /** * Merges two config objects. This will not only add missing keys, but will also modify values to match. * @param {Object} target config object * @param {Object} src config object. Overrides in this config object will take priority over base. * @param {boolean} [combine] Whether to combine arrays or not * @param {boolean} [isRule] Whether its a rule * @returns {Object} merged config object. */ merge: function deepmerge(target, src, combine, isRule) { /* * The MIT License (MIT) * * Copyright (c) 2012 Nicholas Fisher * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* * This code is taken from deepmerge repo * (https://github.com/KyleAMathews/deepmerge) * and modified to meet our needs. */ var array = Array.isArray(src) || Array.isArray(target); var dst = array && [] || {}; if (array) { var resolvedTarget = target || []; // src could be a string, so check for array if (isRule && Array.isArray(src) && src.length > 1) { dst = dst.concat(src); } else { dst = dst.concat(resolvedTarget); } var resolvedSrc = (typeof src === "undefined" ? "undefined" : _typeof(src)) === "object" ? src : [src]; Object.keys(resolvedSrc).forEach(function (_, i) { var e = resolvedSrc[i]; if (typeof dst[i] === "undefined") { dst[i] = e; } else if ((typeof e === "undefined" ? "undefined" : _typeof(e)) === "object") { if (isRule) { dst[i] = e; } else { dst[i] = deepmerge(resolvedTarget[i], e, combine, isRule); } } else { if (!combine) { dst[i] = e; } else { if (dst.indexOf(e) === -1) { dst.push(e); } } } }); } else { if (target && (typeof target === "undefined" ? "undefined" : _typeof(target)) === "object") { Object.keys(target).forEach(function (key) { dst[key] = target[key]; }); } Object.keys(src).forEach(function (key) { if (key === "overrides") { dst[key] = (target[key] || []).concat(src[key] || []); } else if (Array.isArray(src[key]) || Array.isArray(target[key])) { dst[key] = deepmerge(target[key], src[key], key === "plugins" || key === "extends", isRule); } else if (_typeof(src[key]) !== "object" || !src[key] || key === "exported" || key === "astGlobals") { dst[key] = src[key]; } else { dst[key] = deepmerge(target[key] || {}, src[key], combine, key === "rules"); } }); } return dst; }, /** * Normalizes the severity value of a rule's configuration to a number * @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally * received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0), * the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array * whose first element is one of the above values. Strings are matched case-insensitively. * @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0. */ getRuleSeverity: function getRuleSeverity(ruleConfig) { var severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; if (severityValue === 0 || severityValue === 1 || severityValue === 2) { return severityValue; } if (typeof severityValue === "string") { return RULE_SEVERITY[severityValue.toLowerCase()] || 0; } return 0; }, /** * Converts old-style severity settings (0, 1, 2) into new-style * severity settings (off, warn, error) for all rules. Assumption is that severity * values have already been validated as correct. * @param {Object} config The config object to normalize. * @returns {void} */ normalizeToStrings: function normalizeToStrings(config) { if (config.rules) { Object.keys(config.rules).forEach(function (ruleId) { var ruleConfig = config.rules[ruleId]; if (typeof ruleConfig === "number") { config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") { ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0]; } }); } }, /** * Determines if the severity for the given rule configuration represents an error. * @param {int|string|Array} ruleConfig The configuration for an individual rule. * @returns {boolean} True if the rule represents an error, false if not. */ isErrorSeverity: function isErrorSeverity(ruleConfig) { return module.exports.getRuleSeverity(ruleConfig) === 2; }, /** * Checks whether a given config has valid severity or not. * @param {number|string|Array} ruleConfig - The configuration for an individual rule. * @returns {boolean} `true` if the configuration has valid severity. */ isValidSeverity: function isValidSeverity(ruleConfig) { var severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; if (typeof severity === "string") { severity = severity.toLowerCase(); } return VALID_SEVERITIES.indexOf(severity) !== -1; }, /** * Checks whether every rule of a given config has valid severity or not. * @param {Object} config - The configuration for rules. * @returns {boolean} `true` if the configuration has valid severity. */ isEverySeverityValid: function isEverySeverityValid(config) { var _this = this; return Object.keys(config).every(function (ruleId) { return _this.isValidSeverity(config[ruleId]); }); }, /** * Merges all configurations in a given config vector. A vector is an array of objects, each containing a config * file path and a list of subconfig indices that match the current file path. All config data is assumed to be * cached. * @param {Array} vector list of config files and their subconfig indices that match the current file path * @param {Object} configCache the config cache * @returns {Object} config object */ getConfigFromVector: function getConfigFromVector(vector, configCache) { var cachedConfig = configCache.getMergedVectorConfig(vector); if (cachedConfig) { return cachedConfig; } debug("Using config from partial cache"); var subvector = Array.from(vector); var nearestCacheIndex = subvector.length - 1, partialCachedConfig = void 0; while (nearestCacheIndex >= 0) { partialCachedConfig = configCache.getMergedVectorConfig(subvector); if (partialCachedConfig) { break; } subvector.pop(); nearestCacheIndex--; } if (!partialCachedConfig) { partialCachedConfig = {}; } var finalConfig = partialCachedConfig; // Start from entry immediately following nearest cached config (first uncached entry) for (var i = nearestCacheIndex + 1; i < vector.length; i++) { finalConfig = this.mergeVectorEntry(finalConfig, vector[i], configCache); configCache.setMergedVectorConfig(vector.slice(0, i + 1), finalConfig); } return finalConfig; }, /** * Merges the config options from a single vector entry into the supplied config. * @param {Object} config the base config to merge the vector entry's options into * @param {Object} vectorEntry a single entry from a vector, consisting of a config file path and an array of * matching override indices * @param {Object} configCache the config cache * @returns {Object} merged config object */ mergeVectorEntry: function mergeVectorEntry(config, vectorEntry, configCache) { var _this2 = this; var vectorEntryConfig = Object.assign({}, configCache.getConfig(vectorEntry.filePath)); var mergedConfig = Object.assign({}, config), overrides = void 0; if (vectorEntryConfig.overrides) { overrides = vectorEntryConfig.overrides.filter(function (override, overrideIndex) { return vectorEntry.matchingOverrides.indexOf(overrideIndex) !== -1; }); } else { overrides = []; } mergedConfig = this.merge(mergedConfig, vectorEntryConfig); delete mergedConfig.overrides; mergedConfig = overrides.reduce(function (lastConfig, override) { return _this2.merge(lastConfig, override); }, mergedConfig); if (mergedConfig.filePath) { delete mergedConfig.filePath; delete mergedConfig.baseDirectory; } else if (mergedConfig.files) { delete mergedConfig.files; } return mergedConfig; }, /** * Checks that the specified file path matches all of the supplied glob patterns. * @param {string} filePath The file path to test patterns against * @param {string|string[]} patterns One or more glob patterns, of which at least one should match the file path * @param {string|string[]} [excludedPatterns] One or more glob patterns, of which none should match the file path * @returns {boolean} True if all the supplied patterns match the file path, false otherwise */ pathMatchesGlobs: function pathMatchesGlobs(filePath, patterns, excludedPatterns) { var patternList = [].concat(patterns); var excludedPatternList = [].concat(excludedPatterns || []); patternList.concat(excludedPatternList).forEach(function (pattern) { if (path.isAbsolute(pattern) || pattern.includes("..")) { throw new Error("Invalid override pattern (expected relative path not containing '..'): " + pattern); } }); var opts = { matchBase: true }; return patternList.some(function (pattern) { return minimatch(filePath, pattern, opts); }) && !excludedPatternList.some(function (excludedPattern) { return minimatch(filePath, excludedPattern, opts); }); } }; },{"debug":53,"minimatch":93,"path":96}],120:[function(require,module,exports){ (function (process){ /** * @fileoverview Validates configs. * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var path = require("path"), ajv = require("../util/ajv"), lodash = require("lodash"), configSchema = require("../../conf/config-schema.js"), util = require("util"); var ruleValidators = new WeakMap(); //------------------------------------------------------------------------------ // Private //------------------------------------------------------------------------------ var validateSchema = void 0; // Defitions for deprecation warnings. var deprecationWarningMessages = { ESLINT_LEGACY_ECMAFEATURES: "The 'ecmaFeatures' config file property is deprecated, and has no effect.", ESLINT_LEGACY_OBJECT_REST_SPREAD: "The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead." }; var severityMap = { error: 2, warn: 1, off: 0 }; /** * Gets a complete options schema for a rule. * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object * @returns {Object} JSON Schema for the rule's options. */ function getRuleOptionsSchema(rule) { var schema = rule.schema || rule.meta && rule.meta.schema; // Given a tuple of schemas, insert warning level at the beginning if (Array.isArray(schema)) { if (schema.length) { return { type: "array", items: schema, minItems: 0, maxItems: schema.length }; } return { type: "array", minItems: 0, maxItems: 0 }; } // Given a full schema, leave it alone return schema || null; } /** * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. * @param {options} options The given options for the rule. * @returns {number|string} The rule's severity value */ function validateRuleSeverity(options) { var severity = Array.isArray(options) ? options[0] : options; var normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity; if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { return normSeverity; } throw new Error("\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '" + util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "") + "').\n"); } /** * Validates the non-severity options passed to a rule, based on its schema. * @param {{create: Function}} rule The rule to validate * @param {Array} localOptions The options for the rule, excluding severity * @returns {void} */ function validateRuleSchema(rule, localOptions) { if (!ruleValidators.has(rule)) { var schema = getRuleOptionsSchema(rule); if (schema) { ruleValidators.set(rule, ajv.compile(schema)); } } var validateRule = ruleValidators.get(rule); if (validateRule) { validateRule(localOptions); if (validateRule.errors) { throw new Error(validateRule.errors.map(function (error) { return "\tValue " + JSON.stringify(error.data) + " " + error.message + ".\n"; }).join("")); } } } /** * Validates a rule's options against its schema. * @param {{create: Function}|null} rule The rule that the config is being validated for * @param {string} ruleId The rule's unique name. * @param {Array|number} options The given options for the rule. * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, * no source is prepended to the message. * @returns {void} */ function validateRuleOptions(rule, ruleId, options, source) { if (!rule) { return; } try { var severity = validateRuleSeverity(options); if (severity !== 0) { validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); } } catch (err) { var enhancedMessage = "Configuration for rule \"" + ruleId + "\" is invalid:\n" + err.message; if (typeof source === "string") { throw new Error(source + ":\n\t" + enhancedMessage); } else { throw new Error(enhancedMessage); } } } /** * Validates an environment object * @param {Object} environment The environment config object to validate. * @param {string} source The name of the configuration source to report in any errors. * @param {Environments} envContext Env context * @returns {void} */ function validateEnvironment(environment, source, envContext) { // not having an environment is ok if (!environment) { return; } Object.keys(environment).forEach(function (env) { if (!envContext.get(env)) { var message = source + ":\n\tEnvironment key \"" + env + "\" is unknown\n"; throw new Error(message); } }); } /** * Validates a rules config object * @param {Object} rulesConfig The rules config object to validate. * @param {string} source The name of the configuration source to report in any errors. * @param {function(string): {create: Function}} ruleMapper A mapper function from strings to loaded rules * @returns {void} */ function validateRules(rulesConfig, source, ruleMapper) { if (!rulesConfig) { return; } Object.keys(rulesConfig).forEach(function (id) { validateRuleOptions(ruleMapper(id), id, rulesConfig[id], source); }); } /** * Formats an array of schema validation errors. * @param {Array} errors An array of error messages to format. * @returns {string} Formatted error message */ function formatErrors(errors) { return errors.map(function (error) { if (error.keyword === "additionalProperties") { var formattedPropertyPath = error.dataPath.length ? error.dataPath.slice(1) + "." + error.params.additionalProperty : error.params.additionalProperty; return "Unexpected top-level property \"" + formattedPropertyPath + "\""; } if (error.keyword === "type") { var formattedField = error.dataPath.slice(1); var formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; var formattedValue = JSON.stringify(error.data); return "Property \"" + formattedField + "\" is the wrong type (expected " + formattedExpectedType + " but got `" + formattedValue + "`)"; } var field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; return "\"" + field + "\" " + error.message + ". Value: " + JSON.stringify(error.data); }).map(function (message) { return "\t- " + message + ".\n"; }).join(""); } /** * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted * for each unique file path, but repeated invocations with the same file path have no effect. * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. * @param {string} source The name of the configuration source to report the warning for. * @param {string} errorCode The warning message to show. * @returns {void} */ var emitDeprecationWarning = lodash.memoize(function (source, errorCode) { var rel = path.relative(process.cwd(), source); var message = deprecationWarningMessages[errorCode]; process.emitWarning(message + " (found in \"" + rel + "\")", "DeprecationWarning", errorCode); }); /** * Validates the top level properties of the config object. * @param {Object} config The config object to validate. * @param {string} source The name of the configuration source to report in any errors. * @returns {void} */ function validateConfigSchema(config, source) { validateSchema = validateSchema || ajv.compile(configSchema); if (!validateSchema(config)) { throw new Error("ESLint configuration in " + source + " is invalid:\n" + formatErrors(validateSchema.errors)); } if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES"); } if ((config.parser || "espree") === "espree" && config.parserOptions && config.parserOptions.ecmaFeatures && config.parserOptions.ecmaFeatures.experimentalObjectRestSpread) { emitDeprecationWarning(source, "ESLINT_LEGACY_OBJECT_REST_SPREAD"); } } /** * Validates an entire config object. * @param {Object} config The config object to validate. * @param {string} source The name of the configuration source to report in any errors. * @param {function(string): {create: Function}} ruleMapper A mapper function from rule IDs to defined rules * @param {Environments} envContext The env context * @returns {void} */ function validate(config, source, ruleMapper, envContext) { validateConfigSchema(config, source); validateRules(config.rules, source, ruleMapper); validateEnvironment(config.env, source, envContext); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (config.overrides || [])[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var override = _step.value; validateRules(override.rules, source, ruleMapper); validateEnvironment(override.env, source, envContext); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = { getRuleOptionsSchema: getRuleOptionsSchema, validate: validate, validateRuleOptions: validateRuleOptions }; }).call(this,require('_process')) },{"../../conf/config-schema.js":1,"../util/ajv":403,"_process":103,"lodash":92,"path":96,"util":110}],121:[function(require,module,exports){ /** * @fileoverview Environments manager * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var envs = require("../../conf/environments"); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ var Environments = function () { /** * create env context */ function Environments() { _classCallCheck(this, Environments); this._environments = new Map(); this.load(); } /** * Loads the default environments. * @returns {void} * @private */ _createClass(Environments, [{ key: "load", value: function load() { var _this = this; Object.keys(envs).forEach(function (envName) { _this._environments.set(envName, envs[envName]); }); } /** * Gets the environment with the given name. * @param {string} name The name of the environment to retrieve. * @returns {Object?} The environment object or null if not found. */ }, { key: "get", value: function get(name) { return this._environments.get(name) || null; } /** * Gets all the environment present * @returns {Object} The environment object for each env name */ }, { key: "getAll", value: function getAll() { return Array.from(this._environments).reduce(function (coll, env) { coll[env[0]] = env[1]; return coll; }, {}); } /** * Defines an environment. * @param {string} name The name of the environment. * @param {Object} env The environment settings. * @returns {void} */ }, { key: "define", value: function define(name, env) { this._environments.set(name, env); } /** * Imports all environments from a plugin. * @param {Object} plugin The plugin object. * @param {string} pluginName The name of the plugin. * @returns {void} */ }, { key: "importPlugin", value: function importPlugin(plugin, pluginName) { var _this2 = this; if (plugin.environments) { Object.keys(plugin.environments).forEach(function (envName) { _this2.define(pluginName + "/" + envName, plugin.environments[envName]); }); } } }]); return Environments; }(); module.exports = Environments; },{"../../conf/environments":2}],122:[function(require,module,exports){ /** * @fileoverview Main Linter Class * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var eslintScope = require("eslint-scope"), evk = require("eslint-visitor-keys"), lodash = require("lodash"), CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"), ConfigOps = require("./config/config-ops"), validator = require("./config/config-validator"), Environments = require("./config/environments"), applyDisableDirectives = require("./util/apply-disable-directives"), createEmitter = require("./util/safe-emitter"), NodeEventGenerator = require("./util/node-event-generator"), SourceCode = require("./util/source-code"), Traverser = require("./util/traverser"), createReportTranslator = require("./util/report-translator"), Rules = require("./rules"), timing = require("./util/timing"), ConfigCommentParser = require("./util/config-comment-parser"), astUtils = require("./util/ast-utils"), pkg = require("../package.json"), SourceCodeFixer = require("./util/source-code-fixer"); var debug = require("debug")("eslint:linter"); var MAX_AUTOFIX_PASSES = 10; var DEFAULT_PARSER_NAME = "espree"; var commentParser = new ConfigCommentParser(); //------------------------------------------------------------------------------ // Typedefs //------------------------------------------------------------------------------ /** * The result of a parsing operation from parseForESLint() * @typedef {Object} CustomParseResult * @property {ASTNode} ast The ESTree AST Program node. * @property {Object} services An object containing additional services related * to the parser. * @property {ScopeManager|null} scopeManager The scope manager object of this AST. * @property {Object|null} visitorKeys The visitor keys to traverse this AST. */ /** * @typedef {Object} DisableDirective * @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type * @property {number} line * @property {number} column * @property {(string|null)} ruleId */ //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Ensures that variables representing built-in properties of the Global Object, * and any globals declared by special block comments, are present in the global * scope. * @param {Scope} globalScope The global scope. * @param {Object} configGlobals The globals declared in configuration * @param {{exportedVariables: Object, enabledGlobals: Object}} commentDirectives Directives from comment configuration * @returns {void} */ function addDeclaredGlobals(globalScope, configGlobals, commentDirectives) { Object.keys(configGlobals).forEach(function (name) { var variable = globalScope.set.get(name); if (!variable) { variable = new eslintScope.Variable(name, globalScope); variable.eslintExplicitGlobal = false; globalScope.variables.push(variable); globalScope.set.set(name, variable); } variable.writeable = configGlobals[name]; }); Object.keys(commentDirectives.enabledGlobals).forEach(function (name) { var variable = globalScope.set.get(name); if (!variable) { variable = new eslintScope.Variable(name, globalScope); variable.eslintExplicitGlobal = true; variable.eslintExplicitGlobalComment = commentDirectives.enabledGlobals[name].comment; globalScope.variables.push(variable); globalScope.set.set(name, variable); } variable.writeable = commentDirectives.enabledGlobals[name].value; }); // mark all exported variables as such Object.keys(commentDirectives.exportedVariables).forEach(function (name) { var variable = globalScope.set.get(name); if (variable) { variable.eslintUsed = true; } }); /* * "through" contains all references which definitions cannot be found. * Since we augment the global scope using configuration, we need to update * references and remove the ones that were added by configuration. */ globalScope.through = globalScope.through.filter(function (reference) { var name = reference.identifier.name; var variable = globalScope.set.get(name); if (variable) { /* * Links the variable and the reference. * And this reference is removed from `Scope#through`. */ reference.resolved = variable; variable.references.push(reference); return false; } return true; }); } /** * Creates a collection of disable directives from a comment * @param {("disable"|"enable"|"disable-line"|"disable-next-line")} type The type of directive comment * @param {{line: number, column: number}} loc The 0-based location of the comment token * @param {string} value The value after the directive in the comment * comment specified no specific rules, so it applies to all rules (e.g. `eslint-disable`) * @returns {DisableDirective[]} Directives from the comment */ function createDisableDirectives(type, loc, value) { var ruleIds = Object.keys(commentParser.parseListConfig(value)); var directiveRules = ruleIds.length ? ruleIds : [null]; return directiveRules.map(function (ruleId) { return { type: type, line: loc.line, column: loc.column + 1, ruleId: ruleId }; }); } /** * Parses comments in file to extract file-specific config of rules, globals * and environments and merges them with global config; also code blocks * where reporting is disabled or enabled and merges them with reporting config. * @param {string} filename The file being checked. * @param {ASTNode} ast The top node of the AST. * @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules * @returns {{configuredRules: Object, enabledGlobals: Object, exportedVariables: Object, problems: Problem[], disableDirectives: DisableDirective[]}} * A collection of the directive comments that were found, along with any problems that occurred when parsing */ function getDirectiveComments(filename, ast, ruleMapper) { var configuredRules = {}; var enabledGlobals = {}; var exportedVariables = {}; var problems = []; var disableDirectives = []; ast.comments.filter(function (token) { return token.type !== "Shebang"; }).forEach(function (comment) { var trimmedCommentText = comment.value.trim(); var match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(trimmedCommentText); if (!match) { return; } var directiveValue = trimmedCommentText.slice(match.index + match[1].length); if (/^eslint-disable-(next-)?line$/.test(match[1])) { if (comment.loc.start.line === comment.loc.end.line) { var directiveType = match[1].slice("eslint-".length); disableDirectives.push.apply(disableDirectives, _toConsumableArray(createDisableDirectives(directiveType, comment.loc.start, directiveValue))); } else { problems.push({ ruleId: null, severity: 2, message: match[1] + " comment should not span multiple lines.", line: comment.loc.start.line, column: comment.loc.start.column + 1, endLine: comment.loc.end.line, endColumn: comment.loc.end.column + 1, nodeType: null }); } } else if (comment.type === "Block") { switch (match[1]) { case "exported": Object.assign(exportedVariables, commentParser.parseBooleanConfig(directiveValue, comment)); break; case "globals": case "global": Object.assign(enabledGlobals, commentParser.parseBooleanConfig(directiveValue, comment)); break; case "eslint-disable": disableDirectives.push.apply(disableDirectives, _toConsumableArray(createDisableDirectives("disable", comment.loc.start, directiveValue))); break; case "eslint-enable": disableDirectives.push.apply(disableDirectives, _toConsumableArray(createDisableDirectives("enable", comment.loc.start, directiveValue))); break; case "eslint": { var parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc); if (parseResult.success) { Object.keys(parseResult.config).forEach(function (name) { var ruleValue = parseResult.config[name]; try { validator.validateRuleOptions(ruleMapper(name), name, ruleValue); } catch (err) { problems.push({ ruleId: name, severity: 2, message: err.message, line: comment.loc.start.line, column: comment.loc.start.column + 1, endLine: comment.loc.end.line, endColumn: comment.loc.end.column + 1, nodeType: null }); } configuredRules[name] = ruleValue; }); } else { problems.push(parseResult.error); } break; } // no default } } }); return { configuredRules: configuredRules, enabledGlobals: enabledGlobals, exportedVariables: exportedVariables, problems: problems, disableDirectives: disableDirectives }; } /** * Normalize ECMAScript version from the initial config * @param {number} ecmaVersion ECMAScript version from the initial config * @param {boolean} isModule Whether the source type is module or not * @returns {number} normalized ECMAScript version */ function normalizeEcmaVersion(ecmaVersion, isModule) { // Need at least ES6 for modules if (isModule && (!ecmaVersion || ecmaVersion < 6)) { return 6; } /* * Calculate ECMAScript edition number from official year version starting with * ES2015, which corresponds with ES6 (or a difference of 2009). */ if (ecmaVersion >= 2015) { return ecmaVersion - 2009; } return ecmaVersion; } var eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g; /** * Checks whether or not there is a comment which has "eslint-env *" in a given text. * @param {string} text - A source code text to check. * @returns {Object|null} A result of parseListConfig() with "eslint-env *" comment. */ function findEslintEnv(text) { var match = void 0, retv = void 0; eslintEnvPattern.lastIndex = 0; while (match = eslintEnvPattern.exec(text)) { retv = Object.assign(retv || {}, commentParser.parseListConfig(match[1])); } return retv; } /** * Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a * consistent shape. * @param {(string|{reportUnusedDisableDirectives: boolean, filename: string, allowInlineConfig: boolean})} providedOptions Options * @returns {{reportUnusedDisableDirectives: boolean, filename: string, allowInlineConfig: boolean}} Normalized options */ function normalizeVerifyOptions(providedOptions) { var isObjectOptions = (typeof providedOptions === "undefined" ? "undefined" : _typeof(providedOptions)) === "object"; var providedFilename = isObjectOptions ? providedOptions.filename : providedOptions; return { filename: typeof providedFilename === "string" ? providedFilename : "", allowInlineConfig: !isObjectOptions || providedOptions.allowInlineConfig !== false, reportUnusedDisableDirectives: isObjectOptions && !!providedOptions.reportUnusedDisableDirectives }; } /** * Combines the provided parserOptions with the options from environments * @param {string} parserName The parser name which uses this options. * @param {Object} providedOptions The provided 'parserOptions' key in a config * @param {Environment[]} enabledEnvironments The environments enabled in configuration and with inline comments * @returns {Object} Resulting parser options after merge */ function resolveParserOptions(parserName, providedOptions, enabledEnvironments) { var parserOptionsFromEnv = enabledEnvironments.filter(function (env) { return env.parserOptions; }).reduce(function (parserOptions, env) { return ConfigOps.merge(parserOptions, env.parserOptions); }, {}); var mergedParserOptions = ConfigOps.merge(parserOptionsFromEnv, providedOptions || {}); var isModule = mergedParserOptions.sourceType === "module"; if (isModule) { // can't have global return inside of modules mergedParserOptions.ecmaFeatures = Object.assign({}, mergedParserOptions.ecmaFeatures, { globalReturn: false }); } mergedParserOptions.ecmaVersion = normalizeEcmaVersion(mergedParserOptions.ecmaVersion, isModule); // TODO: For backward compatibility. Will remove on v6.0.0. if (parserName === DEFAULT_PARSER_NAME && mergedParserOptions.ecmaFeatures && mergedParserOptions.ecmaFeatures.experimentalObjectRestSpread && (!mergedParserOptions.ecmaVersion || mergedParserOptions.ecmaVersion < 9)) { mergedParserOptions.ecmaVersion = 9; } return mergedParserOptions; } /** * Combines the provided globals object with the globals from environments * @param {Object} providedGlobals The 'globals' key in a config * @param {Environments[]} enabledEnvironments The environments enabled in configuration and with inline comments * @returns {Object} The resolved globals object */ function resolveGlobals(providedGlobals, enabledEnvironments) { return Object.assign.apply(Object, [{}].concat(_toConsumableArray(enabledEnvironments.filter(function (env) { return env.globals; }).map(function (env) { return env.globals; })), [providedGlobals])); } /** * Strips Unicode BOM from a given text. * * @param {string} text - A text to strip. * @returns {string} The stripped text. */ function stripUnicodeBOM(text) { /* * Check Unicode BOM. * In JavaScript, string data is stored as UTF-16, so BOM is 0xFEFF. * http://www.ecma-international.org/ecma-262/6.0/#sec-unicode-format-control-characters */ if (text.charCodeAt(0) === 0xFEFF) { return text.slice(1); } return text; } /** * Get the options for a rule (not including severity), if any * @param {Array|number} ruleConfig rule configuration * @returns {Array} of rule options, empty Array if none */ function getRuleOptions(ruleConfig) { if (Array.isArray(ruleConfig)) { return ruleConfig.slice(1); } return []; } /** * Analyze scope of the given AST. * @param {ASTNode} ast The `Program` node to analyze. * @param {Object} parserOptions The parser options. * @param {Object} visitorKeys The visitor keys. * @returns {ScopeManager} The analysis result. */ function analyzeScope(ast, parserOptions, visitorKeys) { var ecmaFeatures = parserOptions.ecmaFeatures || {}; var ecmaVersion = parserOptions.ecmaVersion || 5; return eslintScope.analyze(ast, { ignoreEval: true, nodejsScope: ecmaFeatures.globalReturn, impliedStrict: ecmaFeatures.impliedStrict, ecmaVersion: ecmaVersion, sourceType: parserOptions.sourceType || "script", childVisitorKeys: visitorKeys || evk.KEYS, fallback: Traverser.getKeys }); } /** * Parses text into an AST. Moved out here because the try-catch prevents * optimization of functions, so it's best to keep the try-catch as isolated * as possible * @param {string} text The text to parse. * @param {Object} providedParserOptions Options to pass to the parser * @param {string} parserName The name of the parser * @param {Map} parserMap A map from names to loaded parsers * @param {string} filePath The path to the file being parsed. * @returns {{success: false, error: Problem}|{success: true, sourceCode: SourceCode}} * An object containing the AST and parser services if parsing was successful, or the error if parsing failed * @private */ function parse(text, providedParserOptions, parserName, parserMap, filePath) { var textToParse = stripUnicodeBOM(text).replace(astUtils.SHEBANG_MATCHER, function (match, captured) { return "//" + captured; }); var parserOptions = Object.assign({}, providedParserOptions, { loc: true, range: true, raw: true, tokens: true, comment: true, eslintVisitorKeys: true, eslintScopeManager: true, filePath: filePath }); var parser = void 0; try { parser = parserMap.get(parserName) || require(parserName); } catch (ex) { return { success: false, error: { ruleId: null, fatal: true, severity: 2, message: ex.message, line: 0, column: 0 } }; } /* * Check for parsing errors first. If there's a parsing error, nothing * else can happen. However, a parsing error does not throw an error * from this method - it's just considered a fatal error message, a * problem that ESLint identified just like any other. */ try { var parseResult = typeof parser.parseForESLint === "function" ? parser.parseForESLint(textToParse, parserOptions) : { ast: parser.parse(textToParse, parserOptions) }; var ast = parseResult.ast; var parserServices = parseResult.services || {}; var visitorKeys = parseResult.visitorKeys || evk.KEYS; var scopeManager = parseResult.scopeManager || analyzeScope(ast, parserOptions, visitorKeys); return { success: true, /* * Save all values that `parseForESLint()` returned. * If a `SourceCode` object is given as the first parameter instead of source code text, * linter skips the parsing process and reuses the source code object. * In that case, linter needs all the values that `parseForESLint()` returned. */ sourceCode: new SourceCode({ text: text, ast: ast, parserServices: parserServices, scopeManager: scopeManager, visitorKeys: visitorKeys }) }; } catch (ex) { // If the message includes a leading line number, strip it: var message = "Parsing error: " + ex.message.replace(/^line \d+:/i, "").trim(); return { success: false, error: { ruleId: null, fatal: true, severity: 2, message: message, line: ex.lineNumber, column: ex.column } }; } } /** * Gets the scope for the current node * @param {ScopeManager} scopeManager The scope manager for this AST * @param {ASTNode} currentNode The node to get the scope of * @returns {eslint-scope.Scope} The scope information for this node */ function _getScope(scopeManager, currentNode) { // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope. var inner = currentNode.type !== "Program"; for (var node = currentNode; node; node = node.parent) { var scope = scopeManager.acquire(node, inner); if (scope) { if (scope.type === "function-expression-name") { return scope.childScopes[0]; } return scope; } } return scopeManager.scopes[0]; } /** * Marks a variable as used in the current scope * @param {ScopeManager} scopeManager The scope manager for this AST. The scope may be mutated by this function. * @param {ASTNode} currentNode The node currently being traversed * @param {Object} parserOptions The options used to parse this text * @param {string} name The name of the variable that should be marked as used. * @returns {boolean} True if the variable was found and marked as used, false if not. */ function _markVariableAsUsed(scopeManager, currentNode, parserOptions, name) { var hasGlobalReturn = parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn; var specialScope = hasGlobalReturn || parserOptions.sourceType === "module"; var currentScope = _getScope(scopeManager, currentNode); // Special Node.js scope means we need to start one level deeper var initialScope = currentScope.type === "global" && specialScope ? currentScope.childScopes[0] : currentScope; for (var scope = initialScope; scope; scope = scope.upper) { var variable = scope.variables.find(function (scopeVar) { return scopeVar.name === name; }); if (variable) { variable.eslintUsed = true; return true; } } return false; } /** * Runs a rule, and gets its listeners * @param {Rule} rule A normalized rule with a `create` method * @param {Context} ruleContext The context that should be passed to the rule * @returns {Object} A map of selector listeners provided by the rule */ function createRuleListeners(rule, ruleContext) { try { return rule.create(ruleContext); } catch (ex) { ex.message = "Error while loading rule '" + ruleContext.id + "': " + ex.message; throw ex; } } /** * Gets all the ancestors of a given node * @param {ASTNode} node The node * @returns {ASTNode[]} All the ancestor nodes in the AST, not including the provided node, starting * from the root node and going inwards to the parent node. */ function _getAncestors(node) { var ancestorsStartingAtParent = []; for (var ancestor = node.parent; ancestor; ancestor = ancestor.parent) { ancestorsStartingAtParent.push(ancestor); } return ancestorsStartingAtParent.reverse(); } // methods that exist on SourceCode object var DEPRECATED_SOURCECODE_PASSTHROUGHS = { getSource: "getText", getSourceLines: "getLines", getAllComments: "getAllComments", getNodeByRangeIndex: "getNodeByRangeIndex", getComments: "getComments", getCommentsBefore: "getCommentsBefore", getCommentsAfter: "getCommentsAfter", getCommentsInside: "getCommentsInside", getJSDocComment: "getJSDocComment", getFirstToken: "getFirstToken", getFirstTokens: "getFirstTokens", getLastToken: "getLastToken", getLastTokens: "getLastTokens", getTokenAfter: "getTokenAfter", getTokenBefore: "getTokenBefore", getTokenByRangeStart: "getTokenByRangeStart", getTokens: "getTokens", getTokensAfter: "getTokensAfter", getTokensBefore: "getTokensBefore", getTokensBetween: "getTokensBetween" }; var BASE_TRAVERSAL_CONTEXT = Object.freeze(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).reduce(function (contextInfo, methodName) { return Object.assign(contextInfo, _defineProperty({}, methodName, function () { var _getSourceCode; return (_getSourceCode = this.getSourceCode())[DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]].apply(_getSourceCode, arguments); })); }, {})); /** * Runs the given rules on the given SourceCode object * @param {SourceCode} sourceCode A SourceCode object for the given text * @param {Object} configuredRules The rules configuration * @param {function(string): Rule} ruleMapper A mapper function from rule names to rules * @param {Object} parserOptions The options that were passed to the parser * @param {string} parserName The name of the parser in the config * @param {Object} settings The settings that were enabled in the config * @param {string} filename The reported filename of the code * @returns {Problem[]} An array of reported problems */ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename) { var emitter = createEmitter(); var nodeQueue = []; var currentNode = sourceCode.ast; Traverser.traverse(sourceCode.ast, { enter: function enter(node, parent) { node.parent = parent; nodeQueue.push({ isEntering: true, node: node }); }, leave: function leave(node) { nodeQueue.push({ isEntering: false, node: node }); }, visitorKeys: sourceCode.visitorKeys }); /* * Create a frozen object with the ruleContext properties and methods that are shared by all rules. * All rule contexts will inherit from this object. This avoids the performance penalty of copying all the * properties once for each rule. */ var sharedTraversalContext = Object.freeze(Object.assign(Object.create(BASE_TRAVERSAL_CONTEXT), { getAncestors: function getAncestors() { return _getAncestors(currentNode); }, getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager), getFilename: function getFilename() { return filename; }, getScope: function getScope() { return _getScope(sourceCode.scopeManager, currentNode); }, getSourceCode: function getSourceCode() { return sourceCode; }, markVariableAsUsed: function markVariableAsUsed(name) { return _markVariableAsUsed(sourceCode.scopeManager, currentNode, parserOptions, name); }, parserOptions: parserOptions, parserPath: parserName, parserServices: sourceCode.parserServices, settings: settings })); var lintingProblems = []; Object.keys(configuredRules).forEach(function (ruleId) { var severity = ConfigOps.getRuleSeverity(configuredRules[ruleId]); if (severity === 0) { return; } var rule = ruleMapper(ruleId); var messageIds = rule.meta && rule.meta.messages; var reportTranslator = null; var ruleContext = Object.freeze(Object.assign(Object.create(sharedTraversalContext), { id: ruleId, options: getRuleOptions(configuredRules[ruleId]), report: function report() { /* * Create a report translator lazily. * In a vast majority of cases, any given rule reports zero errors on a given * piece of code. Creating a translator lazily avoids the performance cost of * creating a new translator function for each rule that usually doesn't get * called. * * Using lazy report translators improves end-to-end performance by about 3% * with Node 8.4.0. */ if (reportTranslator === null) { reportTranslator = createReportTranslator({ ruleId: ruleId, severity: severity, sourceCode: sourceCode, messageIds: messageIds }); } var problem = reportTranslator.apply(undefined, arguments); if (problem.fix && rule.meta && !rule.meta.fixable) { throw new Error("Fixable rules should export a `meta.fixable` property."); } lintingProblems.push(problem); } })); var ruleListeners = createRuleListeners(rule, ruleContext); // add all the selectors from the rule as listeners Object.keys(ruleListeners).forEach(function (selector) { emitter.on(selector, timing.enabled ? timing.time(ruleId, ruleListeners[selector]) : ruleListeners[selector]); }); }); var eventGenerator = new CodePathAnalyzer(new NodeEventGenerator(emitter)); nodeQueue.forEach(function (traversalInfo) { currentNode = traversalInfo.node; if (traversalInfo.isEntering) { eventGenerator.enterNode(currentNode); } else { eventGenerator.leaveNode(currentNode); } }); return lintingProblems; } var lastSourceCodes = new WeakMap(); var loadedParserMaps = new WeakMap(); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * Object that is responsible for verifying JavaScript text * @name eslint */ module.exports = function () { function Linter() { _classCallCheck(this, Linter); lastSourceCodes.set(this, null); loadedParserMaps.set(this, new Map()); this.version = pkg.version; this.rules = new Rules(); this.environments = new Environments(); } /** * Getter for package version. * @static * @returns {string} The version from package.json. */ _createClass(Linter, [{ key: "_verifyWithoutProcessors", /** * Configuration object for the `verify` API. A JS representation of the eslintrc files. * @typedef {Object} ESLintConfig * @property {Object} rules The rule configuration to verify against. * @property {string} [parser] Parser to use when generatig the AST. * @property {Object} [parserOptions] Options for the parsed used. * @property {Object} [settings] Global settings passed to each rule. * @property {Object} [env] The environment to verify in. * @property {Object} [globals] Available globals to the code. */ /** * Same as linter.verify, except without support for processors. * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. * @param {ESLintConfig} providedConfig An ESLintConfig instance to configure everything. * @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked. * If this is not set, the filename will default to '' in the rule context. If * an object, then it has "filename", "saveState", and "allowInlineConfig" properties. * @param {boolean} [filenameOrOptions.allowInlineConfig=true] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied. * Useful if you want to validate JS without comments overriding rules. * @param {boolean} [filenameOrOptions.reportUnusedDisableDirectives=false] Adds reported errors for unused * eslint-disable directives * @returns {Object[]} The results as an array of messages or an empty array if no messages. */ value: function _verifyWithoutProcessors(textOrSourceCode, providedConfig, filenameOrOptions) { var _this = this; var config = providedConfig || {}; var options = normalizeVerifyOptions(filenameOrOptions); var text = void 0; // evaluate arguments if (typeof textOrSourceCode === "string") { lastSourceCodes.set(this, null); text = textOrSourceCode; } else { lastSourceCodes.set(this, textOrSourceCode); text = textOrSourceCode.text; } // search and apply "eslint-env *". var envInFile = findEslintEnv(text); var resolvedEnvConfig = Object.assign({ builtin: true }, config.env, envInFile); var enabledEnvs = Object.keys(resolvedEnvConfig).filter(function (envName) { return resolvedEnvConfig[envName]; }).map(function (envName) { return _this.environments.get(envName); }).filter(function (env) { return env; }); var parserName = config.parser || DEFAULT_PARSER_NAME; var parserOptions = resolveParserOptions(parserName, config.parserOptions || {}, enabledEnvs); var configuredGlobals = resolveGlobals(config.globals || {}, enabledEnvs); var settings = config.settings || {}; if (!lastSourceCodes.get(this)) { var parseResult = parse(text, parserOptions, parserName, loadedParserMaps.get(this), options.filename); if (!parseResult.success) { return [parseResult.error]; } lastSourceCodes.set(this, parseResult.sourceCode); } else { /* * If the given source code object as the first argument does not have scopeManager, analyze the scope. * This is for backward compatibility (SourceCode is frozen so it cannot rebind). */ var lastSourceCode = lastSourceCodes.get(this); if (!lastSourceCode.scopeManager) { lastSourceCodes.set(this, new SourceCode({ text: lastSourceCode.text, ast: lastSourceCode.ast, parserServices: lastSourceCode.parserServices, visitorKeys: lastSourceCode.visitorKeys, scopeManager: analyzeScope(lastSourceCode.ast, parserOptions) })); } } var sourceCode = lastSourceCodes.get(this); var commentDirectives = options.allowInlineConfig ? getDirectiveComments(options.filename, sourceCode.ast, function (ruleId) { return _this.rules.get(ruleId); }) : { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] }; // augment global scope with declared global variables addDeclaredGlobals(sourceCode.scopeManager.scopes[0], configuredGlobals, { exportedVariables: commentDirectives.exportedVariables, enabledGlobals: commentDirectives.enabledGlobals }); var configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules); var lintingProblems = void 0; try { lintingProblems = runRules(sourceCode, configuredRules, function (ruleId) { return _this.rules.get(ruleId); }, parserOptions, parserName, settings, options.filename); } catch (err) { debug("An error occurred while traversing"); debug("Filename:", options.filename); debug("Parser Options:", parserOptions); debug("Parser Path:", parserName); debug("Settings:", settings); throw err; } return applyDisableDirectives({ directives: commentDirectives.disableDirectives, problems: lintingProblems.concat(commentDirectives.problems).sort(function (problemA, problemB) { return problemA.line - problemB.line || problemA.column - problemB.column; }), reportUnusedDisableDirectives: options.reportUnusedDisableDirectives }); } /** * Verifies the text against the rules specified by the second argument. * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. * @param {ESLintConfig} config An ESLintConfig instance to configure everything. * @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked. * If this is not set, the filename will default to '' in the rule context. If * an object, then it has "filename", "saveState", and "allowInlineConfig" properties. * @param {boolean} [filenameOrOptions.allowInlineConfig] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied. * Useful if you want to validate JS without comments overriding rules. * @param {function(string): string[]} [filenameOrOptions.preprocess] preprocessor for source text. If provided, * this should accept a string of source text, and return an array of code blocks to lint. * @param {function(Array): Object[]} [filenameOrOptions.postprocess] postprocessor for report messages. If provided, * this should accept an array of the message lists for each code block returned from the preprocessor, * apply a mapping to the messages as appropriate, and return a one-dimensional array of messages * @returns {Object[]} The results as an array of messages or an empty array if no messages. */ }, { key: "verify", value: function verify(textOrSourceCode, config, filenameOrOptions) { var _this2 = this; var preprocess = filenameOrOptions && filenameOrOptions.preprocess || function (rawText) { return [rawText]; }; var postprocess = filenameOrOptions && filenameOrOptions.postprocess || lodash.flatten; return postprocess(preprocess(textOrSourceCode).map(function (textBlock) { return _this2._verifyWithoutProcessors(textBlock, config, filenameOrOptions); })); } /** * Gets the SourceCode object representing the parsed source. * @returns {SourceCode} The SourceCode object. */ }, { key: "getSourceCode", value: function getSourceCode() { return lastSourceCodes.get(this); } /** * Defines a new linting rule. * @param {string} ruleId A unique rule identifier * @param {Function} ruleModule Function from context to object mapping AST node types to event handlers * @returns {void} */ }, { key: "defineRule", value: function defineRule(ruleId, ruleModule) { this.rules.define(ruleId, ruleModule); } /** * Defines many new linting rules. * @param {Object} rulesToDefine map from unique rule identifier to rule * @returns {void} */ }, { key: "defineRules", value: function defineRules(rulesToDefine) { var _this3 = this; Object.getOwnPropertyNames(rulesToDefine).forEach(function (ruleId) { _this3.defineRule(ruleId, rulesToDefine[ruleId]); }); } /** * Gets an object with all loaded rules. * @returns {Map} All loaded rules */ }, { key: "getRules", value: function getRules() { return this.rules.getAllLoadedRules(); } /** * Define a new parser module * @param {any} parserId Name of the parser * @param {any} parserModule The parser object * @returns {void} */ }, { key: "defineParser", value: function defineParser(parserId, parserModule) { loadedParserMaps.get(this).set(parserId, parserModule); } /** * Performs multiple autofix passes over the text until as many fixes as possible * have been applied. * @param {string} text The source text to apply fixes to. * @param {Object} config The ESLint config object to use. * @param {Object} options The ESLint options object to use. * @param {string} options.filename The filename from which the text was read. * @param {boolean} options.allowInlineConfig Flag indicating if inline comments * should be allowed. * @param {boolean|Function} options.fix Determines whether fixes should be applied * @param {Function} options.preprocess preprocessor for source text. If provided, this should * accept a string of source text, and return an array of code blocks to lint. * @param {Function} options.postprocess postprocessor for report messages. If provided, * this should accept an array of the message lists for each code block returned from the preprocessor, * apply a mapping to the messages as appropriate, and return a one-dimensional array of messages * @returns {Object} The result of the fix operation as returned from the * SourceCodeFixer. */ }, { key: "verifyAndFix", value: function verifyAndFix(text, config, options) { var messages = [], fixedResult = void 0, fixed = false, passNumber = 0, currentText = text; var debugTextDescription = options && options.filename || text.slice(0, 10) + "..."; var shouldFix = options && typeof options.fix !== "undefined" ? options.fix : true; /** * This loop continues until one of the following is true: * * 1. No more fixes have been applied. * 2. Ten passes have been made. * * That means anytime a fix is successfully applied, there will be another pass. * Essentially, guaranteeing a minimum of two passes. */ do { passNumber++; debug("Linting code for " + debugTextDescription + " (pass " + passNumber + ")"); messages = this.verify(currentText, config, options); debug("Generating fixed text for " + debugTextDescription + " (pass " + passNumber + ")"); fixedResult = SourceCodeFixer.applyFixes(currentText, messages, shouldFix); /* * stop if there are any syntax errors. * 'fixedResult.output' is a empty string. */ if (messages.length === 1 && messages[0].fatal) { break; } // keep track if any fixes were ever applied - important for return value fixed = fixed || fixedResult.fixed; // update to use the fixed output instead of the original text currentText = fixedResult.output; } while (fixedResult.fixed && passNumber < MAX_AUTOFIX_PASSES); /* * If the last result had fixes, we need to lint again to be sure we have * the most up-to-date information. */ if (fixedResult.fixed) { fixedResult.messages = this.verify(currentText, config, options); } // ensure the last result properly reflects if fixes were done fixedResult.fixed = fixed; fixedResult.output = currentText; return fixedResult; } }], [{ key: "version", get: function get() { return pkg.version; } }]); return Linter; }(); },{"../package.json":111,"./code-path-analysis/code-path-analyzer":112,"./config/config-ops":119,"./config/config-validator":120,"./config/environments":121,"./rules":124,"./util/apply-disable-directives":404,"./util/ast-utils":405,"./util/config-comment-parser":406,"./util/node-event-generator":410,"./util/report-translator":412,"./util/safe-emitter":414,"./util/source-code":416,"./util/source-code-fixer":415,"./util/timing":417,"./util/traverser":418,"debug":53,"eslint-scope":60,"eslint-visitor-keys":69,"lodash":92}],123:[function(require,module,exports){ "use strict"; module.exports = function () { var rules = Object.create(null); rules["accessor-pairs"] = require("./rules/accessor-pairs"); rules["array-bracket-newline"] = require("./rules/array-bracket-newline"); rules["array-bracket-spacing"] = require("./rules/array-bracket-spacing"); rules["array-callback-return"] = require("./rules/array-callback-return"); rules["array-element-newline"] = require("./rules/array-element-newline"); rules["arrow-body-style"] = require("./rules/arrow-body-style"); rules["arrow-parens"] = require("./rules/arrow-parens"); rules["arrow-spacing"] = require("./rules/arrow-spacing"); rules["block-scoped-var"] = require("./rules/block-scoped-var"); rules["block-spacing"] = require("./rules/block-spacing"); rules["brace-style"] = require("./rules/brace-style"); rules["callback-return"] = require("./rules/callback-return"); rules["camelcase"] = require("./rules/camelcase"); rules["capitalized-comments"] = require("./rules/capitalized-comments"); rules["class-methods-use-this"] = require("./rules/class-methods-use-this"); rules["comma-dangle"] = require("./rules/comma-dangle"); rules["comma-spacing"] = require("./rules/comma-spacing"); rules["comma-style"] = require("./rules/comma-style"); rules["complexity"] = require("./rules/complexity"); rules["computed-property-spacing"] = require("./rules/computed-property-spacing"); rules["consistent-return"] = require("./rules/consistent-return"); rules["consistent-this"] = require("./rules/consistent-this"); rules["constructor-super"] = require("./rules/constructor-super"); rules["curly"] = require("./rules/curly"); rules["default-case"] = require("./rules/default-case"); rules["dot-location"] = require("./rules/dot-location"); rules["dot-notation"] = require("./rules/dot-notation"); rules["eol-last"] = require("./rules/eol-last"); rules["eqeqeq"] = require("./rules/eqeqeq"); rules["for-direction"] = require("./rules/for-direction"); rules["func-call-spacing"] = require("./rules/func-call-spacing"); rules["func-name-matching"] = require("./rules/func-name-matching"); rules["func-names"] = require("./rules/func-names"); rules["func-style"] = require("./rules/func-style"); rules["function-paren-newline"] = require("./rules/function-paren-newline"); rules["generator-star-spacing"] = require("./rules/generator-star-spacing"); rules["getter-return"] = require("./rules/getter-return"); rules["global-require"] = require("./rules/global-require"); rules["guard-for-in"] = require("./rules/guard-for-in"); rules["handle-callback-err"] = require("./rules/handle-callback-err"); rules["id-blacklist"] = require("./rules/id-blacklist"); rules["id-length"] = require("./rules/id-length"); rules["id-match"] = require("./rules/id-match"); rules["implicit-arrow-linebreak"] = require("./rules/implicit-arrow-linebreak"); rules["indent-legacy"] = require("./rules/indent-legacy"); rules["indent"] = require("./rules/indent"); rules["init-declarations"] = require("./rules/init-declarations"); rules["jsx-quotes"] = require("./rules/jsx-quotes"); rules["key-spacing"] = require("./rules/key-spacing"); rules["keyword-spacing"] = require("./rules/keyword-spacing"); rules["line-comment-position"] = require("./rules/line-comment-position"); rules["linebreak-style"] = require("./rules/linebreak-style"); rules["lines-around-comment"] = require("./rules/lines-around-comment"); rules["lines-around-directive"] = require("./rules/lines-around-directive"); rules["lines-between-class-members"] = require("./rules/lines-between-class-members"); rules["max-classes-per-file"] = require("./rules/max-classes-per-file"); rules["max-depth"] = require("./rules/max-depth"); rules["max-len"] = require("./rules/max-len"); rules["max-lines-per-function"] = require("./rules/max-lines-per-function"); rules["max-lines"] = require("./rules/max-lines"); rules["max-nested-callbacks"] = require("./rules/max-nested-callbacks"); rules["max-params"] = require("./rules/max-params"); rules["max-statements-per-line"] = require("./rules/max-statements-per-line"); rules["max-statements"] = require("./rules/max-statements"); rules["multiline-comment-style"] = require("./rules/multiline-comment-style"); rules["multiline-ternary"] = require("./rules/multiline-ternary"); rules["new-cap"] = require("./rules/new-cap"); rules["new-parens"] = require("./rules/new-parens"); rules["newline-after-var"] = require("./rules/newline-after-var"); rules["newline-before-return"] = require("./rules/newline-before-return"); rules["newline-per-chained-call"] = require("./rules/newline-per-chained-call"); rules["no-alert"] = require("./rules/no-alert"); rules["no-array-constructor"] = require("./rules/no-array-constructor"); rules["no-async-promise-executor"] = require("./rules/no-async-promise-executor"); rules["no-await-in-loop"] = require("./rules/no-await-in-loop"); rules["no-bitwise"] = require("./rules/no-bitwise"); rules["no-buffer-constructor"] = require("./rules/no-buffer-constructor"); rules["no-caller"] = require("./rules/no-caller"); rules["no-case-declarations"] = require("./rules/no-case-declarations"); rules["no-catch-shadow"] = require("./rules/no-catch-shadow"); rules["no-class-assign"] = require("./rules/no-class-assign"); rules["no-compare-neg-zero"] = require("./rules/no-compare-neg-zero"); rules["no-cond-assign"] = require("./rules/no-cond-assign"); rules["no-confusing-arrow"] = require("./rules/no-confusing-arrow"); rules["no-console"] = require("./rules/no-console"); rules["no-const-assign"] = require("./rules/no-const-assign"); rules["no-constant-condition"] = require("./rules/no-constant-condition"); rules["no-continue"] = require("./rules/no-continue"); rules["no-control-regex"] = require("./rules/no-control-regex"); rules["no-debugger"] = require("./rules/no-debugger"); rules["no-delete-var"] = require("./rules/no-delete-var"); rules["no-div-regex"] = require("./rules/no-div-regex"); rules["no-dupe-args"] = require("./rules/no-dupe-args"); rules["no-dupe-class-members"] = require("./rules/no-dupe-class-members"); rules["no-dupe-keys"] = require("./rules/no-dupe-keys"); rules["no-duplicate-case"] = require("./rules/no-duplicate-case"); rules["no-duplicate-imports"] = require("./rules/no-duplicate-imports"); rules["no-else-return"] = require("./rules/no-else-return"); rules["no-empty-character-class"] = require("./rules/no-empty-character-class"); rules["no-empty-function"] = require("./rules/no-empty-function"); rules["no-empty-pattern"] = require("./rules/no-empty-pattern"); rules["no-empty"] = require("./rules/no-empty"); rules["no-eq-null"] = require("./rules/no-eq-null"); rules["no-eval"] = require("./rules/no-eval"); rules["no-ex-assign"] = require("./rules/no-ex-assign"); rules["no-extend-native"] = require("./rules/no-extend-native"); rules["no-extra-bind"] = require("./rules/no-extra-bind"); rules["no-extra-boolean-cast"] = require("./rules/no-extra-boolean-cast"); rules["no-extra-label"] = require("./rules/no-extra-label"); rules["no-extra-parens"] = require("./rules/no-extra-parens"); rules["no-extra-semi"] = require("./rules/no-extra-semi"); rules["no-fallthrough"] = require("./rules/no-fallthrough"); rules["no-floating-decimal"] = require("./rules/no-floating-decimal"); rules["no-func-assign"] = require("./rules/no-func-assign"); rules["no-global-assign"] = require("./rules/no-global-assign"); rules["no-implicit-coercion"] = require("./rules/no-implicit-coercion"); rules["no-implicit-globals"] = require("./rules/no-implicit-globals"); rules["no-implied-eval"] = require("./rules/no-implied-eval"); rules["no-inline-comments"] = require("./rules/no-inline-comments"); rules["no-inner-declarations"] = require("./rules/no-inner-declarations"); rules["no-invalid-regexp"] = require("./rules/no-invalid-regexp"); rules["no-invalid-this"] = require("./rules/no-invalid-this"); rules["no-irregular-whitespace"] = require("./rules/no-irregular-whitespace"); rules["no-iterator"] = require("./rules/no-iterator"); rules["no-label-var"] = require("./rules/no-label-var"); rules["no-labels"] = require("./rules/no-labels"); rules["no-lone-blocks"] = require("./rules/no-lone-blocks"); rules["no-lonely-if"] = require("./rules/no-lonely-if"); rules["no-loop-func"] = require("./rules/no-loop-func"); rules["no-magic-numbers"] = require("./rules/no-magic-numbers"); rules["no-misleading-character-class"] = require("./rules/no-misleading-character-class"); rules["no-mixed-operators"] = require("./rules/no-mixed-operators"); rules["no-mixed-requires"] = require("./rules/no-mixed-requires"); rules["no-mixed-spaces-and-tabs"] = require("./rules/no-mixed-spaces-and-tabs"); rules["no-multi-assign"] = require("./rules/no-multi-assign"); rules["no-multi-spaces"] = require("./rules/no-multi-spaces"); rules["no-multi-str"] = require("./rules/no-multi-str"); rules["no-multiple-empty-lines"] = require("./rules/no-multiple-empty-lines"); rules["no-native-reassign"] = require("./rules/no-native-reassign"); rules["no-negated-condition"] = require("./rules/no-negated-condition"); rules["no-negated-in-lhs"] = require("./rules/no-negated-in-lhs"); rules["no-nested-ternary"] = require("./rules/no-nested-ternary"); rules["no-new-func"] = require("./rules/no-new-func"); rules["no-new-object"] = require("./rules/no-new-object"); rules["no-new-require"] = require("./rules/no-new-require"); rules["no-new-symbol"] = require("./rules/no-new-symbol"); rules["no-new-wrappers"] = require("./rules/no-new-wrappers"); rules["no-new"] = require("./rules/no-new"); rules["no-obj-calls"] = require("./rules/no-obj-calls"); rules["no-octal-escape"] = require("./rules/no-octal-escape"); rules["no-octal"] = require("./rules/no-octal"); rules["no-param-reassign"] = require("./rules/no-param-reassign"); rules["no-path-concat"] = require("./rules/no-path-concat"); rules["no-plusplus"] = require("./rules/no-plusplus"); rules["no-process-env"] = require("./rules/no-process-env"); rules["no-process-exit"] = require("./rules/no-process-exit"); rules["no-proto"] = require("./rules/no-proto"); rules["no-prototype-builtins"] = require("./rules/no-prototype-builtins"); rules["no-redeclare"] = require("./rules/no-redeclare"); rules["no-regex-spaces"] = require("./rules/no-regex-spaces"); rules["no-restricted-globals"] = require("./rules/no-restricted-globals"); rules["no-restricted-imports"] = require("./rules/no-restricted-imports"); rules["no-restricted-modules"] = require("./rules/no-restricted-modules"); rules["no-restricted-properties"] = require("./rules/no-restricted-properties"); rules["no-restricted-syntax"] = require("./rules/no-restricted-syntax"); rules["no-return-assign"] = require("./rules/no-return-assign"); rules["no-return-await"] = require("./rules/no-return-await"); rules["no-script-url"] = require("./rules/no-script-url"); rules["no-self-assign"] = require("./rules/no-self-assign"); rules["no-self-compare"] = require("./rules/no-self-compare"); rules["no-sequences"] = require("./rules/no-sequences"); rules["no-shadow-restricted-names"] = require("./rules/no-shadow-restricted-names"); rules["no-shadow"] = require("./rules/no-shadow"); rules["no-spaced-func"] = require("./rules/no-spaced-func"); rules["no-sparse-arrays"] = require("./rules/no-sparse-arrays"); rules["no-sync"] = require("./rules/no-sync"); rules["no-tabs"] = require("./rules/no-tabs"); rules["no-template-curly-in-string"] = require("./rules/no-template-curly-in-string"); rules["no-ternary"] = require("./rules/no-ternary"); rules["no-this-before-super"] = require("./rules/no-this-before-super"); rules["no-throw-literal"] = require("./rules/no-throw-literal"); rules["no-trailing-spaces"] = require("./rules/no-trailing-spaces"); rules["no-undef-init"] = require("./rules/no-undef-init"); rules["no-undef"] = require("./rules/no-undef"); rules["no-undefined"] = require("./rules/no-undefined"); rules["no-underscore-dangle"] = require("./rules/no-underscore-dangle"); rules["no-unexpected-multiline"] = require("./rules/no-unexpected-multiline"); rules["no-unmodified-loop-condition"] = require("./rules/no-unmodified-loop-condition"); rules["no-unneeded-ternary"] = require("./rules/no-unneeded-ternary"); rules["no-unreachable"] = require("./rules/no-unreachable"); rules["no-unsafe-finally"] = require("./rules/no-unsafe-finally"); rules["no-unsafe-negation"] = require("./rules/no-unsafe-negation"); rules["no-unused-expressions"] = require("./rules/no-unused-expressions"); rules["no-unused-labels"] = require("./rules/no-unused-labels"); rules["no-unused-vars"] = require("./rules/no-unused-vars"); rules["no-use-before-define"] = require("./rules/no-use-before-define"); rules["no-useless-call"] = require("./rules/no-useless-call"); rules["no-useless-catch"] = require("./rules/no-useless-catch"); rules["no-useless-computed-key"] = require("./rules/no-useless-computed-key"); rules["no-useless-concat"] = require("./rules/no-useless-concat"); rules["no-useless-constructor"] = require("./rules/no-useless-constructor"); rules["no-useless-escape"] = require("./rules/no-useless-escape"); rules["no-useless-rename"] = require("./rules/no-useless-rename"); rules["no-useless-return"] = require("./rules/no-useless-return"); rules["no-var"] = require("./rules/no-var"); rules["no-void"] = require("./rules/no-void"); rules["no-warning-comments"] = require("./rules/no-warning-comments"); rules["no-whitespace-before-property"] = require("./rules/no-whitespace-before-property"); rules["no-with"] = require("./rules/no-with"); rules["nonblock-statement-body-position"] = require("./rules/nonblock-statement-body-position"); rules["object-curly-newline"] = require("./rules/object-curly-newline"); rules["object-curly-spacing"] = require("./rules/object-curly-spacing"); rules["object-property-newline"] = require("./rules/object-property-newline"); rules["object-shorthand"] = require("./rules/object-shorthand"); rules["one-var-declaration-per-line"] = require("./rules/one-var-declaration-per-line"); rules["one-var"] = require("./rules/one-var"); rules["operator-assignment"] = require("./rules/operator-assignment"); rules["operator-linebreak"] = require("./rules/operator-linebreak"); rules["padded-blocks"] = require("./rules/padded-blocks"); rules["padding-line-between-statements"] = require("./rules/padding-line-between-statements"); rules["prefer-arrow-callback"] = require("./rules/prefer-arrow-callback"); rules["prefer-const"] = require("./rules/prefer-const"); rules["prefer-destructuring"] = require("./rules/prefer-destructuring"); rules["prefer-numeric-literals"] = require("./rules/prefer-numeric-literals"); rules["prefer-object-spread"] = require("./rules/prefer-object-spread"); rules["prefer-promise-reject-errors"] = require("./rules/prefer-promise-reject-errors"); rules["prefer-reflect"] = require("./rules/prefer-reflect"); rules["prefer-rest-params"] = require("./rules/prefer-rest-params"); rules["prefer-spread"] = require("./rules/prefer-spread"); rules["prefer-template"] = require("./rules/prefer-template"); rules["quote-props"] = require("./rules/quote-props"); rules["quotes"] = require("./rules/quotes"); rules["radix"] = require("./rules/radix"); rules["require-atomic-updates"] = require("./rules/require-atomic-updates"); rules["require-await"] = require("./rules/require-await"); rules["require-jsdoc"] = require("./rules/require-jsdoc"); rules["require-unicode-regexp"] = require("./rules/require-unicode-regexp"); rules["require-yield"] = require("./rules/require-yield"); rules["rest-spread-spacing"] = require("./rules/rest-spread-spacing"); rules["semi-spacing"] = require("./rules/semi-spacing"); rules["semi-style"] = require("./rules/semi-style"); rules["semi"] = require("./rules/semi"); rules["sort-imports"] = require("./rules/sort-imports"); rules["sort-keys"] = require("./rules/sort-keys"); rules["sort-vars"] = require("./rules/sort-vars"); rules["space-before-blocks"] = require("./rules/space-before-blocks"); rules["space-before-function-paren"] = require("./rules/space-before-function-paren"); rules["space-in-parens"] = require("./rules/space-in-parens"); rules["space-infix-ops"] = require("./rules/space-infix-ops"); rules["space-unary-ops"] = require("./rules/space-unary-ops"); rules["spaced-comment"] = require("./rules/spaced-comment"); rules["strict"] = require("./rules/strict"); rules["switch-colon-spacing"] = require("./rules/switch-colon-spacing"); rules["symbol-description"] = require("./rules/symbol-description"); rules["template-curly-spacing"] = require("./rules/template-curly-spacing"); rules["template-tag-spacing"] = require("./rules/template-tag-spacing"); rules["unicode-bom"] = require("./rules/unicode-bom"); rules["use-isnan"] = require("./rules/use-isnan"); rules["valid-jsdoc"] = require("./rules/valid-jsdoc"); rules["valid-typeof"] = require("./rules/valid-typeof"); rules["vars-on-top"] = require("./rules/vars-on-top"); rules["wrap-iife"] = require("./rules/wrap-iife"); rules["wrap-regex"] = require("./rules/wrap-regex"); rules["yield-star-spacing"] = require("./rules/yield-star-spacing"); rules["yoda"] = require("./rules/yoda"); return rules; }; },{"./rules/accessor-pairs":125,"./rules/array-bracket-newline":126,"./rules/array-bracket-spacing":127,"./rules/array-callback-return":128,"./rules/array-element-newline":129,"./rules/arrow-body-style":130,"./rules/arrow-parens":131,"./rules/arrow-spacing":132,"./rules/block-scoped-var":133,"./rules/block-spacing":134,"./rules/brace-style":135,"./rules/callback-return":136,"./rules/camelcase":137,"./rules/capitalized-comments":138,"./rules/class-methods-use-this":139,"./rules/comma-dangle":140,"./rules/comma-spacing":141,"./rules/comma-style":142,"./rules/complexity":143,"./rules/computed-property-spacing":144,"./rules/consistent-return":145,"./rules/consistent-this":146,"./rules/constructor-super":147,"./rules/curly":148,"./rules/default-case":149,"./rules/dot-location":150,"./rules/dot-notation":151,"./rules/eol-last":152,"./rules/eqeqeq":153,"./rules/for-direction":154,"./rules/func-call-spacing":155,"./rules/func-name-matching":156,"./rules/func-names":157,"./rules/func-style":158,"./rules/function-paren-newline":159,"./rules/generator-star-spacing":160,"./rules/getter-return":161,"./rules/global-require":162,"./rules/guard-for-in":163,"./rules/handle-callback-err":164,"./rules/id-blacklist":165,"./rules/id-length":166,"./rules/id-match":167,"./rules/implicit-arrow-linebreak":168,"./rules/indent":170,"./rules/indent-legacy":169,"./rules/init-declarations":171,"./rules/jsx-quotes":172,"./rules/key-spacing":173,"./rules/keyword-spacing":174,"./rules/line-comment-position":175,"./rules/linebreak-style":176,"./rules/lines-around-comment":177,"./rules/lines-around-directive":178,"./rules/lines-between-class-members":179,"./rules/max-classes-per-file":180,"./rules/max-depth":181,"./rules/max-len":182,"./rules/max-lines":184,"./rules/max-lines-per-function":183,"./rules/max-nested-callbacks":185,"./rules/max-params":186,"./rules/max-statements":188,"./rules/max-statements-per-line":187,"./rules/multiline-comment-style":189,"./rules/multiline-ternary":190,"./rules/new-cap":191,"./rules/new-parens":192,"./rules/newline-after-var":193,"./rules/newline-before-return":194,"./rules/newline-per-chained-call":195,"./rules/no-alert":196,"./rules/no-array-constructor":197,"./rules/no-async-promise-executor":198,"./rules/no-await-in-loop":199,"./rules/no-bitwise":200,"./rules/no-buffer-constructor":201,"./rules/no-caller":202,"./rules/no-case-declarations":203,"./rules/no-catch-shadow":204,"./rules/no-class-assign":205,"./rules/no-compare-neg-zero":206,"./rules/no-cond-assign":207,"./rules/no-confusing-arrow":208,"./rules/no-console":209,"./rules/no-const-assign":210,"./rules/no-constant-condition":211,"./rules/no-continue":212,"./rules/no-control-regex":213,"./rules/no-debugger":214,"./rules/no-delete-var":215,"./rules/no-div-regex":216,"./rules/no-dupe-args":217,"./rules/no-dupe-class-members":218,"./rules/no-dupe-keys":219,"./rules/no-duplicate-case":220,"./rules/no-duplicate-imports":221,"./rules/no-else-return":222,"./rules/no-empty":226,"./rules/no-empty-character-class":223,"./rules/no-empty-function":224,"./rules/no-empty-pattern":225,"./rules/no-eq-null":227,"./rules/no-eval":228,"./rules/no-ex-assign":229,"./rules/no-extend-native":230,"./rules/no-extra-bind":231,"./rules/no-extra-boolean-cast":232,"./rules/no-extra-label":233,"./rules/no-extra-parens":234,"./rules/no-extra-semi":235,"./rules/no-fallthrough":236,"./rules/no-floating-decimal":237,"./rules/no-func-assign":238,"./rules/no-global-assign":239,"./rules/no-implicit-coercion":240,"./rules/no-implicit-globals":241,"./rules/no-implied-eval":242,"./rules/no-inline-comments":243,"./rules/no-inner-declarations":244,"./rules/no-invalid-regexp":245,"./rules/no-invalid-this":246,"./rules/no-irregular-whitespace":247,"./rules/no-iterator":248,"./rules/no-label-var":249,"./rules/no-labels":250,"./rules/no-lone-blocks":251,"./rules/no-lonely-if":252,"./rules/no-loop-func":253,"./rules/no-magic-numbers":254,"./rules/no-misleading-character-class":255,"./rules/no-mixed-operators":256,"./rules/no-mixed-requires":257,"./rules/no-mixed-spaces-and-tabs":258,"./rules/no-multi-assign":259,"./rules/no-multi-spaces":260,"./rules/no-multi-str":261,"./rules/no-multiple-empty-lines":262,"./rules/no-native-reassign":263,"./rules/no-negated-condition":264,"./rules/no-negated-in-lhs":265,"./rules/no-nested-ternary":266,"./rules/no-new":272,"./rules/no-new-func":267,"./rules/no-new-object":268,"./rules/no-new-require":269,"./rules/no-new-symbol":270,"./rules/no-new-wrappers":271,"./rules/no-obj-calls":273,"./rules/no-octal":275,"./rules/no-octal-escape":274,"./rules/no-param-reassign":276,"./rules/no-path-concat":277,"./rules/no-plusplus":278,"./rules/no-process-env":279,"./rules/no-process-exit":280,"./rules/no-proto":281,"./rules/no-prototype-builtins":282,"./rules/no-redeclare":283,"./rules/no-regex-spaces":284,"./rules/no-restricted-globals":285,"./rules/no-restricted-imports":286,"./rules/no-restricted-modules":287,"./rules/no-restricted-properties":288,"./rules/no-restricted-syntax":289,"./rules/no-return-assign":290,"./rules/no-return-await":291,"./rules/no-script-url":292,"./rules/no-self-assign":293,"./rules/no-self-compare":294,"./rules/no-sequences":295,"./rules/no-shadow":297,"./rules/no-shadow-restricted-names":296,"./rules/no-spaced-func":298,"./rules/no-sparse-arrays":299,"./rules/no-sync":300,"./rules/no-tabs":301,"./rules/no-template-curly-in-string":302,"./rules/no-ternary":303,"./rules/no-this-before-super":304,"./rules/no-throw-literal":305,"./rules/no-trailing-spaces":306,"./rules/no-undef":308,"./rules/no-undef-init":307,"./rules/no-undefined":309,"./rules/no-underscore-dangle":310,"./rules/no-unexpected-multiline":311,"./rules/no-unmodified-loop-condition":312,"./rules/no-unneeded-ternary":313,"./rules/no-unreachable":314,"./rules/no-unsafe-finally":315,"./rules/no-unsafe-negation":316,"./rules/no-unused-expressions":317,"./rules/no-unused-labels":318,"./rules/no-unused-vars":319,"./rules/no-use-before-define":320,"./rules/no-useless-call":321,"./rules/no-useless-catch":322,"./rules/no-useless-computed-key":323,"./rules/no-useless-concat":324,"./rules/no-useless-constructor":325,"./rules/no-useless-escape":326,"./rules/no-useless-rename":327,"./rules/no-useless-return":328,"./rules/no-var":329,"./rules/no-void":330,"./rules/no-warning-comments":331,"./rules/no-whitespace-before-property":332,"./rules/no-with":333,"./rules/nonblock-statement-body-position":334,"./rules/object-curly-newline":335,"./rules/object-curly-spacing":336,"./rules/object-property-newline":337,"./rules/object-shorthand":338,"./rules/one-var":340,"./rules/one-var-declaration-per-line":339,"./rules/operator-assignment":341,"./rules/operator-linebreak":342,"./rules/padded-blocks":343,"./rules/padding-line-between-statements":344,"./rules/prefer-arrow-callback":345,"./rules/prefer-const":346,"./rules/prefer-destructuring":347,"./rules/prefer-numeric-literals":348,"./rules/prefer-object-spread":349,"./rules/prefer-promise-reject-errors":350,"./rules/prefer-reflect":351,"./rules/prefer-rest-params":352,"./rules/prefer-spread":353,"./rules/prefer-template":354,"./rules/quote-props":355,"./rules/quotes":356,"./rules/radix":357,"./rules/require-atomic-updates":358,"./rules/require-await":359,"./rules/require-jsdoc":360,"./rules/require-unicode-regexp":361,"./rules/require-yield":362,"./rules/rest-spread-spacing":363,"./rules/semi":366,"./rules/semi-spacing":364,"./rules/semi-style":365,"./rules/sort-imports":367,"./rules/sort-keys":368,"./rules/sort-vars":369,"./rules/space-before-blocks":370,"./rules/space-before-function-paren":371,"./rules/space-in-parens":372,"./rules/space-infix-ops":373,"./rules/space-unary-ops":374,"./rules/spaced-comment":375,"./rules/strict":376,"./rules/switch-colon-spacing":377,"./rules/symbol-description":378,"./rules/template-curly-spacing":379,"./rules/template-tag-spacing":380,"./rules/unicode-bom":381,"./rules/use-isnan":382,"./rules/valid-jsdoc":383,"./rules/valid-typeof":384,"./rules/vars-on-top":385,"./rules/wrap-iife":386,"./rules/wrap-regex":387,"./rules/yield-star-spacing":388,"./rules/yoda":389}],124:[function(require,module,exports){ /** * @fileoverview Defines a storage for rules. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var lodash = require("lodash"); var loadRules = require("./load-rules"); var ruleReplacements = require("../conf/replacements").rules; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Creates a stub rule that gets used when a rule with a given ID is not found. * @param {string} ruleId The ID of the missing rule * @returns {{create: function(RuleContext): Object}} A rule that reports an error at the first location * in the program. The report has the message `Definition for rule '${ruleId}' was not found` if the rule is unknown, * or `Rule '${ruleId}' was removed and replaced by: ${replacements.join(", ")}` if the rule is known to have been * replaced. */ var createMissingRule = lodash.memoize(function (ruleId) { var message = Object.prototype.hasOwnProperty.call(ruleReplacements, ruleId) ? "Rule '" + ruleId + "' was removed and replaced by: " + ruleReplacements[ruleId].join(", ") : "Definition for rule '" + ruleId + "' was not found"; return { create: function create(context) { return { Program: function Program() { context.report({ loc: { line: 1, column: 0 }, message: message }); } }; } }; }); /** * Normalizes a rule module to the new-style API * @param {(Function|{create: Function})} rule A rule object, which can either be a function * ("old-style") or an object with a `create` method ("new-style") * @returns {{create: Function}} A new-style rule. */ function normalizeRule(rule) { return typeof rule === "function" ? Object.assign({ create: rule }, rule) : rule; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ var Rules = function () { function Rules() { _classCallCheck(this, Rules); this._rules = Object.create(null); this.load(); } /** * Registers a rule module for rule id in storage. * @param {string} ruleId Rule id (file name). * @param {Function} ruleModule Rule handler. * @returns {void} */ _createClass(Rules, [{ key: "define", value: function define(ruleId, ruleModule) { this._rules[ruleId] = normalizeRule(ruleModule); } /** * Loads and registers all rules from passed rules directory. * @param {string} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`. * @param {string} cwd Current working directory * @returns {void} */ }, { key: "load", value: function load(rulesDir, cwd) { var _this = this; var newRules = loadRules(rulesDir, cwd); Object.keys(newRules).forEach(function (ruleId) { _this.define(ruleId, newRules[ruleId]); }); } /** * Registers all given rules of a plugin. * @param {Object} plugin The plugin object to import. * @param {string} pluginName The name of the plugin without prefix (`eslint-plugin-`). * @returns {void} */ }, { key: "importPlugin", value: function importPlugin(plugin, pluginName) { var _this2 = this; if (plugin.rules) { Object.keys(plugin.rules).forEach(function (ruleId) { var qualifiedRuleId = pluginName + "/" + ruleId, rule = plugin.rules[ruleId]; _this2.define(qualifiedRuleId, rule); }); } } /** * Access rule handler by id (file name). * @param {string} ruleId Rule id (file name). * @returns {{create: Function, schema: JsonSchema[]}} * A rule. This is normalized to always have the new-style shape with a `create` method. */ }, { key: "get", value: function get(ruleId) { if (!Object.prototype.hasOwnProperty.call(this._rules, ruleId)) { return createMissingRule(ruleId); } if (typeof this._rules[ruleId] === "string") { return normalizeRule(require(this._rules[ruleId])); } return this._rules[ruleId]; } /** * Get an object with all currently loaded rules * @returns {Map} All loaded rules */ }, { key: "getAllLoadedRules", value: function getAllLoadedRules() { var _this3 = this; var allRules = new Map(); Object.keys(this._rules).forEach(function (name) { var rule = _this3.get(name); allRules.set(name, rule); }); return allRules; } }]); return Rules; }(); module.exports = Rules; },{"../conf/replacements":3,"./load-rules":123,"lodash":92}],125:[function(require,module,exports){ /** * @fileoverview Rule to flag wrapping non-iife in parens * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is an `Identifier` node which was named a given name. * @param {ASTNode} node - A node to check. * @param {string} name - An expected name of the node. * @returns {boolean} `true` if the node is an `Identifier` node which was named as expected. */ function isIdentifier(node, name) { return node.type === "Identifier" && node.name === name; } /** * Checks whether or not a given node is an argument of a specified method call. * @param {ASTNode} node - A node to check. * @param {number} index - An expected index of the node in arguments. * @param {string} object - An expected name of the object of the method. * @param {string} property - An expected name of the method. * @returns {boolean} `true` if the node is an argument of the specified method call. */ function isArgumentOfMethodCall(node, index, object, property) { var parent = node.parent; return parent.type === "CallExpression" && parent.callee.type === "MemberExpression" && parent.callee.computed === false && isIdentifier(parent.callee.object, object) && isIdentifier(parent.callee.property, property) && parent.arguments[index] === node; } /** * Checks whether or not a given node is a property descriptor. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a property descriptor. */ function isPropertyDescriptor(node) { // Object.defineProperty(obj, "foo", {set: ...}) if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") || isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")) { return true; } /* * Object.defineProperties(obj, {foo: {set: ...}}) * Object.create(proto, {foo: {set: ...}}) */ var grandparent = node.parent.parent; return grandparent.type === "ObjectExpression" && (isArgumentOfMethodCall(grandparent, 1, "Object", "create") || isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties")); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce getter and setter pairs in objects", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/accessor-pairs" }, schema: [{ type: "object", properties: { getWithoutSet: { type: "boolean" }, setWithoutGet: { type: "boolean" } }, additionalProperties: false }], messages: { getter: "Getter is not present.", setter: "Setter is not present." } }, create: function create(context) { var config = context.options[0] || {}; var checkGetWithoutSet = config.getWithoutSet === true; var checkSetWithoutGet = config.setWithoutGet !== false; /** * Checks a object expression to see if it has setter and getter both present or none. * @param {ASTNode} node The node to check. * @returns {void} * @private */ function checkLonelySetGet(node) { var isSetPresent = false; var isGetPresent = false; var isDescriptor = isPropertyDescriptor(node); for (var i = 0, end = node.properties.length; i < end; i++) { var property = node.properties[i]; var propToCheck = ""; if (property.kind === "init") { if (isDescriptor && !property.computed) { propToCheck = property.key.name; } } else { propToCheck = property.kind; } switch (propToCheck) { case "set": isSetPresent = true; break; case "get": isGetPresent = true; break; default: // Do nothing } if (isSetPresent && isGetPresent) { break; } } if (checkSetWithoutGet && isSetPresent && !isGetPresent) { context.report({ node: node, messageId: "getter" }); } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) { context.report({ node: node, messageId: "setter" }); } } return { ObjectExpression: function ObjectExpression(node) { if (checkSetWithoutGet || checkGetWithoutSet) { checkLonelySetGet(node); } } }; } }; },{}],126:[function(require,module,exports){ /** * @fileoverview Rule to enforce linebreaks after open and before close array brackets * @author Jan Peer Stöcklmair */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce linebreaks after opening and before closing array brackets", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/array-bracket-newline" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["always", "never", "consistent"] }, { type: "object", properties: { multiline: { type: "boolean" }, minItems: { type: ["integer", "null"], minimum: 0 } }, additionalProperties: false }] }], messages: { unexpectedOpeningLinebreak: "There should be no linebreak after '['.", unexpectedClosingLinebreak: "There should be no linebreak before ']'.", missingOpeningLinebreak: "A linebreak is required after '['.", missingClosingLinebreak: "A linebreak is required before ']'." } }, create: function create(context) { var sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Normalizes a given option value. * * @param {string|Object|undefined} option - An option value to parse. * @returns {{multiline: boolean, minItems: number}} Normalized option object. */ function normalizeOptionValue(option) { var consistent = false; var multiline = false; var minItems = 0; if (option) { if (option === "consistent") { consistent = true; minItems = Number.POSITIVE_INFINITY; } else if (option === "always" || option.minItems === 0) { minItems = 0; } else if (option === "never") { minItems = Number.POSITIVE_INFINITY; } else { multiline = Boolean(option.multiline); minItems = option.minItems || Number.POSITIVE_INFINITY; } } else { consistent = false; multiline = true; minItems = Number.POSITIVE_INFINITY; } return { consistent: consistent, multiline: multiline, minItems: minItems }; } /** * Normalizes a given option value. * * @param {string|Object|undefined} options - An option value to parse. * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. */ function normalizeOptions(options) { var value = normalizeOptionValue(options); return { ArrayExpression: value, ArrayPattern: value }; } /** * Reports that there shouldn't be a linebreak after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoBeginningLinebreak(node, token) { context.report({ node: node, loc: token.loc, messageId: "unexpectedOpeningLinebreak", fix: function fix(fixer) { var nextToken = sourceCode.getTokenAfter(token, { includeComments: true }); if (astUtils.isCommentToken(nextToken)) { return null; } return fixer.removeRange([token.range[1], nextToken.range[0]]); } }); } /** * Reports that there shouldn't be a linebreak before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoEndingLinebreak(node, token) { context.report({ node: node, loc: token.loc, messageId: "unexpectedClosingLinebreak", fix: function fix(fixer) { var previousToken = sourceCode.getTokenBefore(token, { includeComments: true }); if (astUtils.isCommentToken(previousToken)) { return null; } return fixer.removeRange([previousToken.range[1], token.range[0]]); } }); } /** * Reports that there should be a linebreak after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredBeginningLinebreak(node, token) { context.report({ node: node, loc: token.loc, messageId: "missingOpeningLinebreak", fix: function fix(fixer) { return fixer.insertTextAfter(token, "\n"); } }); } /** * Reports that there should be a linebreak before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredEndingLinebreak(node, token) { context.report({ node: node, loc: token.loc, messageId: "missingClosingLinebreak", fix: function fix(fixer) { return fixer.insertTextBefore(token, "\n"); } }); } /** * Reports a given node if it violated this rule. * * @param {ASTNode} node - A node to check. This is an ArrayExpression node or an ArrayPattern node. * @returns {void} */ function check(node) { var elements = node.elements; var normalizedOptions = normalizeOptions(context.options[0]); var options = normalizedOptions[node.type]; var openBracket = sourceCode.getFirstToken(node); var closeBracket = sourceCode.getLastToken(node); var firstIncComment = sourceCode.getTokenAfter(openBracket, { includeComments: true }); var lastIncComment = sourceCode.getTokenBefore(closeBracket, { includeComments: true }); var first = sourceCode.getTokenAfter(openBracket); var last = sourceCode.getTokenBefore(closeBracket); var needsLinebreaks = elements.length >= options.minItems || options.multiline && elements.length > 0 && firstIncComment.loc.start.line !== lastIncComment.loc.end.line || elements.length === 0 && firstIncComment.type === "Block" && firstIncComment.loc.start.line !== lastIncComment.loc.end.line && firstIncComment === lastIncComment || options.consistent && firstIncComment.loc.start.line !== openBracket.loc.end.line; /* * Use tokens or comments to check multiline or not. * But use only tokens to check whether linebreaks are needed. * This allows: * var arr = [ // eslint-disable-line foo * 'a' * ] */ if (needsLinebreaks) { if (astUtils.isTokenOnSameLine(openBracket, first)) { reportRequiredBeginningLinebreak(node, openBracket); } if (astUtils.isTokenOnSameLine(last, closeBracket)) { reportRequiredEndingLinebreak(node, closeBracket); } } else { if (!astUtils.isTokenOnSameLine(openBracket, first)) { reportNoBeginningLinebreak(node, openBracket); } if (!astUtils.isTokenOnSameLine(last, closeBracket)) { reportNoEndingLinebreak(node, closeBracket); } } } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { ArrayPattern: check, ArrayExpression: check }; } }; },{"../util/ast-utils":405}],127:[function(require,module,exports){ /** * @fileoverview Disallows or enforces spaces inside of array brackets. * @author Jamund Ferguson */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing inside array brackets", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/array-bracket-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }, { type: "object", properties: { singleValue: { type: "boolean" }, objectsInArrays: { type: "boolean" }, arraysInArrays: { type: "boolean" } }, additionalProperties: false }], messages: { unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", missingSpaceAfter: "A space is required after '{{tokenValue}}'.", missingSpaceBefore: "A space is required before '{{tokenValue}}'." } }, create: function create(context) { var spaced = context.options[0] === "always", sourceCode = context.getSourceCode(); /** * Determines whether an option is set, relative to the spacing option. * If spaced is "always", then check whether option is set to false. * If spaced is "never", then check whether option is set to true. * @param {Object} option - The option to exclude. * @returns {boolean} Whether or not the property is excluded. */ function isOptionSet(option) { return context.options[1] ? context.options[1][option] === !spaced : false; } var options = { spaced: spaced, singleElementException: isOptionSet("singleValue"), objectsInArraysException: isOptionSet("objectsInArrays"), arraysInArraysException: isOptionSet("arraysInArrays") }; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports that there shouldn't be a space after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoBeginningSpace(node, token) { context.report({ node: node, loc: token.loc.start, messageId: "unexpectedSpaceAfter", data: { tokenValue: token.value }, fix: function fix(fixer) { var nextToken = sourceCode.getTokenAfter(token); return fixer.removeRange([token.range[1], nextToken.range[0]]); } }); } /** * Reports that there shouldn't be a space before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoEndingSpace(node, token) { context.report({ node: node, loc: token.loc.start, messageId: "unexpectedSpaceBefore", data: { tokenValue: token.value }, fix: function fix(fixer) { var previousToken = sourceCode.getTokenBefore(token); return fixer.removeRange([previousToken.range[1], token.range[0]]); } }); } /** * Reports that there should be a space after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredBeginningSpace(node, token) { context.report({ node: node, loc: token.loc.start, messageId: "missingSpaceAfter", data: { tokenValue: token.value }, fix: function fix(fixer) { return fixer.insertTextAfter(token, " "); } }); } /** * Reports that there should be a space before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredEndingSpace(node, token) { context.report({ node: node, loc: token.loc.start, messageId: "missingSpaceBefore", data: { tokenValue: token.value }, fix: function fix(fixer) { return fixer.insertTextBefore(token, " "); } }); } /** * Determines if a node is an object type * @param {ASTNode} node - The node to check. * @returns {boolean} Whether or not the node is an object type. */ function isObjectType(node) { return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern"); } /** * Determines if a node is an array type * @param {ASTNode} node - The node to check. * @returns {boolean} Whether or not the node is an array type. */ function isArrayType(node) { return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern"); } /** * Validates the spacing around array brackets * @param {ASTNode} node - The node we're checking for spacing * @returns {void} */ function validateArraySpacing(node) { if (options.spaced && node.elements.length === 0) { return; } var first = sourceCode.getFirstToken(node), second = sourceCode.getFirstToken(node, 1), last = node.typeAnnotation ? sourceCode.getTokenBefore(node.typeAnnotation) : sourceCode.getLastToken(node), penultimate = sourceCode.getTokenBefore(last), firstElement = node.elements[0], lastElement = node.elements[node.elements.length - 1]; var openingBracketMustBeSpaced = options.objectsInArraysException && isObjectType(firstElement) || options.arraysInArraysException && isArrayType(firstElement) || options.singleElementException && node.elements.length === 1 ? !options.spaced : options.spaced; var closingBracketMustBeSpaced = options.objectsInArraysException && isObjectType(lastElement) || options.arraysInArraysException && isArrayType(lastElement) || options.singleElementException && node.elements.length === 1 ? !options.spaced : options.spaced; if (astUtils.isTokenOnSameLine(first, second)) { if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) { reportRequiredBeginningSpace(node, first); } if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) { reportNoBeginningSpace(node, first); } } if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) { if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) { reportRequiredEndingSpace(node, last); } if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) { reportNoEndingSpace(node, last); } } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ArrayPattern: validateArraySpacing, ArrayExpression: validateArraySpacing }; } }; },{"../util/ast-utils":405}],128:[function(require,module,exports){ /** * @fileoverview Rule to enforce return statements in callbacks of array's methods * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/; var TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/; /** * Checks a given code path segment is reachable. * * @param {CodePathSegment} segment - A segment to check. * @returns {boolean} `true` if the segment is reachable. */ function isReachable(segment) { return segment.reachable; } /** * Gets a readable location. * * - FunctionExpression -> the function name or `function` keyword. * - ArrowFunctionExpression -> `=>` token. * * @param {ASTNode} node - A function node to get. * @param {SourceCode} sourceCode - A source code to get tokens. * @returns {ASTNode|Token} The node or the token of a location. */ function getLocation(node, sourceCode) { if (node.type === "ArrowFunctionExpression") { return sourceCode.getTokenBefore(node.body); } return node.id || node; } /** * Checks a given node is a MemberExpression node which has the specified name's * property. * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a MemberExpression node which has * the specified name's property */ function isTargetMethod(node) { return node.type === "MemberExpression" && TARGET_METHODS.test(astUtils.getStaticPropertyName(node) || ""); } /** * Checks whether or not a given node is a function expression which is the * callback of an array method. * * @param {ASTNode} node - A node to check. This is one of * FunctionExpression or ArrowFunctionExpression. * @returns {boolean} `true` if the node is the callback of an array method. */ function isCallbackOfArrayMethod(node) { var currentNode = node; while (currentNode) { var parent = currentNode.parent; switch (parent.type) { /* * Looks up the destination. e.g., * foo.every(nativeFoo || function foo() { ... }); */ case "LogicalExpression": case "ConditionalExpression": currentNode = parent; break; /* * If the upper function is IIFE, checks the destination of the return value. * e.g. * foo.every((function() { * // setup... * return function callback() { ... }; * })()); */ case "ReturnStatement": { var func = astUtils.getUpperFunction(parent); if (func === null || !astUtils.isCallee(func)) { return false; } currentNode = func.parent; break; } /* * e.g. * Array.from([], function() {}); * list.every(function() {}); */ case "CallExpression": if (astUtils.isArrayFromMethod(parent.callee)) { return parent.arguments.length >= 2 && parent.arguments[1] === currentNode; } if (isTargetMethod(parent.callee)) { return parent.arguments.length >= 1 && parent.arguments[0] === currentNode; } return false; // Otherwise this node is not target. default: return false; } } /* istanbul ignore next: unreachable */ return false; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "enforce `return` statements in callbacks of array methods", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/array-callback-return" }, schema: [{ type: "object", properties: { allowImplicit: { type: "boolean" } }, additionalProperties: false }], messages: { expectedAtEnd: "Expected to return a value at the end of {{name}}.", expectedInside: "Expected to return a value in {{name}}.", expectedReturnValue: "{{name}} expected a return value." } }, create: function create(context) { var options = context.options[0] || { allowImplicit: false }; var funcInfo = { upper: null, codePath: null, hasReturn: false, shouldCheck: false, node: null }; /** * Checks whether or not the last code path segment is reachable. * Then reports this function if the segment is reachable. * * If the last code path segment is reachable, there are paths which are not * returned or thrown. * * @param {ASTNode} node - A node to check. * @returns {void} */ function checkLastSegment(node) { if (funcInfo.shouldCheck && funcInfo.codePath.currentSegments.some(isReachable)) { context.report({ node: node, loc: getLocation(node, context.getSourceCode()).loc.start, messageId: funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside", data: { name: astUtils.getFunctionNameWithKind(funcInfo.node) } }); } } return { // Stacks this function's information. onCodePathStart: function onCodePathStart(codePath, node) { funcInfo = { upper: funcInfo, codePath: codePath, hasReturn: false, shouldCheck: TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement" && isCallbackOfArrayMethod(node) && !node.async && !node.generator, node: node }; }, // Pops this function's information. onCodePathEnd: function onCodePathEnd() { funcInfo = funcInfo.upper; }, // Checks the return statement is valid. ReturnStatement: function ReturnStatement(node) { if (funcInfo.shouldCheck) { funcInfo.hasReturn = true; // if allowImplicit: false, should also check node.argument if (!options.allowImplicit && !node.argument) { context.report({ node: node, messageId: "expectedReturnValue", data: { name: lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node)) } }); } } }, // Reports a given function if the last path is reachable. "FunctionExpression:exit": checkLastSegment, "ArrowFunctionExpression:exit": checkLastSegment }; } }; },{"../util/ast-utils":405,"lodash":92}],129:[function(require,module,exports){ /** * @fileoverview Rule to enforce line breaks after each array element * @author Jan Peer Stöcklmair */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce line breaks after each array element", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/array-element-newline" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["always", "never", "consistent"] }, { type: "object", properties: { multiline: { type: "boolean" }, minItems: { type: ["integer", "null"], minimum: 0 } }, additionalProperties: false }] }], messages: { unexpectedLineBreak: "There should be no linebreak here.", missingLineBreak: "There should be a linebreak after this element." } }, create: function create(context) { var sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Normalizes a given option value. * * @param {string|Object|undefined} providedOption - An option value to parse. * @returns {{multiline: boolean, minItems: number}} Normalized option object. */ function normalizeOptionValue(providedOption) { var consistent = false; var multiline = false; var minItems = void 0; var option = providedOption || "always"; if (!option || option === "always" || option.minItems === 0) { minItems = 0; } else if (option === "never") { minItems = Number.POSITIVE_INFINITY; } else if (option === "consistent") { consistent = true; minItems = Number.POSITIVE_INFINITY; } else { multiline = Boolean(option.multiline); minItems = option.minItems || Number.POSITIVE_INFINITY; } return { consistent: consistent, multiline: multiline, minItems: minItems }; } /** * Normalizes a given option value. * * @param {string|Object|undefined} options - An option value to parse. * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. */ function normalizeOptions(options) { var value = normalizeOptionValue(options); return { ArrayExpression: value, ArrayPattern: value }; } /** * Reports that there shouldn't be a line break after the first token * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoLineBreak(token) { var tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); context.report({ loc: { start: tokenBefore.loc.end, end: token.loc.start }, messageId: "unexpectedLineBreak", fix: function fix(fixer) { if (astUtils.isCommentToken(tokenBefore)) { return null; } if (!astUtils.isTokenOnSameLine(tokenBefore, token)) { return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " "); } /* * This will check if the comma is on the same line as the next element * Following array: * [ * 1 * , 2 * , 3 * ] * * will be fixed to: * [ * 1, 2, 3 * ] */ var twoTokensBefore = sourceCode.getTokenBefore(tokenBefore, { includeComments: true }); if (astUtils.isCommentToken(twoTokensBefore)) { return null; } return fixer.replaceTextRange([twoTokensBefore.range[1], tokenBefore.range[0]], ""); } }); } /** * Reports that there should be a line break after the first token * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredLineBreak(token) { var tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); context.report({ loc: { start: tokenBefore.loc.end, end: token.loc.start }, messageId: "missingLineBreak", fix: function fix(fixer) { return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n"); } }); } /** * Reports a given node if it violated this rule. * * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node. * @returns {void} */ function check(node) { var elements = node.elements; var normalizedOptions = normalizeOptions(context.options[0]); var options = normalizedOptions[node.type]; var elementBreak = false; /* * MULTILINE: true * loop through every element and check * if at least one element has linebreaks inside * this ensures that following is not valid (due to elements are on the same line): * * [ * 1, * 2, * 3 * ] */ if (options.multiline) { elementBreak = elements.filter(function (element) { return element !== null; }).some(function (element) { return element.loc.start.line !== element.loc.end.line; }); } var linebreaksCount = node.elements.map(function (element, i) { var previousElement = elements[i - 1]; if (i === 0 || element === null || previousElement === null) { return false; } var commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); var lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); var firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement); }).filter(function (isBreak) { return isBreak === true; }).length; var needsLinebreaks = elements.length >= options.minItems || options.multiline && elementBreak || options.consistent && linebreaksCount > 0 && linebreaksCount < node.elements.length; elements.forEach(function (element, i) { var previousElement = elements[i - 1]; if (i === 0 || element === null || previousElement === null) { return; } var commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); var lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); var firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); if (needsLinebreaks) { if (astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { reportRequiredLineBreak(firstTokenOfCurrentElement); } } else { if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { reportNoLineBreak(firstTokenOfCurrentElement); } } }); } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { ArrayPattern: check, ArrayExpression: check }; } }; },{"../util/ast-utils":405}],130:[function(require,module,exports){ /** * @fileoverview Rule to require braces in arrow function body. * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require braces around arrow function bodies", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/arrow-body-style" }, schema: { anyOf: [{ type: "array", items: [{ enum: ["always", "never"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["as-needed"] }, { type: "object", properties: { requireReturnForObjectLiteral: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] }, fixable: "code", messages: { unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.", unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.", unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.", unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.", expectedBlock: "Expected block statement surrounding arrow body." } }, create: function create(context) { var options = context.options; var always = options[0] === "always"; var asNeeded = !options[0] || options[0] === "as-needed"; var never = options[0] === "never"; var requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; var sourceCode = context.getSourceCode(); /** * Checks whether the given node has ASI problem or not. * @param {Token} token The token to check. * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed. */ function hasASIProblem(token) { return token && token.type === "Punctuator" && /^[([/`+-]/.test(token.value); } /** * Gets the closing parenthesis which is the pair of the given opening parenthesis. * @param {Token} token The opening parenthesis token to get. * @returns {Token} The found closing parenthesis token. */ function findClosingParen(token) { var node = sourceCode.getNodeByRangeIndex(token.range[1]); while (!astUtils.isParenthesised(sourceCode, node)) { node = node.parent; } return sourceCode.getTokenAfter(node); } /** * Determines whether a arrow function body needs braces * @param {ASTNode} node The arrow function node. * @returns {void} */ function validate(node) { var arrowBody = node.body; if (arrowBody.type === "BlockStatement") { var blockBody = arrowBody.body; if (blockBody.length !== 1 && !never) { return; } if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") { return; } if (never || asNeeded && blockBody[0].type === "ReturnStatement") { var messageId = void 0; if (blockBody.length === 0) { messageId = "unexpectedEmptyBlock"; } else if (blockBody.length > 1) { messageId = "unexpectedOtherBlock"; } else if (blockBody[0].argument === null) { messageId = "unexpectedSingleBlock"; } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) { messageId = "unexpectedObjectBlock"; } else { messageId = "unexpectedSingleBlock"; } context.report({ node: node, loc: arrowBody.loc.start, messageId: messageId, fix: function fix(fixer) { var fixes = []; if (blockBody.length !== 1 || blockBody[0].type !== "ReturnStatement" || !blockBody[0].argument || hasASIProblem(sourceCode.getTokenAfter(arrowBody))) { return fixes; } var openingBrace = sourceCode.getFirstToken(arrowBody); var closingBrace = sourceCode.getLastToken(arrowBody); var firstValueToken = sourceCode.getFirstToken(blockBody[0], 1); var lastValueToken = sourceCode.getLastToken(blockBody[0]); var commentsExist = sourceCode.commentsExistBetween(openingBrace, firstValueToken) || sourceCode.commentsExistBetween(lastValueToken, closingBrace); /* * Remove tokens around the return value. * If comments don't exist, remove extra spaces as well. */ if (commentsExist) { fixes.push(fixer.remove(openingBrace), fixer.remove(closingBrace), fixer.remove(sourceCode.getTokenAfter(openingBrace)) // return keyword ); } else { fixes.push(fixer.removeRange([openingBrace.range[0], firstValueToken.range[0]]), fixer.removeRange([lastValueToken.range[1], closingBrace.range[1]])); } /* * If the first token of the reutrn value is `{`, * enclose the return value by parentheses to avoid syntax error. */ if (astUtils.isOpeningBraceToken(firstValueToken)) { fixes.push(fixer.insertTextBefore(firstValueToken, "("), fixer.insertTextAfter(lastValueToken, ")")); } /* * If the last token of the return statement is semicolon, remove it. * Non-block arrow body is an expression, not a statement. */ if (astUtils.isSemicolonToken(lastValueToken)) { fixes.push(fixer.remove(lastValueToken)); } return fixes; } }); } } else { if (always || asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression") { context.report({ node: node, loc: arrowBody.loc.start, messageId: "expectedBlock", fix: function fix(fixer) { var fixes = []; var arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken); var firstBodyToken = sourceCode.getTokenAfter(arrowToken); var lastBodyToken = sourceCode.getLastToken(node); var isParenthesisedObjectLiteral = astUtils.isOpeningParenToken(firstBodyToken) && astUtils.isOpeningBraceToken(sourceCode.getTokenAfter(firstBodyToken)); // Wrap the value by a block and a return statement. fixes.push(fixer.insertTextBefore(firstBodyToken, "{return "), fixer.insertTextAfter(lastBodyToken, "}")); // If the value is object literal, remove parentheses which were forced by syntax. if (isParenthesisedObjectLiteral) { fixes.push(fixer.remove(firstBodyToken), fixer.remove(findClosingParen(firstBodyToken))); } return fixes; } }); } } } return { "ArrowFunctionExpression:exit": validate }; } }; },{"../util/ast-utils":405}],131:[function(require,module,exports){ /** * @fileoverview Rule to require parens in arrow function arguments. * @author Jxck */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require parentheses around arrow function arguments", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/arrow-parens" }, fixable: "code", schema: [{ enum: ["always", "as-needed"] }, { type: "object", properties: { requireForBlockBody: { type: "boolean" } }, additionalProperties: false }], messages: { unexpectedParens: "Unexpected parentheses around single function argument.", expectedParens: "Expected parentheses around arrow function argument.", unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.", expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces." } }, create: function create(context) { var asNeeded = context.options[0] === "as-needed"; var requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true; var sourceCode = context.getSourceCode(); /** * Determines whether a arrow function argument end with `)` * @param {ASTNode} node The arrow function node. * @returns {void} */ function parens(node) { var isAsync = node.async; var firstTokenOfParam = sourceCode.getFirstToken(node, isAsync ? 1 : 0); /** * Remove the parenthesis around a parameter * @param {Fixer} fixer Fixer * @returns {string} fixed parameter */ function fixParamsWithParenthesis(fixer) { var paramToken = sourceCode.getTokenAfter(firstTokenOfParam); /* * ES8 allows Trailing commas in function parameter lists and calls * https://github.com/eslint/eslint/issues/8834 */ var closingParenToken = sourceCode.getTokenAfter(paramToken, astUtils.isClosingParenToken); var asyncToken = isAsync ? sourceCode.getTokenBefore(firstTokenOfParam) : null; var shouldAddSpaceForAsync = asyncToken && asyncToken.range[1] === firstTokenOfParam.range[0]; return fixer.replaceTextRange([firstTokenOfParam.range[0], closingParenToken.range[1]], "" + (shouldAddSpaceForAsync ? " " : "") + paramToken.value); } // "as-needed", { "requireForBlockBody": true }: x => x if (requireForBlockBody && node.params.length === 1 && node.params[0].type === "Identifier" && !node.params[0].typeAnnotation && node.body.type !== "BlockStatement" && !node.returnType) { if (astUtils.isOpeningParenToken(firstTokenOfParam)) { context.report({ node: node, messageId: "unexpectedParensInline", fix: fixParamsWithParenthesis }); } return; } if (requireForBlockBody && node.body.type === "BlockStatement") { if (!astUtils.isOpeningParenToken(firstTokenOfParam)) { context.report({ node: node, messageId: "expectedParensBlock", fix: function fix(fixer) { return fixer.replaceText(firstTokenOfParam, "(" + firstTokenOfParam.value + ")"); } }); } return; } // "as-needed": x => x if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier" && !node.params[0].typeAnnotation && !node.returnType) { if (astUtils.isOpeningParenToken(firstTokenOfParam)) { context.report({ node: node, messageId: "unexpectedParens", fix: fixParamsWithParenthesis }); } return; } if (firstTokenOfParam.type === "Identifier") { var after = sourceCode.getTokenAfter(firstTokenOfParam); // (x) => x if (after.value !== ")") { context.report({ node: node, messageId: "expectedParens", fix: function fix(fixer) { return fixer.replaceText(firstTokenOfParam, "(" + firstTokenOfParam.value + ")"); } }); } } } return { ArrowFunctionExpression: parens }; } }; },{"../util/ast-utils":405}],132:[function(require,module,exports){ /** * @fileoverview Rule to define spacing before/after arrow function's arrow. * @author Jxck */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before and after the arrow in arrow functions", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/arrow-spacing" }, fixable: "whitespace", schema: [{ type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }], messages: { expectedBefore: "Missing space before =>.", unexpectedBefore: "Unexpected space before =>.", expectedAfter: "Missing space after =>.", unexpectedAfter: "Unexpected space after =>." } }, create: function create(context) { // merge rules with default var rule = { before: true, after: true }, option = context.options[0] || {}; rule.before = option.before !== false; rule.after = option.after !== false; var sourceCode = context.getSourceCode(); /** * Get tokens of arrow(`=>`) and before/after arrow. * @param {ASTNode} node The arrow function node. * @returns {Object} Tokens of arrow and before/after arrow. */ function getTokens(node) { var arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken); return { before: sourceCode.getTokenBefore(arrow), arrow: arrow, after: sourceCode.getTokenAfter(arrow) }; } /** * Count spaces before/after arrow(`=>`) token. * @param {Object} tokens Tokens before/after arrow. * @returns {Object} count of space before/after arrow. */ function countSpaces(tokens) { var before = tokens.arrow.range[0] - tokens.before.range[1]; var after = tokens.after.range[0] - tokens.arrow.range[1]; return { before: before, after: after }; } /** * Determines whether space(s) before after arrow(`=>`) is satisfy rule. * if before/after value is `true`, there should be space(s). * if before/after value is `false`, there should be no space. * @param {ASTNode} node The arrow function node. * @returns {void} */ function spaces(node) { var tokens = getTokens(node); var countSpace = countSpaces(tokens); if (rule.before) { // should be space(s) before arrow if (countSpace.before === 0) { context.report({ node: tokens.before, messageId: "expectedBefore", fix: function fix(fixer) { return fixer.insertTextBefore(tokens.arrow, " "); } }); } } else { // should be no space before arrow if (countSpace.before > 0) { context.report({ node: tokens.before, messageId: "unexpectedBefore", fix: function fix(fixer) { return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); } }); } } if (rule.after) { // should be space(s) after arrow if (countSpace.after === 0) { context.report({ node: tokens.after, messageId: "expectedAfter", fix: function fix(fixer) { return fixer.insertTextAfter(tokens.arrow, " "); } }); } } else { // should be no space after arrow if (countSpace.after > 0) { context.report({ node: tokens.after, messageId: "unexpectedAfter", fix: function fix(fixer) { return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); } }); } } } return { ArrowFunctionExpression: spaces }; } }; },{"../util/ast-utils":405}],133:[function(require,module,exports){ /** * @fileoverview Rule to check for "block scoped" variables by binding context * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce the use of variables within the scope they are defined", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/block-scoped-var" }, schema: [], messages: { outOfScope: "'{{name}}' used outside of binding context." } }, create: function create(context) { var stack = []; /** * Makes a block scope. * @param {ASTNode} node - A node of a scope. * @returns {void} */ function enterScope(node) { stack.push(node.range); } /** * Pops the last block scope. * @returns {void} */ function exitScope() { stack.pop(); } /** * Reports a given reference. * @param {eslint-scope.Reference} reference - A reference to report. * @returns {void} */ function report(reference) { var identifier = reference.identifier; context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } }); } /** * Finds and reports references which are outside of valid scopes. * @param {ASTNode} node - A node to get variables. * @returns {void} */ function checkForVariables(node) { if (node.kind !== "var") { return; } // Defines a predicate to check whether or not a given reference is outside of valid scope. var scopeRange = stack[stack.length - 1]; /** * Check if a reference is out of scope * @param {ASTNode} reference node to examine * @returns {boolean} True is its outside the scope * @private */ function isOutsideOfScope(reference) { var idRange = reference.identifier.range; return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1]; } // Gets declared variables, and checks its references. var variables = context.getDeclaredVariables(node); for (var i = 0; i < variables.length; ++i) { // Reports. variables[i].references.filter(isOutsideOfScope).forEach(report); } } return { Program: function Program(node) { stack = [node.range]; }, // Manages scopes. BlockStatement: enterScope, "BlockStatement:exit": exitScope, ForStatement: enterScope, "ForStatement:exit": exitScope, ForInStatement: enterScope, "ForInStatement:exit": exitScope, ForOfStatement: enterScope, "ForOfStatement:exit": exitScope, SwitchStatement: enterScope, "SwitchStatement:exit": exitScope, CatchClause: enterScope, "CatchClause:exit": exitScope, // Finds and reports references which are outside of valid scope. VariableDeclaration: checkForVariables }; } }; },{}],134:[function(require,module,exports){ /** * @fileoverview A rule to disallow or enforce spaces inside of single line blocks. * @author Toru Nagashima */ "use strict"; var util = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow or enforce spaces inside of blocks after opening block and before closing block", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/block-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }], messages: { missing: "Requires a space {{location}} '{{token}}'", extra: "Unexpected space(s) {{location}} '{{token}}'" } }, create: function create(context) { var always = context.options[0] !== "never", messageId = always ? "missing" : "extra", sourceCode = context.getSourceCode(); /** * Gets the open brace token from a given node. * @param {ASTNode} node - A BlockStatement/SwitchStatement node to get. * @returns {Token} The token of the open brace. */ function getOpenBrace(node) { if (node.type === "SwitchStatement") { if (node.cases.length > 0) { return sourceCode.getTokenBefore(node.cases[0]); } return sourceCode.getLastToken(node, 1); } return sourceCode.getFirstToken(node); } /** * Checks whether or not: * - given tokens are on same line. * - there is/isn't a space between given tokens. * @param {Token} left - A token to check. * @param {Token} right - The token which is next to `left`. * @returns {boolean} * When the option is `"always"`, `true` if there are one or more spaces between given tokens. * When the option is `"never"`, `true` if there are not any spaces between given tokens. * If given tokens are not on same line, it's always `true`. */ function isValid(left, right) { return !util.isTokenOnSameLine(left, right) || sourceCode.isSpaceBetweenTokens(left, right) === always; } /** * Reports invalid spacing style inside braces. * @param {ASTNode} node - A BlockStatement/SwitchStatement node to get. * @returns {void} */ function checkSpacingInsideBraces(node) { // Gets braces and the first/last token of content. var openBrace = getOpenBrace(node); var closeBrace = sourceCode.getLastToken(node); var firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true }); var lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); // Skip if the node is invalid or empty. if (openBrace.type !== "Punctuator" || openBrace.value !== "{" || closeBrace.type !== "Punctuator" || closeBrace.value !== "}" || firstToken === closeBrace) { return; } // Skip line comments for option never if (!always && firstToken.type === "Line") { return; } // Check. if (!isValid(openBrace, firstToken)) { context.report({ node: node, loc: openBrace.loc.start, messageId: messageId, data: { location: "after", token: openBrace.value }, fix: function fix(fixer) { if (always) { return fixer.insertTextBefore(firstToken, " "); } return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); } }); } if (!isValid(lastToken, closeBrace)) { context.report({ node: node, loc: closeBrace.loc.start, messageId: messageId, data: { location: "before", token: closeBrace.value }, fix: function fix(fixer) { if (always) { return fixer.insertTextAfter(lastToken, " "); } return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); } }); } } return { BlockStatement: checkSpacingInsideBraces, SwitchStatement: checkSpacingInsideBraces }; } }; },{"../util/ast-utils":405}],135:[function(require,module,exports){ /** * @fileoverview Rule to flag block statements that do not use the one true brace style * @author Ian Christian Myers */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent brace style for blocks", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/brace-style" }, schema: [{ enum: ["1tbs", "stroustrup", "allman"] }, { type: "object", properties: { allowSingleLine: { type: "boolean" } }, additionalProperties: false }], fixable: "whitespace", messages: { nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.", sameLineOpen: "Opening curly brace appears on the same line as controlling statement.", blockSameLine: "Statement inside of curly braces should be on next line.", nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.", singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.", sameLineClose: "Closing curly brace appears on the same line as the subsequent block." } }, create: function create(context) { var style = context.options[0] || "1tbs", params = context.options[1] || {}, sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Fixes a place where a newline unexpectedly appears * @param {Token} firstToken The token before the unexpected newline * @param {Token} secondToken The token after the unexpected newline * @returns {Function} A fixer function to remove the newlines between the tokens */ function removeNewlineBetween(firstToken, secondToken) { var textRange = [firstToken.range[1], secondToken.range[0]]; var textBetween = sourceCode.text.slice(textRange[0], textRange[1]); // Don't do a fix if there is a comment between the tokens if (textBetween.trim()) { return null; } return function (fixer) { return fixer.replaceTextRange(textRange, " "); }; } /** * Validates a pair of curly brackets based on the user's config * @param {Token} openingCurly The opening curly bracket * @param {Token} closingCurly The closing curly bracket * @returns {void} */ function validateCurlyPair(openingCurly, closingCurly) { var tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly); var tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly); var tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly); var singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly); if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) { context.report({ node: openingCurly, messageId: "nextLineOpen", fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly) }); } if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) { context.report({ node: openingCurly, messageId: "sameLineOpen", fix: function fix(fixer) { return fixer.insertTextBefore(openingCurly, "\n"); } }); } if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) { context.report({ node: openingCurly, messageId: "blockSameLine", fix: function fix(fixer) { return fixer.insertTextAfter(openingCurly, "\n"); } }); } if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) { context.report({ node: closingCurly, messageId: "singleLineClose", fix: function fix(fixer) { return fixer.insertTextBefore(closingCurly, "\n"); } }); } } /** * Validates the location of a token that appears before a keyword (e.g. a newline before `else`) * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`). * @returns {void} */ function validateCurlyBeforeKeyword(curlyToken) { var keywordToken = sourceCode.getTokenAfter(curlyToken); if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { context.report({ node: curlyToken, messageId: "nextLineClose", fix: removeNewlineBetween(curlyToken, keywordToken) }); } if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { context.report({ node: curlyToken, messageId: "sameLineClose", fix: function fix(fixer) { return fixer.insertTextAfter(curlyToken, "\n"); } }); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { BlockStatement: function BlockStatement(node) { if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); } }, ClassBody: function ClassBody(node) { validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); }, SwitchStatement: function SwitchStatement(node) { var closingCurly = sourceCode.getLastToken(node); var openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly); validateCurlyPair(openingCurly, closingCurly); }, IfStatement: function IfStatement(node) { if (node.consequent.type === "BlockStatement" && node.alternate) { // Handle the keyword after the `if` block (before `else`) validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent)); } }, TryStatement: function TryStatement(node) { // Handle the keyword after the `try` block (before `catch` or `finally`) validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block)); if (node.handler && node.finalizer) { // Handle the keyword after the `catch` block (before `finally`) validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body)); } } }; } }; },{"../util/ast-utils":405}],136:[function(require,module,exports){ /** * @fileoverview Enforce return after a callback. * @author Jamund Ferguson */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `return` statements after callbacks", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/callback-return" }, schema: [{ type: "array", items: { type: "string" } }], messages: { missingReturn: "Expected return with your callback function." } }, create: function create(context) { var callbacks = context.options[0] || ["callback", "cb", "next"], sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Find the closest parent matching a list of types. * @param {ASTNode} node The node whose parents we are searching * @param {Array} types The node types to match * @returns {ASTNode} The matched node or undefined. */ function findClosestParentOfType(node, types) { if (!node.parent) { return null; } if (types.indexOf(node.parent.type) === -1) { return findClosestParentOfType(node.parent, types); } return node.parent; } /** * Check to see if a node contains only identifers * @param {ASTNode} node The node to check * @returns {boolean} Whether or not the node contains only identifers */ function containsOnlyIdentifiers(node) { if (node.type === "Identifier") { return true; } if (node.type === "MemberExpression") { if (node.object.type === "Identifier") { return true; } if (node.object.type === "MemberExpression") { return containsOnlyIdentifiers(node.object); } } return false; } /** * Check to see if a CallExpression is in our callback list. * @param {ASTNode} node The node to check against our callback names list. * @returns {boolean} Whether or not this function matches our callback name. */ function isCallback(node) { return containsOnlyIdentifiers(node.callee) && callbacks.indexOf(sourceCode.getText(node.callee)) > -1; } /** * Determines whether or not the callback is part of a callback expression. * @param {ASTNode} node The callback node * @param {ASTNode} parentNode The expression node * @returns {boolean} Whether or not this is part of a callback expression */ function isCallbackExpression(node, parentNode) { // ensure the parent node exists and is an expression if (!parentNode || parentNode.type !== "ExpressionStatement") { return false; } // cb() if (parentNode.expression === node) { return true; } // special case for cb && cb() and similar if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") { if (parentNode.expression.right === node) { return true; } } return false; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { CallExpression: function CallExpression(node) { // if we're not a callback we can return if (!isCallback(node)) { return; } // find the closest block, return or loop var closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}; // if our parent is a return we know we're ok if (closestBlock.type === "ReturnStatement") { return; } // arrow functions don't always have blocks and implicitly return if (closestBlock.type === "ArrowFunctionExpression") { return; } // block statements are part of functions and most if statements if (closestBlock.type === "BlockStatement") { // find the last item in the block var lastItem = closestBlock.body[closestBlock.body.length - 1]; // if the callback is the last thing in a block that might be ok if (isCallbackExpression(node, lastItem)) { var parentType = closestBlock.parent.type; // but only if the block is part of a function if (parentType === "FunctionExpression" || parentType === "FunctionDeclaration" || parentType === "ArrowFunctionExpression") { return; } } // ending a block with a return is also ok if (lastItem.type === "ReturnStatement") { // but only if the callback is immediately before if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) { return; } } } // as long as you're the child of a function at this point you should be asked to return if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) { context.report({ node: node, messageId: "missingReturn" }); } } }; } }; },{}],137:[function(require,module,exports){ /** * @fileoverview Rule to flag non-camelcased identifiers * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce camelcase naming convention", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/camelcase" }, schema: [{ type: "object", properties: { ignoreDestructuring: { type: "boolean" }, properties: { enum: ["always", "never"] }, allow: { type: "array", items: [{ type: "string" }], minItems: 0, uniqueItems: true } }, additionalProperties: false }], messages: { notCamelCase: "Identifier '{{name}}' is not in camel case." } }, create: function create(context) { var options = context.options[0] || {}; var properties = options.properties || ""; var ignoreDestructuring = options.ignoreDestructuring || false; var allow = options.allow || []; if (properties !== "always" && properties !== "never") { properties = "always"; } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- // contains reported nodes to avoid reporting twice on destructuring with shorthand notation var reported = []; var ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); /** * Checks if a string contains an underscore and isn't all upper-case * @param {string} name The string to check. * @returns {boolean} if the string is underscored * @private */ function isUnderscored(name) { // if there's an underscore, it might be A_CONSTANT, which is okay return name.indexOf("_") > -1 && name !== name.toUpperCase(); } /** * Checks if a string match the ignore list * @param {string} name The string to check. * @returns {boolean} if the string is ignored * @private */ function isAllowed(name) { return allow.findIndex(function (entry) { return name === entry || name.match(new RegExp(entry)); }) !== -1; } /** * Checks if a parent of a node is an ObjectPattern. * @param {ASTNode} node The node to check. * @returns {boolean} if the node is inside an ObjectPattern * @private */ function isInsideObjectPattern(node) { var current = node; while (current) { var parent = current.parent; if (parent && parent.type === "Property" && parent.computed && parent.key === current) { return false; } if (current.type === "ObjectPattern") { return true; } current = parent; } return false; } /** * Reports an AST node as a rule violation. * @param {ASTNode} node The node to report. * @returns {void} * @private */ function report(node) { if (reported.indexOf(node) < 0) { reported.push(node); context.report({ node: node, messageId: "notCamelCase", data: { name: node.name } }); } } return { Identifier: function Identifier(node) { /* * Leading and trailing underscores are commonly used to flag * private/protected identifiers, strip them before checking if underscored */ var name = node.name, nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/g, "")), effectiveParent = node.parent.type === "MemberExpression" ? node.parent.parent : node.parent; // First, we ignore the node if it match the ignore list if (isAllowed(name)) { return; } // MemberExpressions get special rules if (node.parent.type === "MemberExpression") { // "never" check properties if (properties === "never") { return; } // Always report underscored object names if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && nameIsUnderscored) { report(node); // Report AssignmentExpressions only if they are the left side of the assignment } else if (effectiveParent.type === "AssignmentExpression" && nameIsUnderscored && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { report(node); } /* * Properties have their own rules, and * AssignmentPattern nodes can be treated like Properties: * e.g.: const { no_camelcased = false } = bar; */ } else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") { if (node.parent.parent && node.parent.parent.type === "ObjectPattern") { if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) { report(node); } var assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name; if (isUnderscored(name) && node.parent.computed) { report(node); } // prevent checking righthand side of destructured object if (node.parent.key === node && node.parent.value !== node) { return; } var valueIsUnderscored = node.parent.value.name && nameIsUnderscored; // ignore destructuring if the option is set, unless a new identifier is created if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) { report(node); } } // "never" check properties or always ignore destructuring if (properties === "never" || ignoreDestructuring && isInsideObjectPattern(node)) { return; } // don't check right hand side of AssignmentExpression to prevent duplicate warnings if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) { report(node); } // Check if it's an import specifier } else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].indexOf(node.parent.type) >= 0) { // Report only if the local imported identifier is underscored if (node.parent.local && node.parent.local.name === node.name && nameIsUnderscored) { report(node); } // Report anything that is underscored that isn't a CallExpression } else if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { report(node); } } }; } }; },{}],138:[function(require,module,exports){ /** * @fileoverview enforce or disallow capitalization of the first letter of a comment * @author Kevin Partington */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var LETTER_PATTERN = require("../util/patterns/letters"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN, WHITESPACE = /\s/g, MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/, // TODO: Combine w/ max-len pattern? DEFAULTS = { ignorePattern: null, ignoreInlineComments: false, ignoreConsecutiveComments: false }; /* * Base schema body for defining the basic capitalization rule, ignorePattern, * and ignoreInlineComments values. * This can be used in a few different ways in the actual schema. */ var SCHEMA_BODY = { type: "object", properties: { ignorePattern: { type: "string" }, ignoreInlineComments: { type: "boolean" }, ignoreConsecutiveComments: { type: "boolean" } }, additionalProperties: false }; /** * Get normalized options for either block or line comments from the given * user-provided options. * - If the user-provided options is just a string, returns a normalized * set of options using default values for all other options. * - If the user-provided options is an object, then a normalized option * set is returned. Options specified in overrides will take priority * over options specified in the main options object, which will in * turn take priority over the rule's defaults. * * @param {Object|string} rawOptions The user-provided options. * @param {string} which Either "line" or "block". * @returns {Object} The normalized options. */ function getNormalizedOptions(rawOptions, which) { if (!rawOptions) { return Object.assign({}, DEFAULTS); } return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions); } /** * Get normalized options for block and line comments. * * @param {Object|string} rawOptions The user-provided options. * @returns {Object} An object with "Line" and "Block" keys and corresponding * normalized options objects. */ function getAllNormalizedOptions(rawOptions) { return { Line: getNormalizedOptions(rawOptions, "line"), Block: getNormalizedOptions(rawOptions, "block") }; } /** * Creates a regular expression for each ignorePattern defined in the rule * options. * * This is done in order to avoid invoking the RegExp constructor repeatedly. * * @param {Object} normalizedOptions The normalized rule options. * @returns {void} */ function createRegExpForIgnorePatterns(normalizedOptions) { Object.keys(normalizedOptions).forEach(function (key) { var ignorePatternStr = normalizedOptions[key].ignorePattern; if (ignorePatternStr) { var regExp = RegExp("^\\s*(?:" + ignorePatternStr + ")"); normalizedOptions[key].ignorePatternRegExp = regExp; } }); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce or disallow capitalization of the first letter of a comment", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/capitalized-comments" }, fixable: "code", schema: [{ enum: ["always", "never"] }, { oneOf: [SCHEMA_BODY, { type: "object", properties: { line: SCHEMA_BODY, block: SCHEMA_BODY }, additionalProperties: false }] }], messages: { unexpectedLowercaseComment: "Comments should not begin with a lowercase character", unexpectedUppercaseComment: "Comments should not begin with an uppercase character" } }, create: function create(context) { var capitalize = context.options[0] || "always", normalizedOptions = getAllNormalizedOptions(context.options[1]), sourceCode = context.getSourceCode(); createRegExpForIgnorePatterns(normalizedOptions); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Checks whether a comment is an inline comment. * * For the purpose of this rule, a comment is inline if: * 1. The comment is preceded by a token on the same line; and * 2. The command is followed by a token on the same line. * * Note that the comment itself need not be single-line! * * Also, it follows from this definition that only block comments can * be considered as possibly inline. This is because line comments * would consume any following tokens on the same line as the comment. * * @param {ASTNode} comment The comment node to check. * @returns {boolean} True if the comment is an inline comment, false * otherwise. */ function isInlineComment(comment) { var previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }), nextToken = sourceCode.getTokenAfter(comment, { includeComments: true }); return Boolean(previousToken && nextToken && comment.loc.start.line === previousToken.loc.end.line && comment.loc.end.line === nextToken.loc.start.line); } /** * Determine if a comment follows another comment. * * @param {ASTNode} comment The comment to check. * @returns {boolean} True if the comment follows a valid comment. */ function isConsecutiveComment(comment) { var previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true }); return Boolean(previousTokenOrComment && ["Block", "Line"].indexOf(previousTokenOrComment.type) !== -1); } /** * Check a comment to determine if it is valid for this rule. * * @param {ASTNode} comment The comment node to process. * @param {Object} options The options for checking this comment. * @returns {boolean} True if the comment is valid, false otherwise. */ function isCommentValid(comment, options) { // 1. Check for default ignore pattern. if (DEFAULT_IGNORE_PATTERN.test(comment.value)) { return true; } // 2. Check for custom ignore pattern. var commentWithoutAsterisks = comment.value.replace(/\*/g, ""); if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { return true; } // 3. Check for inline comments. if (options.ignoreInlineComments && isInlineComment(comment)) { return true; } // 4. Is this a consecutive comment (and are we tolerating those)? if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) { return true; } // 5. Does the comment start with a possible URL? if (MAYBE_URL.test(commentWithoutAsterisks)) { return true; } // 6. Is the initial word character a letter? var commentWordCharsOnly = commentWithoutAsterisks.replace(WHITESPACE, ""); if (commentWordCharsOnly.length === 0) { return true; } var firstWordChar = commentWordCharsOnly[0]; if (!LETTER_PATTERN.test(firstWordChar)) { return true; } // 7. Check the case of the initial word character. var isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(), isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase(); if (capitalize === "always" && isLowercase) { return false; } if (capitalize === "never" && isUppercase) { return false; } return true; } /** * Process a comment to determine if it needs to be reported. * * @param {ASTNode} comment The comment node to process. * @returns {void} */ function processComment(comment) { var options = normalizedOptions[comment.type], commentValid = isCommentValid(comment, options); if (!commentValid) { var messageId = capitalize === "always" ? "unexpectedLowercaseComment" : "unexpectedUppercaseComment"; context.report({ node: null, // Intentionally using loc instead loc: comment.loc, messageId: messageId, fix: function fix(fixer) { var match = comment.value.match(LETTER_PATTERN); return fixer.replaceTextRange( // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*) [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3], capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase()); } }); } } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { Program: function Program() { var comments = sourceCode.getAllComments(); comments.filter(function (token) { return token.type !== "Shebang"; }).forEach(processComment); } }; } }; },{"../util/ast-utils":405,"../util/patterns/letters":411}],139:[function(require,module,exports){ /** * @fileoverview Rule to enforce that all class methods use 'this'. * @author Patrick Williams */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce that class methods utilize `this`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/class-methods-use-this" }, schema: [{ type: "object", properties: { exceptMethods: { type: "array", items: { type: "string" } } }, additionalProperties: false }], messages: { missingThis: "Expected 'this' to be used by class method '{{name}}'." } }, create: function create(context) { var config = context.options[0] ? Object.assign({}, context.options[0]) : {}; var exceptMethods = new Set(config.exceptMethods || []); var stack = []; /** * Initializes the current context to false and pushes it onto the stack. * These booleans represent whether 'this' has been used in the context. * @returns {void} * @private */ function enterFunction() { stack.push(false); } /** * Check if the node is an instance method * @param {ASTNode} node - node to check * @returns {boolean} True if its an instance method * @private */ function isInstanceMethod(node) { return !node.static && node.kind !== "constructor" && node.type === "MethodDefinition"; } /** * Check if the node is an instance method not excluded by config * @param {ASTNode} node - node to check * @returns {boolean} True if it is an instance method, and not excluded by config * @private */ function isIncludedInstanceMethod(node) { return isInstanceMethod(node) && !exceptMethods.has(node.key.name); } /** * Checks if we are leaving a function that is a method, and reports if 'this' has not been used. * Static methods and the constructor are exempt. * Then pops the context off the stack. * @param {ASTNode} node - A function node that was entered. * @returns {void} * @private */ function exitFunction(node) { var methodUsesThis = stack.pop(); if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) { context.report({ node: node, messageId: "missingThis", data: { name: node.parent.key.name } }); } } /** * Mark the current context as having used 'this'. * @returns {void} * @private */ function markThisUsed() { if (stack.length) { stack[stack.length - 1] = true; } } return { FunctionDeclaration: enterFunction, "FunctionDeclaration:exit": exitFunction, FunctionExpression: enterFunction, "FunctionExpression:exit": exitFunction, ThisExpression: markThisUsed, Super: markThisUsed }; } }; },{}],140:[function(require,module,exports){ /** * @fileoverview Rule to forbid or enforce dangling commas. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var DEFAULT_OPTIONS = Object.freeze({ arrays: "never", objects: "never", imports: "never", exports: "never", functions: "ignore" }); /** * Checks whether or not a trailing comma is allowed in a given node. * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas. * * @param {ASTNode} lastItem - The node of the last element in the given node. * @returns {boolean} `true` if a trailing comma is allowed. */ function isTrailingCommaAllowed(lastItem) { return !(lastItem.type === "RestElement" || lastItem.type === "RestProperty" || lastItem.type === "ExperimentalRestProperty"); } /** * Normalize option value. * * @param {string|Object|undefined} optionValue - The 1st option value to normalize. * @returns {Object} The normalized option value. */ function normalizeOptions(optionValue) { if (typeof optionValue === "string") { return { arrays: optionValue, objects: optionValue, imports: optionValue, exports: optionValue, // For backward compatibility, always ignore functions. functions: "ignore" }; } if ((typeof optionValue === "undefined" ? "undefined" : _typeof(optionValue)) === "object" && optionValue !== null) { return { arrays: optionValue.arrays || DEFAULT_OPTIONS.arrays, objects: optionValue.objects || DEFAULT_OPTIONS.objects, imports: optionValue.imports || DEFAULT_OPTIONS.imports, exports: optionValue.exports || DEFAULT_OPTIONS.exports, functions: optionValue.functions || DEFAULT_OPTIONS.functions }; } return DEFAULT_OPTIONS; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow trailing commas", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/comma-dangle" }, fixable: "code", schema: { definitions: { value: { enum: ["always-multiline", "always", "never", "only-multiline"] }, valueWithIgnore: { enum: ["always-multiline", "always", "ignore", "never", "only-multiline"] } }, type: "array", items: [{ oneOf: [{ $ref: "#/definitions/value" }, { type: "object", properties: { arrays: { $ref: "#/definitions/valueWithIgnore" }, objects: { $ref: "#/definitions/valueWithIgnore" }, imports: { $ref: "#/definitions/valueWithIgnore" }, exports: { $ref: "#/definitions/valueWithIgnore" }, functions: { $ref: "#/definitions/valueWithIgnore" } }, additionalProperties: false }] }] }, messages: { unexpected: "Unexpected trailing comma.", missing: "Missing trailing comma." } }, create: function create(context) { var options = normalizeOptions(context.options[0]); var sourceCode = context.getSourceCode(); /** * Gets the last item of the given node. * @param {ASTNode} node - The node to get. * @returns {ASTNode|null} The last node or null. */ function getLastItem(node) { switch (node.type) { case "ObjectExpression": case "ObjectPattern": return lodash.last(node.properties); case "ArrayExpression": case "ArrayPattern": return lodash.last(node.elements); case "ImportDeclaration": case "ExportNamedDeclaration": return lodash.last(node.specifiers); case "FunctionDeclaration": case "FunctionExpression": case "ArrowFunctionExpression": return lodash.last(node.params); case "CallExpression": case "NewExpression": return lodash.last(node.arguments); default: return null; } } /** * Gets the trailing comma token of the given node. * If the trailing comma does not exist, this returns the token which is * the insertion point of the trailing comma token. * * @param {ASTNode} node - The node to get. * @param {ASTNode} lastItem - The last item of the node. * @returns {Token} The trailing comma token or the insertion point. */ function getTrailingToken(node, lastItem) { switch (node.type) { case "ObjectExpression": case "ArrayExpression": case "CallExpression": case "NewExpression": return sourceCode.getLastToken(node, 1); default: { var nextToken = sourceCode.getTokenAfter(lastItem); if (astUtils.isCommaToken(nextToken)) { return nextToken; } return sourceCode.getLastToken(lastItem); } } } /** * Checks whether or not a given node is multiline. * This rule handles a given node as multiline when the closing parenthesis * and the last element are not on the same line. * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is multiline. */ function isMultiline(node) { var lastItem = getLastItem(node); if (!lastItem) { return false; } var penultimateToken = getTrailingToken(node, lastItem); var lastToken = sourceCode.getTokenAfter(penultimateToken); return lastToken.loc.end.line !== penultimateToken.loc.end.line; } /** * Reports a trailing comma if it exists. * * @param {ASTNode} node - A node to check. Its type is one of * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, * ImportDeclaration, and ExportNamedDeclaration. * @returns {void} */ function forbidTrailingComma(node) { var lastItem = getLastItem(node); if (!lastItem || node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier") { return; } var trailingToken = getTrailingToken(node, lastItem); if (astUtils.isCommaToken(trailingToken)) { context.report({ node: lastItem, loc: trailingToken.loc.start, messageId: "unexpected", fix: function fix(fixer) { return fixer.remove(trailingToken); } }); } } /** * Reports the last element of a given node if it does not have a trailing * comma. * * If a given node is `ArrayPattern` which has `RestElement`, the trailing * comma is disallowed, so report if it exists. * * @param {ASTNode} node - A node to check. Its type is one of * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, * ImportDeclaration, and ExportNamedDeclaration. * @returns {void} */ function forceTrailingComma(node) { var lastItem = getLastItem(node); if (!lastItem || node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier") { return; } if (!isTrailingCommaAllowed(lastItem)) { forbidTrailingComma(node); return; } var trailingToken = getTrailingToken(node, lastItem); if (trailingToken.value !== ",") { context.report({ node: lastItem, loc: trailingToken.loc.end, messageId: "missing", fix: function fix(fixer) { return fixer.insertTextAfter(trailingToken, ","); } }); } } /** * If a given node is multiline, reports the last element of a given node * when it does not have a trailing comma. * Otherwise, reports a trailing comma if it exists. * * @param {ASTNode} node - A node to check. Its type is one of * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, * ImportDeclaration, and ExportNamedDeclaration. * @returns {void} */ function forceTrailingCommaIfMultiline(node) { if (isMultiline(node)) { forceTrailingComma(node); } else { forbidTrailingComma(node); } } /** * Only if a given node is not multiline, reports the last element of a given node * when it does not have a trailing comma. * Otherwise, reports a trailing comma if it exists. * * @param {ASTNode} node - A node to check. Its type is one of * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, * ImportDeclaration, and ExportNamedDeclaration. * @returns {void} */ function allowTrailingCommaIfMultiline(node) { if (!isMultiline(node)) { forbidTrailingComma(node); } } var predicate = { always: forceTrailingComma, "always-multiline": forceTrailingCommaIfMultiline, "only-multiline": allowTrailingCommaIfMultiline, never: forbidTrailingComma, ignore: lodash.noop }; return { ObjectExpression: predicate[options.objects], ObjectPattern: predicate[options.objects], ArrayExpression: predicate[options.arrays], ArrayPattern: predicate[options.arrays], ImportDeclaration: predicate[options.imports], ExportNamedDeclaration: predicate[options.exports], FunctionDeclaration: predicate[options.functions], FunctionExpression: predicate[options.functions], ArrowFunctionExpression: predicate[options.functions], CallExpression: predicate[options.functions], NewExpression: predicate[options.functions] }; } }; },{"../util/ast-utils":405,"lodash":92}],141:[function(require,module,exports){ /** * @fileoverview Comma spacing - validates spacing before and after comma * @author Vignesh Anand aka vegetableman. */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before and after commas", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/comma-spacing" }, fixable: "whitespace", schema: [{ type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }], messages: { missing: "A space is required {{loc}} ','.", unexpected: "There should be no space {{loc}} ','." } }, create: function create(context) { var sourceCode = context.getSourceCode(); var tokensAndComments = sourceCode.tokensAndComments; var options = { before: context.options[0] ? !!context.options[0].before : false, after: context.options[0] ? !!context.options[0].after : true }; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- // list of comma tokens to ignore for the check of leading whitespace var commaTokensToIgnore = []; /** * Reports a spacing error with an appropriate message. * @param {ASTNode} node The binary expression node to report. * @param {string} loc Is the error "before" or "after" the comma? * @param {ASTNode} otherNode The node at the left or right of `node` * @returns {void} * @private */ function report(node, loc, otherNode) { context.report({ node: node, fix: function fix(fixer) { if (options[loc]) { if (loc === "before") { return fixer.insertTextBefore(node, " "); } return fixer.insertTextAfter(node, " "); } var start = void 0, end = void 0; var newText = ""; if (loc === "before") { start = otherNode.range[1]; end = node.range[0]; } else { start = node.range[1]; end = otherNode.range[0]; } return fixer.replaceTextRange([start, end], newText); }, messageId: options[loc] ? "missing" : "unexpected", data: { loc: loc } }); } /** * Validates the spacing around a comma token. * @param {Object} tokens - The tokens to be validated. * @param {Token} tokens.comma The token representing the comma. * @param {Token} [tokens.left] The last token before the comma. * @param {Token} [tokens.right] The first token after the comma. * @param {Token|ASTNode} reportItem The item to use when reporting an error. * @returns {void} * @private */ function validateCommaItemSpacing(tokens, reportItem) { if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) && options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma)) { report(reportItem, "before", tokens.left); } if (tokens.right && !options.after && tokens.right.type === "Line") { return; } if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) && options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right)) { report(reportItem, "after", tokens.right); } } /** * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list. * @param {ASTNode} node An ArrayExpression or ArrayPattern node. * @returns {void} */ function addNullElementsToIgnoreList(node) { var previousToken = sourceCode.getFirstToken(node); node.elements.forEach(function (element) { var token = void 0; if (element === null) { token = sourceCode.getTokenAfter(previousToken); if (astUtils.isCommaToken(token)) { commaTokensToIgnore.push(token); } } else { token = sourceCode.getTokenAfter(element); } previousToken = token; }); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { "Program:exit": function ProgramExit() { tokensAndComments.forEach(function (token, i) { if (!astUtils.isCommaToken(token)) { return; } if (token && token.type === "JSXText") { return; } var previousToken = tokensAndComments[i - 1]; var nextToken = tokensAndComments[i + 1]; validateCommaItemSpacing({ comma: token, left: astUtils.isCommaToken(previousToken) || commaTokensToIgnore.indexOf(token) > -1 ? null : previousToken, right: astUtils.isCommaToken(nextToken) ? null : nextToken }, token); }); }, ArrayExpression: addNullElementsToIgnoreList, ArrayPattern: addNullElementsToIgnoreList }; } }; },{"../util/ast-utils":405}],142:[function(require,module,exports){ /** * @fileoverview Comma style - enforces comma styles of two types: last and first * @author Vignesh Anand aka vegetableman */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent comma style", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/comma-style" }, fixable: "code", schema: [{ enum: ["first", "last"] }, { type: "object", properties: { exceptions: { type: "object", additionalProperties: { type: "boolean" } } }, additionalProperties: false }], messages: { unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.", expectedCommaFirst: "',' should be placed first.", expectedCommaLast: "',' should be placed last." } }, create: function create(context) { var style = context.options[0] || "last", sourceCode = context.getSourceCode(); var exceptions = { ArrayPattern: true, ArrowFunctionExpression: true, CallExpression: true, FunctionDeclaration: true, FunctionExpression: true, ImportDeclaration: true, ObjectPattern: true, NewExpression: true }; if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) { var keys = Object.keys(context.options[1].exceptions); for (var i = 0; i < keys.length; i++) { exceptions[keys[i]] = context.options[1].exceptions[keys[i]]; } } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Modified text based on the style * @param {string} styleType Style type * @param {string} text Source code text * @returns {string} modified text * @private */ function getReplacedText(styleType, text) { switch (styleType) { case "between": return "," + text.replace(astUtils.LINEBREAK_MATCHER, ""); case "first": return text + ","; case "last": return "," + text; default: return ""; } } /** * Determines the fixer function for a given style. * @param {string} styleType comma style * @param {ASTNode} previousItemToken The token to check. * @param {ASTNode} commaToken The token to check. * @param {ASTNode} currentItemToken The token to check. * @returns {Function} Fixer function * @private */ function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) { var text = sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) + sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]); var range = [previousItemToken.range[1], currentItemToken.range[0]]; return function (fixer) { return fixer.replaceTextRange(range, getReplacedText(styleType, text)); }; } /** * Validates the spacing around single items in lists. * @param {Token} previousItemToken The last token from the previous item. * @param {Token} commaToken The token representing the comma. * @param {Token} currentItemToken The first token of the current item. * @param {Token} reportItem The item to use when reporting an error. * @returns {void} * @private */ function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) { // if single line if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) && astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { // do nothing. } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { var comment = sourceCode.getCommentsAfter(commaToken)[0]; var styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment) ? style : "between"; // lone comma context.report({ node: reportItem, loc: { line: commaToken.loc.end.line, column: commaToken.loc.start.column }, messageId: "unexpectedLineBeforeAndAfterComma", fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) }); } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { context.report({ node: reportItem, messageId: "expectedCommaFirst", fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) }); } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { context.report({ node: reportItem, loc: { line: commaToken.loc.end.line, column: commaToken.loc.end.column }, messageId: "expectedCommaLast", fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) }); } } /** * Checks the comma placement with regards to a declaration/property/element * @param {ASTNode} node The binary expression node to check * @param {string} property The property of the node containing child nodes. * @private * @returns {void} */ function validateComma(node, property) { var items = node[property], arrayLiteral = node.type === "ArrayExpression" || node.type === "ArrayPattern"; if (items.length > 1 || arrayLiteral) { // seed as opening [ var previousItemToken = sourceCode.getFirstToken(node); items.forEach(function (item) { var commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), reportItem = item || currentItemToken; /* * This works by comparing three token locations: * - previousItemToken is the last token of the previous item * - commaToken is the location of the comma before the current item * - currentItemToken is the first token of the current item * * These values get switched around if item is undefined. * previousItemToken will refer to the last token not belonging * to the current item, which could be a comma or an opening * square bracket. currentItemToken could be a comma. * * All comparisons are done based on these tokens directly, so * they are always valid regardless of an undefined item. */ if (astUtils.isCommaToken(commaToken)) { validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem); } if (item) { var tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken); previousItemToken = tokenAfterItem ? sourceCode.getTokenBefore(tokenAfterItem) : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1]; } }); /* * Special case for array literals that have empty last items, such * as [ 1, 2, ]. These arrays only have two items show up in the * AST, so we need to look at the token to verify that there's no * dangling comma. */ if (arrayLiteral) { var lastToken = sourceCode.getLastToken(node), nextToLastToken = sourceCode.getTokenBefore(lastToken); if (astUtils.isCommaToken(nextToLastToken)) { validateCommaItemSpacing(sourceCode.getTokenBefore(nextToLastToken), nextToLastToken, lastToken, lastToken); } } } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- var nodes = {}; if (!exceptions.VariableDeclaration) { nodes.VariableDeclaration = function (node) { validateComma(node, "declarations"); }; } if (!exceptions.ObjectExpression) { nodes.ObjectExpression = function (node) { validateComma(node, "properties"); }; } if (!exceptions.ObjectPattern) { nodes.ObjectPattern = function (node) { validateComma(node, "properties"); }; } if (!exceptions.ArrayExpression) { nodes.ArrayExpression = function (node) { validateComma(node, "elements"); }; } if (!exceptions.ArrayPattern) { nodes.ArrayPattern = function (node) { validateComma(node, "elements"); }; } if (!exceptions.FunctionDeclaration) { nodes.FunctionDeclaration = function (node) { validateComma(node, "params"); }; } if (!exceptions.FunctionExpression) { nodes.FunctionExpression = function (node) { validateComma(node, "params"); }; } if (!exceptions.ArrowFunctionExpression) { nodes.ArrowFunctionExpression = function (node) { validateComma(node, "params"); }; } if (!exceptions.CallExpression) { nodes.CallExpression = function (node) { validateComma(node, "arguments"); }; } if (!exceptions.ImportDeclaration) { nodes.ImportDeclaration = function (node) { validateComma(node, "specifiers"); }; } if (!exceptions.NewExpression) { nodes.NewExpression = function (node) { validateComma(node, "arguments"); }; } return nodes; } }; },{"../util/ast-utils":405}],143:[function(require,module,exports){ /** * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity. * Counts the number of if, conditional, for, whilte, try, switch/case, * @author Patrick Brosset */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum cyclomatic complexity allowed in a program", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/complexity" }, schema: [{ oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { maximum: { type: "integer", minimum: 0 }, max: { type: "integer", minimum: 0 } }, additionalProperties: false }] }], messages: { complex: "{{name}} has a complexity of {{complexity}}." } }, create: function create(context) { var option = context.options[0]; var THRESHOLD = 20; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") { THRESHOLD = option.maximum; } if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") { THRESHOLD = option.max; } if (typeof option === "number") { THRESHOLD = option; } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- // Using a stack to store complexity (handling nested functions) var fns = []; /** * When parsing a new function, store it in our function stack * @returns {void} * @private */ function startFunction() { fns.push(1); } /** * Evaluate the node at the end of function * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function endFunction(node) { var name = lodash.upperFirst(astUtils.getFunctionNameWithKind(node)); var complexity = fns.pop(); if (complexity > THRESHOLD) { context.report({ node: node, messageId: "complex", data: { name: name, complexity: complexity } }); } } /** * Increase the complexity of the function in context * @returns {void} * @private */ function increaseComplexity() { if (fns.length) { fns[fns.length - 1]++; } } /** * Increase the switch complexity in context * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function increaseSwitchComplexity(node) { // Avoiding `default` if (node.test) { increaseComplexity(); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { FunctionDeclaration: startFunction, FunctionExpression: startFunction, ArrowFunctionExpression: startFunction, "FunctionDeclaration:exit": endFunction, "FunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction, CatchClause: increaseComplexity, ConditionalExpression: increaseComplexity, LogicalExpression: increaseComplexity, ForStatement: increaseComplexity, ForInStatement: increaseComplexity, ForOfStatement: increaseComplexity, IfStatement: increaseComplexity, SwitchCase: increaseSwitchComplexity, WhileStatement: increaseComplexity, DoWhileStatement: increaseComplexity }; } }; },{"../util/ast-utils":405,"lodash":92}],144:[function(require,module,exports){ /** * @fileoverview Disallows or enforces spaces inside computed properties. * @author Jamund Ferguson */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing inside computed property brackets", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/computed-property-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }], messages: { unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", missingSpaceBefore: "A space is required before '{{tokenValue}}'.", missingSpaceAfter: "A space is required after '{{tokenValue}}'." } }, create: function create(context) { var sourceCode = context.getSourceCode(); var propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports that there shouldn't be a space after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @param {Token} tokenAfter - The token after `token`. * @returns {void} */ function reportNoBeginningSpace(node, token, tokenAfter) { context.report({ node: node, loc: token.loc.start, messageId: "unexpectedSpaceAfter", data: { tokenValue: token.value }, fix: function fix(fixer) { return fixer.removeRange([token.range[1], tokenAfter.range[0]]); } }); } /** * Reports that there shouldn't be a space before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @param {Token} tokenBefore - The token before `token`. * @returns {void} */ function reportNoEndingSpace(node, token, tokenBefore) { context.report({ node: node, loc: token.loc.start, messageId: "unexpectedSpaceBefore", data: { tokenValue: token.value }, fix: function fix(fixer) { return fixer.removeRange([tokenBefore.range[1], token.range[0]]); } }); } /** * Reports that there should be a space after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredBeginningSpace(node, token) { context.report({ node: node, loc: token.loc.start, messageId: "missingSpaceAfter", data: { tokenValue: token.value }, fix: function fix(fixer) { return fixer.insertTextAfter(token, " "); } }); } /** * Reports that there should be a space before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredEndingSpace(node, token) { context.report({ node: node, loc: token.loc.start, messageId: "missingSpaceBefore", data: { tokenValue: token.value }, fix: function fix(fixer) { return fixer.insertTextBefore(token, " "); } }); } /** * Returns a function that checks the spacing of a node on the property name * that was passed in. * @param {string} propertyName The property on the node to check for spacing * @returns {Function} A function that will check spacing on a node */ function checkSpacing(propertyName) { return function (node) { if (!node.computed) { return; } var property = node[propertyName]; var before = sourceCode.getTokenBefore(property), first = sourceCode.getFirstToken(property), last = sourceCode.getLastToken(property), after = sourceCode.getTokenAfter(property); if (astUtils.isTokenOnSameLine(before, first)) { if (propertyNameMustBeSpaced) { if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) { reportRequiredBeginningSpace(node, before); } } else { if (sourceCode.isSpaceBetweenTokens(before, first)) { reportNoBeginningSpace(node, before, first); } } } if (astUtils.isTokenOnSameLine(last, after)) { if (propertyNameMustBeSpaced) { if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) { reportRequiredEndingSpace(node, after); } } else { if (sourceCode.isSpaceBetweenTokens(last, after)) { reportNoEndingSpace(node, after, last); } } } }; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Property: checkSpacing("key"), MemberExpression: checkSpacing("property") }; } }; },{"../util/ast-utils":405}],145:[function(require,module,exports){ /** * @fileoverview Rule to flag consistent return values * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is an `Identifier` node which was named a given name. * @param {ASTNode} node - A node to check. * @param {string} name - An expected name of the node. * @returns {boolean} `true` if the node is an `Identifier` node which was named as expected. */ function isIdentifier(node, name) { return node.type === "Identifier" && node.name === name; } /** * Checks whether or not a given code path segment is unreachable. * @param {CodePathSegment} segment - A CodePathSegment to check. * @returns {boolean} `true` if the segment is unreachable. */ function isUnreachable(segment) { return !segment.reachable; } /** * Checks whether a given node is a `constructor` method in an ES6 class * @param {ASTNode} node A node to check * @returns {boolean} `true` if the node is a `constructor` method */ function isClassConstructor(node) { return node.type === "FunctionExpression" && node.parent && node.parent.type === "MethodDefinition" && node.parent.kind === "constructor"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `return` statements to either always or never specify values", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/consistent-return" }, schema: [{ type: "object", properties: { treatUndefinedAsUnspecified: { type: "boolean" } }, additionalProperties: false }], messages: { missingReturn: "Expected to return a value at the end of {{name}}.", missingReturnValue: "{{name}} expected a return value.", unexpectedReturnValue: "{{name}} expected no return value." } }, create: function create(context) { var options = context.options[0] || {}; var treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; var funcInfo = null; /** * Checks whether of not the implicit returning is consistent if the last * code path segment is reachable. * * @param {ASTNode} node - A program/function node to check. * @returns {void} */ function checkLastSegment(node) { var loc = void 0, name = void 0; /* * Skip if it expected no return value or unreachable. * When unreachable, all paths are returned or thrown. */ if (!funcInfo.hasReturnValue || funcInfo.codePath.currentSegments.every(isUnreachable) || astUtils.isES5Constructor(node) || isClassConstructor(node)) { return; } // Adjust a location and a message. if (node.type === "Program") { // The head of program. loc = { line: 1, column: 0 }; name = "program"; } else if (node.type === "ArrowFunctionExpression") { // `=>` token loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc.start; } else if (node.parent.type === "MethodDefinition" || node.parent.type === "Property" && node.parent.method) { // Method name. loc = node.parent.key.loc.start; } else { // Function name or `function` keyword. loc = (node.id || node).loc.start; } if (!name) { name = astUtils.getFunctionNameWithKind(node); } // Reports. context.report({ node: node, loc: loc, messageId: "missingReturn", data: { name: name } }); } return { // Initializes/Disposes state of each code path. onCodePathStart: function onCodePathStart(codePath, node) { funcInfo = { upper: funcInfo, codePath: codePath, hasReturn: false, hasReturnValue: false, messageId: "", node: node }; }, onCodePathEnd: function onCodePathEnd() { funcInfo = funcInfo.upper; }, // Reports a given return statement if it's inconsistent. ReturnStatement: function ReturnStatement(node) { var argument = node.argument; var hasReturnValue = Boolean(argument); if (treatUndefinedAsUnspecified && hasReturnValue) { hasReturnValue = !isIdentifier(argument, "undefined") && argument.operator !== "void"; } if (!funcInfo.hasReturn) { funcInfo.hasReturn = true; funcInfo.hasReturnValue = hasReturnValue; funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue"; funcInfo.data = { name: funcInfo.node.type === "Program" ? "Program" : lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node)) }; } else if (funcInfo.hasReturnValue !== hasReturnValue) { context.report({ node: node, messageId: funcInfo.messageId, data: funcInfo.data }); } }, // Reports a given program/function if the implicit returning is not consistent. "Program:exit": checkLastSegment, "FunctionDeclaration:exit": checkLastSegment, "FunctionExpression:exit": checkLastSegment, "ArrowFunctionExpression:exit": checkLastSegment }; } }; },{"../util/ast-utils":405,"lodash":92}],146:[function(require,module,exports){ /** * @fileoverview Rule to enforce consistent naming of "this" context variables * @author Raphael Pigulla */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce consistent naming when capturing the current execution context", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/consistent-this" }, schema: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true }, messages: { aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.", unexpectedAlias: "Unexpected alias '{{name}}' for 'this'." } }, create: function create(context) { var aliases = []; if (context.options.length === 0) { aliases.push("that"); } else { aliases = context.options; } /** * Reports that a variable declarator or assignment expression is assigning * a non-'this' value to the specified alias. * @param {ASTNode} node - The assigning node. * @param {string} name - the name of the alias that was incorrectly used. * @returns {void} */ function reportBadAssignment(node, name) { context.report({ node: node, messageId: "aliasNotAssignedToThis", data: { name: name } }); } /** * Checks that an assignment to an identifier only assigns 'this' to the * appropriate alias, and the alias is only assigned to 'this'. * @param {ASTNode} node - The assigning node. * @param {Identifier} name - The name of the variable assigned to. * @param {Expression} value - The value of the assignment. * @returns {void} */ function checkAssignment(node, name, value) { var isThis = value.type === "ThisExpression"; if (aliases.indexOf(name) !== -1) { if (!isThis || node.operator && node.operator !== "=") { reportBadAssignment(node, name); } } else if (isThis) { context.report({ node: node, messageId: "unexpectedAlias", data: { name: name } }); } } /** * Ensures that a variable declaration of the alias in a program or function * is assigned to the correct value. * @param {string} alias alias the check the assignment of. * @param {Object} scope scope of the current code we are checking. * @private * @returns {void} */ function checkWasAssigned(alias, scope) { var variable = scope.set.get(alias); if (!variable) { return; } if (variable.defs.some(function (def) { return def.node.type === "VariableDeclarator" && def.node.init !== null; })) { return; } /* * The alias has been declared and not assigned: check it was * assigned later in the same scope. */ if (!variable.references.some(function (reference) { var write = reference.writeExpr; return reference.from === scope && write && write.type === "ThisExpression" && write.parent.operator === "="; })) { variable.defs.map(function (def) { return def.node; }).forEach(function (node) { reportBadAssignment(node, alias); }); } } /** * Check each alias to ensure that is was assinged to the correct value. * @returns {void} */ function ensureWasAssigned() { var scope = context.getScope(); aliases.forEach(function (alias) { checkWasAssigned(alias, scope); }); } return { "Program:exit": ensureWasAssigned, "FunctionExpression:exit": ensureWasAssigned, "FunctionDeclaration:exit": ensureWasAssigned, VariableDeclarator: function VariableDeclarator(node) { var id = node.id; var isDestructuring = id.type === "ArrayPattern" || id.type === "ObjectPattern"; if (node.init !== null && !isDestructuring) { checkAssignment(node, id.name, node.init); } }, AssignmentExpression: function AssignmentExpression(node) { if (node.left.type === "Identifier") { checkAssignment(node, node.left.name, node.right); } } }; } }; },{}],147:[function(require,module,exports){ /** * @fileoverview A rule to verify `super()` callings in constructor. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether a given code path segment is reachable or not. * * @param {CodePathSegment} segment - A code path segment to check. * @returns {boolean} `true` if the segment is reachable. */ function isReachable(segment) { return segment.reachable; } /** * Checks whether or not a given node is a constructor. * @param {ASTNode} node - A node to check. This node type is one of * `Program`, `FunctionDeclaration`, `FunctionExpression`, and * `ArrowFunctionExpression`. * @returns {boolean} `true` if the node is a constructor. */ function isConstructorFunction(node) { return node.type === "FunctionExpression" && node.parent.type === "MethodDefinition" && node.parent.kind === "constructor"; } /** * Checks whether a given node can be a constructor or not. * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node can be a constructor. */ function isPossibleConstructor(node) { if (!node) { return false; } switch (node.type) { case "ClassExpression": case "FunctionExpression": case "ThisExpression": case "MemberExpression": case "CallExpression": case "NewExpression": case "YieldExpression": case "TaggedTemplateExpression": case "MetaProperty": return true; case "Identifier": return node.name !== "undefined"; case "AssignmentExpression": return isPossibleConstructor(node.right); case "LogicalExpression": return isPossibleConstructor(node.left) || isPossibleConstructor(node.right); case "ConditionalExpression": return isPossibleConstructor(node.alternate) || isPossibleConstructor(node.consequent); case "SequenceExpression": { var lastExpression = node.expressions[node.expressions.length - 1]; return isPossibleConstructor(lastExpression); } default: return false; } } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "require `super()` calls in constructors", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/constructor-super" }, schema: [], messages: { missingSome: "Lacked a call of 'super()' in some code paths.", missingAll: "Expected to call 'super()'.", duplicate: "Unexpected duplicate 'super()'.", badSuper: "Unexpected 'super()' because 'super' is not a constructor.", unexpected: "Unexpected 'super()'." } }, create: function create(context) { /* * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} * Information for each constructor. * - upper: Information of the upper constructor. * - hasExtends: A flag which shows whether own class has a valid `extends` * part. * - scope: The scope of own class. * - codePath: The code path object of the constructor. */ var funcInfo = null; /* * {Map} * Information for each code path segment. * - calledInSomePaths: A flag of be called `super()` in some code paths. * - calledInEveryPaths: A flag of be called `super()` in all code paths. * - validNodes: */ var segInfoMap = Object.create(null); /** * Gets the flag which shows `super()` is called in some paths. * @param {CodePathSegment} segment - A code path segment to get. * @returns {boolean} The flag which shows `super()` is called in some paths */ function isCalledInSomePath(segment) { return segment.reachable && segInfoMap[segment.id].calledInSomePaths; } /** * Gets the flag which shows `super()` is called in all paths. * @param {CodePathSegment} segment - A code path segment to get. * @returns {boolean} The flag which shows `super()` is called in all paths. */ function isCalledInEveryPath(segment) { /* * If specific segment is the looped segment of the current segment, * skip the segment. * If not skipped, this never becomes true after a loop. */ if (segment.nextSegments.length === 1 && segment.nextSegments[0].isLoopedPrevSegment(segment)) { return true; } return segment.reachable && segInfoMap[segment.id].calledInEveryPaths; } return { /** * Stacks a constructor information. * @param {CodePath} codePath - A code path which was started. * @param {ASTNode} node - The current node. * @returns {void} */ onCodePathStart: function onCodePathStart(codePath, node) { if (isConstructorFunction(node)) { // Class > ClassBody > MethodDefinition > FunctionExpression var classNode = node.parent.parent.parent; var superClass = classNode.superClass; funcInfo = { upper: funcInfo, isConstructor: true, hasExtends: Boolean(superClass), superIsConstructor: isPossibleConstructor(superClass), codePath: codePath }; } else { funcInfo = { upper: funcInfo, isConstructor: false, hasExtends: false, superIsConstructor: false, codePath: codePath }; } }, /** * Pops a constructor information. * And reports if `super()` lacked. * @param {CodePath} codePath - A code path which was ended. * @param {ASTNode} node - The current node. * @returns {void} */ onCodePathEnd: function onCodePathEnd(codePath, node) { var hasExtends = funcInfo.hasExtends; // Pop. funcInfo = funcInfo.upper; if (!hasExtends) { return; } // Reports if `super()` lacked. var segments = codePath.returnedSegments; var calledInEveryPaths = segments.every(isCalledInEveryPath); var calledInSomePaths = segments.some(isCalledInSomePath); if (!calledInEveryPaths) { context.report({ messageId: calledInSomePaths ? "missingSome" : "missingAll", node: node.parent }); } }, /** * Initialize information of a given code path segment. * @param {CodePathSegment} segment - A code path segment to initialize. * @returns {void} */ onCodePathSegmentStart: function onCodePathSegmentStart(segment) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { return; } // Initialize info. var info = segInfoMap[segment.id] = { calledInSomePaths: false, calledInEveryPaths: false, validNodes: [] }; // When there are previous segments, aggregates these. var prevSegments = segment.prevSegments; if (prevSegments.length > 0) { info.calledInSomePaths = prevSegments.some(isCalledInSomePath); info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); } }, /** * Update information of the code path segment when a code path was * looped. * @param {CodePathSegment} fromSegment - The code path segment of the * end of a loop. * @param {CodePathSegment} toSegment - A code path segment of the head * of a loop. * @returns {void} */ onCodePathSegmentLoop: function onCodePathSegmentLoop(fromSegment, toSegment) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { return; } // Update information inside of the loop. var isRealLoop = toSegment.prevSegments.length >= 2; funcInfo.codePath.traverseSegments({ first: toSegment, last: fromSegment }, function (segment) { var info = segInfoMap[segment.id]; var prevSegments = segment.prevSegments; // Updates flags. info.calledInSomePaths = prevSegments.some(isCalledInSomePath); info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); // If flags become true anew, reports the valid nodes. if (info.calledInSomePaths || isRealLoop) { var nodes = info.validNodes; info.validNodes = []; for (var i = 0; i < nodes.length; ++i) { var node = nodes[i]; context.report({ messageId: "duplicate", node: node }); } } }); }, /** * Checks for a call of `super()`. * @param {ASTNode} node - A CallExpression node to check. * @returns {void} */ "CallExpression:exit": function CallExpressionExit(node) { if (!(funcInfo && funcInfo.isConstructor)) { return; } // Skips except `super()`. if (node.callee.type !== "Super") { return; } // Reports if needed. if (funcInfo.hasExtends) { var segments = funcInfo.codePath.currentSegments; var duplicate = false; var info = null; for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; if (segment.reachable) { info = segInfoMap[segment.id]; duplicate = duplicate || info.calledInSomePaths; info.calledInSomePaths = info.calledInEveryPaths = true; } } if (info) { if (duplicate) { context.report({ messageId: "duplicate", node: node }); } else if (!funcInfo.superIsConstructor) { context.report({ messageId: "badSuper", node: node }); } else { info.validNodes.push(node); } } } else if (funcInfo.codePath.currentSegments.some(isReachable)) { context.report({ messageId: "unexpected", node: node }); } }, /** * Set the mark to the returned path as `super()` was called. * @param {ASTNode} node - A ReturnStatement node to check. * @returns {void} */ ReturnStatement: function ReturnStatement(node) { if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { return; } // Skips if no argument. if (!node.argument) { return; } // Returning argument is a substitute of 'super()'. var segments = funcInfo.codePath.currentSegments; for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; if (segment.reachable) { var info = segInfoMap[segment.id]; info.calledInSomePaths = info.calledInEveryPaths = true; } } }, /** * Resets state. * @returns {void} */ "Program:exit": function ProgramExit() { segInfoMap = Object.create(null); } }; } }; },{}],148:[function(require,module,exports){ /** * @fileoverview Rule to flag statements without curly braces * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce consistent brace style for all control statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/curly" }, schema: { anyOf: [{ type: "array", items: [{ enum: ["all"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["multi", "multi-line", "multi-or-nest"] }, { enum: ["consistent"] }], minItems: 0, maxItems: 2 }] }, fixable: "code", messages: { missingCurlyAfter: "Expected { after '{{name}}'.", missingCurlyAfterCondition: "Expected { after '{{name}}' condition.", unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.", unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition." } }, create: function create(context) { var multiOnly = context.options[0] === "multi"; var multiLine = context.options[0] === "multi-line"; var multiOrNest = context.options[0] === "multi-or-nest"; var consistent = context.options[1] === "consistent"; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Determines if a given node is a one-liner that's on the same line as it's preceding code. * @param {ASTNode} node The node to check. * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code. * @private */ function isCollapsedOneLiner(node) { var before = sourceCode.getTokenBefore(node); var last = sourceCode.getLastToken(node); var lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; return before.loc.start.line === lastExcludingSemicolon.loc.end.line; } /** * Determines if a given node is a one-liner. * @param {ASTNode} node The node to check. * @returns {boolean} True if the node is a one-liner. * @private */ function isOneLiner(node) { var first = sourceCode.getFirstToken(node), last = sourceCode.getLastToken(node); return first.loc.start.line === last.loc.end.line; } /** * Checks if the given token is an `else` token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is an `else` token. */ function isElseKeywordToken(token) { return token.value === "else" && token.type === "Keyword"; } /** * Gets the `else` keyword token of a given `IfStatement` node. * @param {ASTNode} node - A `IfStatement` node to get. * @returns {Token} The `else` keyword token. */ function getElseKeyword(node) { return node.alternate && sourceCode.getFirstTokenBetween(node.consequent, node.alternate, isElseKeywordToken); } /** * Checks a given IfStatement node requires braces of the consequent chunk. * This returns `true` when below: * * 1. The given node has the `alternate` node. * 2. There is a `IfStatement` which doesn't have `alternate` node in the * trailing statement chain of the `consequent` node. * * @param {ASTNode} node - A IfStatement node to check. * @returns {boolean} `true` if the node requires braces of the consequent chunk. */ function requiresBraceOfConsequent(node) { if (node.alternate && node.consequent.type === "BlockStatement") { if (node.consequent.body.length >= 2) { return true; } for (var currentNode = node.consequent.body[0]; currentNode; currentNode = astUtils.getTrailingStatement(currentNode)) { if (currentNode.type === "IfStatement" && !currentNode.alternate) { return true; } } } return false; } /** * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError. * @param {Token} closingBracket The } token * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block. */ function needsSemicolon(closingBracket) { var tokenBefore = sourceCode.getTokenBefore(closingBracket); var tokenAfter = sourceCode.getTokenAfter(closingBracket); var lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); if (astUtils.isSemicolonToken(tokenBefore)) { // If the last statement already has a semicolon, don't add another one. return false; } if (!tokenAfter) { // If there are no statements after this block, there is no need to add a semicolon. return false; } if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") { /* * If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression), * don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause * a SyntaxError if it was followed by `else`. */ return false; } if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) { // If the next token is on the same line, insert a semicolon. return true; } if (/^[([/`+-]/.test(tokenAfter.value)) { // If the next token starts with a character that would disrupt ASI, insert a semicolon. return true; } if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) { // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI. return true; } // Otherwise, do not insert a semicolon. return false; } /** * Prepares to check the body of a node to see if it's a block statement. * @param {ASTNode} node The node to report if there's a problem. * @param {ASTNode} body The body node to check for blocks. * @param {string} name The name to report if there's a problem. * @param {{ condition: boolean }} opts Options to pass to the report functions * @returns {Object} a prepared check object, with "actual", "expected", "check" properties. * "actual" will be `true` or `false` whether the body is already a block statement. * "expected" will be `true` or `false` if the body should be a block statement or not, or * `null` if it doesn't matter, depending on the rule options. It can be modified to change * the final behavior of "check". * "check" will be a function reporting appropriate problems depending on the other * properties. */ function prepareCheck(node, body, name, opts) { var hasBlock = body.type === "BlockStatement"; var expected = null; if (node.type === "IfStatement" && node.consequent === body && requiresBraceOfConsequent(node)) { expected = true; } else if (multiOnly) { if (hasBlock && body.body.length === 1) { expected = false; } } else if (multiLine) { if (!isCollapsedOneLiner(body)) { expected = true; } } else if (multiOrNest) { if (hasBlock && body.body.length === 1 && isOneLiner(body.body[0])) { var leadingComments = sourceCode.getCommentsBefore(body.body[0]); expected = leadingComments.length > 0; } else if (!isOneLiner(body)) { expected = true; } } else { expected = true; } return { actual: hasBlock, expected: expected, check: function check() { if (this.expected !== null && this.expected !== this.actual) { if (this.expected) { context.report({ node: node, loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter", data: { name: name }, fix: function fix(fixer) { return fixer.replaceText(body, "{" + sourceCode.getText(body) + "}"); } }); } else { context.report({ node: node, loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter", data: { name: name }, fix: function fix(fixer) { /* * `do while` expressions sometimes need a space to be inserted after `do`. * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)` */ var needsPrecedingSpace = node.type === "DoWhileStatement" && sourceCode.getTokenBefore(body).range[1] === body.range[0] && !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 })); var openingBracket = sourceCode.getFirstToken(body); var closingBracket = sourceCode.getLastToken(body); var lastTokenInBlock = sourceCode.getTokenBefore(closingBracket); if (needsSemicolon(closingBracket)) { /* * If removing braces would cause a SyntaxError due to multiple statements on the same line (or * change the semantics of the code due to ASI), don't perform a fix. */ return null; } var resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) + sourceCode.getText(lastTokenInBlock) + sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]); return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText); } }); } } } }; } /** * Prepares to check the bodies of a "if", "else if" and "else" chain. * @param {ASTNode} node The first IfStatement node of the chain. * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more * information. */ function prepareIfChecks(node) { var preparedChecks = []; for (var currentNode = node; currentNode; currentNode = currentNode.alternate) { preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true })); if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") { preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else")); break; } } if (consistent) { /* * If any node should have or already have braces, make sure they * all have braces. * If all nodes shouldn't have braces, make sure they don't. */ var expected = preparedChecks.some(function (preparedCheck) { if (preparedCheck.expected !== null) { return preparedCheck.expected; } return preparedCheck.actual; }); preparedChecks.forEach(function (preparedCheck) { preparedCheck.expected = expected; }); } return preparedChecks; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { IfStatement: function IfStatement(node) { if (node.parent.type !== "IfStatement") { prepareIfChecks(node).forEach(function (preparedCheck) { preparedCheck.check(); }); } }, WhileStatement: function WhileStatement(node) { prepareCheck(node, node.body, "while", { condition: true }).check(); }, DoWhileStatement: function DoWhileStatement(node) { prepareCheck(node, node.body, "do").check(); }, ForStatement: function ForStatement(node) { prepareCheck(node, node.body, "for", { condition: true }).check(); }, ForInStatement: function ForInStatement(node) { prepareCheck(node, node.body, "for-in").check(); }, ForOfStatement: function ForOfStatement(node) { prepareCheck(node, node.body, "for-of").check(); } }; } }; },{"../util/ast-utils":405}],149:[function(require,module,exports){ /** * @fileoverview require default case in switch statements * @author Aliaksei Shytkin */ "use strict"; var DEFAULT_COMMENT_PATTERN = /^no default$/i; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `default` cases in `switch` statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/default-case" }, schema: [{ type: "object", properties: { commentPattern: { type: "string" } }, additionalProperties: false }], messages: { missingDefaultCase: "Expected a default case." } }, create: function create(context) { var options = context.options[0] || {}; var commentPattern = options.commentPattern ? new RegExp(options.commentPattern) : DEFAULT_COMMENT_PATTERN; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Shortcut to get last element of array * @param {*[]} collection Array * @returns {*} Last element */ function last(collection) { return collection[collection.length - 1]; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { SwitchStatement: function SwitchStatement(node) { if (!node.cases.length) { /* * skip check of empty switch because there is no easy way * to extract comments inside it now */ return; } var hasDefault = node.cases.some(function (v) { return v.test === null; }); if (!hasDefault) { var comment = void 0; var lastCase = last(node.cases); var comments = sourceCode.getCommentsAfter(lastCase); if (comments.length) { comment = last(comments); } if (!comment || !commentPattern.test(comment.value.trim())) { context.report({ node: node, messageId: "missingDefaultCase" }); } } } }; } }; },{}],150:[function(require,module,exports){ /** * @fileoverview Validates newlines before and after dots * @author Greg Cochard */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent newlines before and after dots", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/dot-location" }, schema: [{ enum: ["object", "property"] }], fixable: "code", messages: { expectedDotAfterObject: "Expected dot to be on same line as object.", expectedDotBeforeProperty: "Expected dot to be on same line as property." } }, create: function create(context) { var config = context.options[0]; // default to onObject if no preference is passed var onObject = config === "object" || !config; var sourceCode = context.getSourceCode(); /** * Reports if the dot between object and property is on the correct loccation. * @param {ASTNode} obj The object owning the property. * @param {ASTNode} prop The property of the object. * @param {ASTNode} node The corresponding node of the token. * @returns {void} */ function checkDotLocation(obj, prop, node) { var dot = sourceCode.getTokenBefore(prop); var textBeforeDot = sourceCode.getText().slice(obj.range[1], dot.range[0]); var textAfterDot = sourceCode.getText().slice(dot.range[1], prop.range[0]); if (dot.type === "Punctuator" && dot.value === ".") { if (onObject) { if (!astUtils.isTokenOnSameLine(obj, dot)) { var neededTextAfterObj = astUtils.isDecimalInteger(obj) ? " " : ""; context.report({ node: node, loc: dot.loc.start, messageId: "expectedDotAfterObject", fix: function fix(fixer) { return fixer.replaceTextRange([obj.range[1], prop.range[0]], neededTextAfterObj + "." + textBeforeDot + textAfterDot); } }); } } else if (!astUtils.isTokenOnSameLine(dot, prop)) { context.report({ node: node, loc: dot.loc.start, messageId: "expectedDotBeforeProperty", fix: function fix(fixer) { return fixer.replaceTextRange([obj.range[1], prop.range[0]], "" + textBeforeDot + textAfterDot + "."); } }); } } } /** * Checks the spacing of the dot within a member expression. * @param {ASTNode} node The node to check. * @returns {void} */ function checkNode(node) { checkDotLocation(node.object, node.property, node); } return { MemberExpression: checkNode }; } }; },{"../util/ast-utils":405}],151:[function(require,module,exports){ /** * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible. * @author Josh Perez */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/; var keywords = require("../util/keywords"); module.exports = { meta: { type: "suggestion", docs: { description: "enforce dot notation whenever possible", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/dot-notation" }, schema: [{ type: "object", properties: { allowKeywords: { type: "boolean" }, allowPattern: { type: "string" } }, additionalProperties: false }], fixable: "code", messages: { useDot: "[{{key}}] is better written in dot notation.", useBrackets: ".{{key}} is a syntax error." } }, create: function create(context) { var options = context.options[0] || {}; var allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords; var sourceCode = context.getSourceCode(); var allowPattern = void 0; if (options.allowPattern) { allowPattern = new RegExp(options.allowPattern); } /** * Check if the property is valid dot notation * @param {ASTNode} node The dot notation node * @param {string} value Value which is to be checked * @returns {void} */ function checkComputedProperty(node, value) { if (validIdentifier.test(value) && (allowKeywords || keywords.indexOf(String(value)) === -1) && !(allowPattern && allowPattern.test(value))) { var formattedValue = node.property.type === "Literal" ? JSON.stringify(value) : "`" + value + "`"; context.report({ node: node.property, messageId: "useDot", data: { key: formattedValue }, fix: function fix(fixer) { var leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken); var rightBracket = sourceCode.getLastToken(node); if (sourceCode.getFirstTokenBetween(leftBracket, rightBracket, { includeComments: true, filter: astUtils.isCommentToken })) { // Don't perform any fixes if there are comments inside the brackets. return null; } var tokenAfterProperty = sourceCode.getTokenAfter(rightBracket); var needsSpaceAfterProperty = tokenAfterProperty && rightBracket.range[1] === tokenAfterProperty.range[0] && !astUtils.canTokensBeAdjacent(String(value), tokenAfterProperty); var textBeforeDot = astUtils.isDecimalInteger(node.object) ? " " : ""; var textAfterProperty = needsSpaceAfterProperty ? " " : ""; return fixer.replaceTextRange([leftBracket.range[0], rightBracket.range[1]], textBeforeDot + "." + value + textAfterProperty); } }); } } return { MemberExpression: function MemberExpression(node) { if (node.computed && node.property.type === "Literal") { checkComputedProperty(node, node.property.value); } if (node.computed && node.property.type === "TemplateLiteral" && node.property.expressions.length === 0) { checkComputedProperty(node, node.property.quasis[0].value.cooked); } if (!allowKeywords && !node.computed && keywords.indexOf(String(node.property.name)) !== -1) { context.report({ node: node.property, messageId: "useBrackets", data: { key: node.property.name }, fix: function fix(fixer) { var dot = sourceCode.getTokenBefore(node.property); var textAfterDot = sourceCode.text.slice(dot.range[1], node.property.range[0]); if (textAfterDot.trim()) { // Don't perform any fixes if there are comments between the dot and the property name. return null; } if (node.object.type === "Identifier" && node.object.name === "let") { /* * A statement that starts with `let[` is parsed as a destructuring variable declaration, not * a MemberExpression. */ return null; } return fixer.replaceTextRange([dot.range[0], node.property.range[1]], "[" + textAfterDot + "\"" + node.property.name + "\"]"); } }); } } }; } }; },{"../util/ast-utils":405,"../util/keywords":409}],152:[function(require,module,exports){ /** * @fileoverview Require or disallow newline at the end of files * @author Nodeca Team */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow newline at the end of files", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/eol-last" }, fixable: "whitespace", schema: [{ enum: ["always", "never", "unix", "windows"] }], messages: { missing: "Newline required at end of file but not found.", unexpected: "Newline not allowed at end of file." } }, create: function create(context) { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function checkBadEOF(node) { var sourceCode = context.getSourceCode(), src = sourceCode.getText(), location = { column: lodash.last(sourceCode.lines).length, line: sourceCode.lines.length }, LF = "\n", CRLF = "\r" + LF, endsWithNewline = lodash.endsWith(src, LF); /* * Empty source is always valid: No content in file so we don't * need to lint for a newline on the last line of content. */ if (!src.length) { return; } var mode = context.options[0] || "always", appendCRLF = false; if (mode === "unix") { // `"unix"` should behave exactly as `"always"` mode = "always"; } if (mode === "windows") { // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility mode = "always"; appendCRLF = true; } if (mode === "always" && !endsWithNewline) { // File is not newline-terminated, but should be context.report({ node: node, loc: location, messageId: "missing", fix: function fix(fixer) { return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF); } }); } else if (mode === "never" && endsWithNewline) { // File is newline-terminated, but shouldn't be context.report({ node: node, loc: location, messageId: "unexpected", fix: function fix(fixer) { var finalEOLs = /(?:\r?\n)+$/, match = finalEOLs.exec(sourceCode.text), start = match.index, end = sourceCode.text.length; return fixer.replaceTextRange([start, end], ""); } }); } } }; } }; },{"lodash":92}],153:[function(require,module,exports){ /** * @fileoverview Rule to flag statements that use != and == instead of !== and === * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require the use of `===` and `!==`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/eqeqeq" }, schema: { anyOf: [{ type: "array", items: [{ enum: ["always"] }, { type: "object", properties: { null: { enum: ["always", "never", "ignore"] } }, additionalProperties: false }], additionalItems: false }, { type: "array", items: [{ enum: ["smart", "allow-null"] }], additionalItems: false }] }, fixable: "code", messages: { unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'." } }, create: function create(context) { var config = context.options[0] || "always"; var options = context.options[1] || {}; var sourceCode = context.getSourceCode(); var nullOption = config === "always" ? options.null || "always" : "ignore"; var enforceRuleForNull = nullOption === "always"; var enforceInverseRuleForNull = nullOption === "never"; /** * Checks if an expression is a typeof expression * @param {ASTNode} node The node to check * @returns {boolean} if the node is a typeof expression */ function isTypeOf(node) { return node.type === "UnaryExpression" && node.operator === "typeof"; } /** * Checks if either operand of a binary expression is a typeof operation * @param {ASTNode} node The node to check * @returns {boolean} if one of the operands is typeof * @private */ function isTypeOfBinary(node) { return isTypeOf(node.left) || isTypeOf(node.right); } /** * Checks if operands are literals of the same type (via typeof) * @param {ASTNode} node The node to check * @returns {boolean} if operands are of same type * @private */ function areLiteralsAndSameType(node) { return node.left.type === "Literal" && node.right.type === "Literal" && _typeof(node.left.value) === _typeof(node.right.value); } /** * Checks if one of the operands is a literal null * @param {ASTNode} node The node to check * @returns {boolean} if operands are null * @private */ function isNullCheck(node) { return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left); } /** * Gets the location (line and column) of the binary expression's operator * @param {ASTNode} node The binary expression node to check * @returns {Object} { line, column } location of operator * @private */ function getOperatorLocation(node) { var opToken = sourceCode.getTokenAfter(node.left); return { line: opToken.loc.start.line, column: opToken.loc.start.column }; } /** * Reports a message for this rule. * @param {ASTNode} node The binary expression node that was checked * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==') * @returns {void} * @private */ function report(node, expectedOperator) { context.report({ node: node, loc: getOperatorLocation(node), messageId: "unexpected", data: { expectedOperator: expectedOperator, actualOperator: node.operator }, fix: function fix(fixer) { // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix. if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) { var operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, function (token) { return token.value === node.operator; }); return fixer.replaceText(operatorToken, expectedOperator); } return null; } }); } return { BinaryExpression: function BinaryExpression(node) { var isNull = isNullCheck(node); if (node.operator !== "==" && node.operator !== "!=") { if (enforceInverseRuleForNull && isNull) { report(node, node.operator.slice(0, -1)); } return; } if (config === "smart" && (isTypeOfBinary(node) || areLiteralsAndSameType(node) || isNull)) { return; } if (!enforceRuleForNull && isNull) { return; } report(node, node.operator + "="); } }; } }; },{"../util/ast-utils":405}],154:[function(require,module,exports){ /** * @fileoverview enforce "for" loop update clause moving the counter in the right direction.(for-direction) * @author Aladdin-ADD */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "enforce \"for\" loop update clause moving the counter in the right direction.", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/for-direction" }, fixable: null, schema: [], messages: { incorrectDirection: "The update clause in this loop moves the variable in the wrong direction." } }, create: function create(context) { /** * report an error. * @param {ASTNode} node the node to report. * @returns {void} */ function report(node) { context.report({ node: node, messageId: "incorrectDirection" }); } /** * check UpdateExpression add/sub the counter * @param {ASTNode} update UpdateExpression to check * @param {string} counter variable name to check * @returns {int} if add return 1, if sub return -1, if nochange, return 0 */ function getUpdateDirection(update, counter) { if (update.argument.type === "Identifier" && update.argument.name === counter) { if (update.operator === "++") { return 1; } if (update.operator === "--") { return -1; } } return 0; } /** * check AssignmentExpression add/sub the counter * @param {ASTNode} update AssignmentExpression to check * @param {string} counter variable name to check * @returns {int} if add return 1, if sub return -1, if nochange, return 0 */ function getAssignmentDirection(update, counter) { if (update.left.name === counter) { if (update.operator === "+=") { return 1; } if (update.operator === "-=") { return -1; } } return 0; } return { ForStatement: function ForStatement(node) { if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) { var counter = node.test.left.name; var operator = node.test.operator; var update = node.update; if (operator === "<" || operator === "<=") { // report error if update sub the counter (--, -=) if (update.type === "UpdateExpression" && getUpdateDirection(update, counter) < 0) { report(node); } if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) < 0) { report(node); } } else if (operator === ">" || operator === ">=") { // report error if update add the counter (++, +=) if (update.type === "UpdateExpression" && getUpdateDirection(update, counter) > 0) { report(node); } if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) > 0) { report(node); } } } } }; } }; },{}],155:[function(require,module,exports){ /** * @fileoverview Rule to control spacing within function calls * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow spacing between function identifiers and their invocations", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/func-call-spacing" }, fixable: "whitespace", schema: { anyOf: [{ type: "array", items: [{ enum: ["never"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["always"] }, { type: "object", properties: { allowNewlines: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] }, messages: { unexpected: "Unexpected newline between function name and paren.", missing: "Missing space between function name and paren." } }, create: function create(context) { var never = context.options[0] !== "always"; var allowNewlines = !never && context.options[1] && context.options[1].allowNewlines; var sourceCode = context.getSourceCode(); var text = sourceCode.getText(); /** * Check if open space is present in a function name * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkSpacing(node) { var lastToken = sourceCode.getLastToken(node); var lastCalleeToken = sourceCode.getLastToken(node.callee); var parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken); var prevToken = parenToken && sourceCode.getTokenBefore(parenToken); // Parens in NewExpression are optional if (!(parenToken && parenToken.range[1] < node.range[1])) { return; } var textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//g, ""); var hasWhitespace = /\s/.test(textBetweenTokens); var hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens); /* * never allowNewlines hasWhitespace hasNewline message * F F F F Missing space between function name and paren. * F F F T (Invalid `!hasWhitespace && hasNewline`) * F F T T Unexpected newline between function name and paren. * F F T F (OK) * F T T F (OK) * F T T T (OK) * F T F T (Invalid `!hasWhitespace && hasNewline`) * F T F F Missing space between function name and paren. * T T F F (Invalid `never && allowNewlines`) * T T F T (Invalid `!hasWhitespace && hasNewline`) * T T T T (Invalid `never && allowNewlines`) * T T T F (Invalid `never && allowNewlines`) * T F T F Unexpected space between function name and paren. * T F T T Unexpected space between function name and paren. * T F F T (Invalid `!hasWhitespace && hasNewline`) * T F F F (OK) * * T T Unexpected space between function name and paren. * F F Missing space between function name and paren. * F F T Unexpected newline between function name and paren. */ if (never && hasWhitespace) { context.report({ node: node, loc: lastCalleeToken.loc.start, messageId: "unexpected", fix: function fix(fixer) { /* * Only autofix if there is no newline * https://github.com/eslint/eslint/issues/7787 */ if (!hasNewline) { return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); } return null; } }); } else if (!never && !hasWhitespace) { context.report({ node: node, loc: lastCalleeToken.loc.start, messageId: "missing", fix: function fix(fixer) { return fixer.insertTextBefore(parenToken, " "); } }); } else if (!never && !allowNewlines && hasNewline) { context.report({ node: node, loc: lastCalleeToken.loc.start, messageId: "unexpected", fix: function fix(fixer) { return fixer.replaceTextRange([prevToken.range[1], parenToken.range[0]], " "); } }); } } return { CallExpression: checkSpacing, NewExpression: checkSpacing }; } }; },{"../util/ast-utils":405}],156:[function(require,module,exports){ /** * @fileoverview Rule to require function names to match the name of the variable or property to which they are assigned. * @author Annie Zhang, Pavel Strashkin */ "use strict"; //-------------------------------------------------------------------------- // Requirements //-------------------------------------------------------------------------- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); var esutils = require("esutils"); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Determines if a pattern is `module.exports` or `module["exports"]` * @param {ASTNode} pattern The left side of the AssignmentExpression * @returns {boolean} True if the pattern is `module.exports` or `module["exports"]` */ function isModuleExports(pattern) { if (pattern.type === "MemberExpression" && pattern.object.type === "Identifier" && pattern.object.name === "module") { // module.exports if (pattern.property.type === "Identifier" && pattern.property.name === "exports") { return true; } // module["exports"] if (pattern.property.type === "Literal" && pattern.property.value === "exports") { return true; } } return false; } /** * Determines if a string name is a valid identifier * @param {string} name The string to be checked * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config * @returns {boolean} True if the string is a valid identifier */ function isIdentifier(name, ecmaVersion) { if (ecmaVersion >= 6) { return esutils.keyword.isIdentifierES6(name); } return esutils.keyword.isIdentifierES5(name); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var alwaysOrNever = { enum: ["always", "never"] }; var optionsObject = { type: "object", properties: { considerPropertyDescriptor: { type: "boolean" }, includeCommonJSModuleExports: { type: "boolean" } }, additionalProperties: false }; module.exports = { meta: { type: "suggestion", docs: { description: "require function names to match the name of the variable or property to which they are assigned", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/func-name-matching" }, schema: { anyOf: [{ type: "array", additionalItems: false, items: [alwaysOrNever, optionsObject] }, { type: "array", additionalItems: false, items: [optionsObject] }] }, messages: { matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`", matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`", notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`", notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`" } }, create: function create(context) { var options = (_typeof(context.options[0]) === "object" ? context.options[0] : context.options[1]) || {}; var nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always"; var considerPropertyDescriptor = options.considerPropertyDescriptor; var includeModuleExports = options.includeCommonJSModuleExports; var ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5; /** * Check whether node is a certain CallExpression. * @param {string} objName object name * @param {string} funcName function name * @param {ASTNode} node The node to check * @returns {boolean} `true` if node matches CallExpression */ function isPropertyCall(objName, funcName, node) { if (!node) { return false; } return node.type === "CallExpression" && node.callee.object.name === objName && node.callee.property.name === funcName; } /** * Compares identifiers based on the nameMatches option * @param {string} x the first identifier * @param {string} y the second identifier * @returns {boolean} whether the two identifiers should warn. */ function shouldWarn(x, y) { return nameMatches === "always" && x !== y || nameMatches === "never" && x === y; } /** * Reports * @param {ASTNode} node The node to report * @param {string} name The variable or property name * @param {string} funcName The function name * @param {boolean} isProp True if the reported node is a property assignment * @returns {void} */ function report(node, name, funcName, isProp) { var messageId = void 0; if (nameMatches === "always" && isProp) { messageId = "matchProperty"; } else if (nameMatches === "always") { messageId = "matchVariable"; } else if (isProp) { messageId = "notMatchProperty"; } else { messageId = "notMatchVariable"; } context.report({ node: node, messageId: messageId, data: { name: name, funcName: funcName } }); } /** * Determines whether a given node is a string literal * @param {ASTNode} node The node to check * @returns {boolean} `true` if the node is a string literal */ function isStringLiteral(node) { return node.type === "Literal" && typeof node.value === "string"; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { VariableDeclarator: function VariableDeclarator(node) { if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") { return; } if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) { report(node, node.id.name, node.init.id.name, false); } }, AssignmentExpression: function AssignmentExpression(node) { if (node.right.type !== "FunctionExpression" || node.left.computed && node.left.property.type !== "Literal" || !includeModuleExports && isModuleExports(node.left) || node.left.type !== "Identifier" && node.left.type !== "MemberExpression") { return; } var isProp = node.left.type === "MemberExpression"; var name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name; if (node.right.id && isIdentifier(name) && shouldWarn(name, node.right.id.name)) { report(node, name, node.right.id.name, isProp); } }, Property: function Property(node) { if (node.value.type !== "FunctionExpression" || !node.value.id || node.computed && !isStringLiteral(node.key)) { return; } if (node.key.type === "Identifier") { var functionName = node.value.id.name; var propertyName = node.key.name; if (considerPropertyDescriptor && propertyName === "value") { if (isPropertyCall("Object", "defineProperty", node.parent.parent) || isPropertyCall("Reflect", "defineProperty", node.parent.parent)) { var property = node.parent.parent.arguments[1]; if (isStringLiteral(property) && shouldWarn(property.value, functionName)) { report(node, property.value, functionName, true); } } else if (isPropertyCall("Object", "defineProperties", node.parent.parent.parent.parent)) { propertyName = node.parent.parent.key.name; if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { report(node, propertyName, functionName, true); } } else if (isPropertyCall("Object", "create", node.parent.parent.parent.parent)) { propertyName = node.parent.parent.key.name; if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { report(node, propertyName, functionName, true); } } else if (shouldWarn(propertyName, functionName)) { report(node, propertyName, functionName, true); } } else if (shouldWarn(propertyName, functionName)) { report(node, propertyName, functionName, true); } return; } if (isStringLiteral(node.key) && isIdentifier(node.key.value, ecmaVersion) && shouldWarn(node.key.value, node.value.id.name)) { report(node, node.key.value, node.value.id.name, true); } } }; } }; },{"../util/ast-utils":405,"esutils":80}],157:[function(require,module,exports){ /** * @fileoverview Rule to warn when a function expression does not have a name. * @author Kyle T. Nunery */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); /** * Checks whether or not a given variable is a function name. * @param {eslint-scope.Variable} variable - A variable to check. * @returns {boolean} `true` if the variable is a function name. */ function isFunctionName(variable) { return variable && variable.defs[0].type === "FunctionName"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow named `function` expressions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/func-names" }, schema: { definitions: { value: { enum: ["always", "as-needed", "never"] } }, items: [{ $ref: "#/definitions/value" }, { type: "object", properties: { generators: { $ref: "#/definitions/value" } }, additionalProperties: false }] }, messages: { unnamed: "Unexpected unnamed {{name}}.", named: "Unexpected named {{name}}." } }, create: function create(context) { /** * Returns the config option for the given node. * @param {ASTNode} node - A node to get the config for. * @returns {string} The config option. */ function getConfigForNode(node) { if (node.generator && context.options.length > 1 && context.options[1].generators) { return context.options[1].generators; } return context.options[0] || "always"; } /** * Determines whether the current FunctionExpression node is a get, set, or * shorthand method in an object literal or a class. * @param {ASTNode} node - A node to check. * @returns {boolean} True if the node is a get, set, or shorthand method. */ function isObjectOrClassMethod(node) { var parent = node.parent; return parent.type === "MethodDefinition" || parent.type === "Property" && (parent.method || parent.kind === "get" || parent.kind === "set"); } /** * Determines whether the current FunctionExpression node has a name that would be * inferred from context in a conforming ES6 environment. * @param {ASTNode} node - A node to check. * @returns {boolean} True if the node would have a name assigned automatically. */ function hasInferredName(node) { var parent = node.parent; return isObjectOrClassMethod(node) || parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node || parent.type === "Property" && parent.value === node || parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node || parent.type === "ExportDefaultDeclaration" && parent.declaration === node || parent.type === "AssignmentPattern" && parent.right === node; } /** * Reports that an unnamed function should be named * @param {ASTNode} node - The node to report in the event of an error. * @returns {void} */ function reportUnexpectedUnnamedFunction(node) { context.report({ node: node, messageId: "unnamed", data: { name: astUtils.getFunctionNameWithKind(node) } }); } /** * Reports that a named function should be unnamed * @param {ASTNode} node - The node to report in the event of an error. * @returns {void} */ function reportUnexpectedNamedFunction(node) { context.report({ node: node, messageId: "named", data: { name: astUtils.getFunctionNameWithKind(node) } }); } return { "FunctionExpression:exit": function FunctionExpressionExit(node) { // Skip recursive functions. var nameVar = context.getDeclaredVariables(node)[0]; if (isFunctionName(nameVar) && nameVar.references.length > 0) { return; } var hasName = Boolean(node.id && node.id.name); var config = getConfigForNode(node); if (config === "never") { if (hasName) { reportUnexpectedNamedFunction(node); } } else if (config === "as-needed") { if (!hasName && !hasInferredName(node)) { reportUnexpectedUnnamedFunction(node); } } else { if (!hasName && !isObjectOrClassMethod(node)) { reportUnexpectedUnnamedFunction(node); } } } }; } }; },{"../util/ast-utils":405}],158:[function(require,module,exports){ /** * @fileoverview Rule to enforce a particular function style * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce the consistent use of either `function` declarations or expressions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/func-style" }, schema: [{ enum: ["declaration", "expression"] }, { type: "object", properties: { allowArrowFunctions: { type: "boolean" } }, additionalProperties: false }], messages: { expression: "Expected a function expression.", declaration: "Expected a function declaration." } }, create: function create(context) { var style = context.options[0], allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true, enforceDeclarations = style === "declaration", stack = []; var nodesToCheck = { FunctionDeclaration: function FunctionDeclaration(node) { stack.push(false); if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { context.report({ node: node, messageId: "expression" }); } }, "FunctionDeclaration:exit": function FunctionDeclarationExit() { stack.pop(); }, FunctionExpression: function FunctionExpression(node) { stack.push(false); if (enforceDeclarations && node.parent.type === "VariableDeclarator") { context.report({ node: node.parent, messageId: "declaration" }); } }, "FunctionExpression:exit": function FunctionExpressionExit() { stack.pop(); }, ThisExpression: function ThisExpression() { if (stack.length > 0) { stack[stack.length - 1] = true; } } }; if (!allowArrowFunctions) { nodesToCheck.ArrowFunctionExpression = function () { stack.push(false); }; nodesToCheck["ArrowFunctionExpression:exit"] = function (node) { var hasThisExpr = stack.pop(); if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { context.report({ node: node.parent, messageId: "declaration" }); } }; } return nodesToCheck; } }; },{}],159:[function(require,module,exports){ /** * @fileoverview enforce consistent line breaks inside function parentheses * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent line breaks inside function parentheses", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/function-paren-newline" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["always", "never", "consistent", "multiline"] }, { type: "object", properties: { minItems: { type: "integer", minimum: 0 } }, additionalProperties: false }] }], messages: { expectedBefore: "Expected newline before ')'.", expectedAfter: "Expected newline after '('.", unexpectedBefore: "Unexpected newline before '('.", unexpectedAfter: "Unexpected newline after ')'." } }, create: function create(context) { var sourceCode = context.getSourceCode(); var rawOption = context.options[0] || "multiline"; var multilineOption = rawOption === "multiline"; var consistentOption = rawOption === "consistent"; var minItems = void 0; if ((typeof rawOption === "undefined" ? "undefined" : _typeof(rawOption)) === "object") { minItems = rawOption.minItems; } else if (rawOption === "always") { minItems = 0; } else if (rawOption === "never") { minItems = Infinity; } else { minItems = null; } //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Determines whether there should be newlines inside function parens * @param {ASTNode[]} elements The arguments or parameters in the list * @param {boolean} hasLeftNewline `true` if the left paren has a newline in the current code. * @returns {boolean} `true` if there should be newlines inside the function parens */ function shouldHaveNewlines(elements, hasLeftNewline) { if (multilineOption) { return elements.some(function (element, index) { return index !== elements.length - 1 && element.loc.end.line !== elements[index + 1].loc.start.line; }); } if (consistentOption) { return hasLeftNewline; } return elements.length >= minItems; } /** * Validates a list of arguments or parameters * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token * @param {ASTNode[]} elements The arguments or parameters in the list * @returns {void} */ function validateParens(parens, elements) { var leftParen = parens.leftParen; var rightParen = parens.rightParen; var tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); var tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen); var hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); var hasRightNewline = !astUtils.isTokenOnSameLine(tokenBeforeRightParen, rightParen); var needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); if (hasLeftNewline && !needsNewlines) { context.report({ node: leftParen, messageId: "unexpectedAfter", fix: function fix(fixer) { return sourceCode.getText().slice(leftParen.range[1], tokenAfterLeftParen.range[0]).trim() // If there is a comment between the ( and the first element, don't do a fix. ? null : fixer.removeRange([leftParen.range[1], tokenAfterLeftParen.range[0]]); } }); } else if (!hasLeftNewline && needsNewlines) { context.report({ node: leftParen, messageId: "expectedAfter", fix: function fix(fixer) { return fixer.insertTextAfter(leftParen, "\n"); } }); } if (hasRightNewline && !needsNewlines) { context.report({ node: rightParen, messageId: "unexpectedBefore", fix: function fix(fixer) { return sourceCode.getText().slice(tokenBeforeRightParen.range[1], rightParen.range[0]).trim() // If there is a comment between the last element and the ), don't do a fix. ? null : fixer.removeRange([tokenBeforeRightParen.range[1], rightParen.range[0]]); } }); } else if (!hasRightNewline && needsNewlines) { context.report({ node: rightParen, messageId: "expectedBefore", fix: function fix(fixer) { return fixer.insertTextBefore(rightParen, "\n"); } }); } } /** * Gets the left paren and right paren tokens of a node. * @param {ASTNode} node The node with parens * @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token. * Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression * with a single parameter) */ function getParenTokens(node) { switch (node.type) { case "NewExpression": if (!node.arguments.length && !(astUtils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) && astUtils.isClosingParenToken(sourceCode.getLastToken(node)))) { // If the NewExpression does not have parens (e.g. `new Foo`), return null. return null; } // falls through case "CallExpression": return { leftParen: sourceCode.getTokenAfter(node.callee, astUtils.isOpeningParenToken), rightParen: sourceCode.getLastToken(node) }; case "FunctionDeclaration": case "FunctionExpression": { var leftParen = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); var rightParen = node.params.length ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken) : sourceCode.getTokenAfter(leftParen); return { leftParen: leftParen, rightParen: rightParen }; } case "ArrowFunctionExpression": { var firstToken = sourceCode.getFirstToken(node); if (!astUtils.isOpeningParenToken(firstToken)) { // If the ArrowFunctionExpression has a single param without parens, return null. return null; } return { leftParen: firstToken, rightParen: sourceCode.getTokenBefore(node.body, astUtils.isClosingParenToken) }; } default: throw new TypeError("unexpected node with type " + node.type); } } /** * Validates the parentheses for a node * @param {ASTNode} node The node with parens * @returns {void} */ function validateNode(node) { var parens = getParenTokens(node); if (parens) { validateParens(parens, astUtils.isFunction(node) ? node.params : node.arguments); } } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { ArrowFunctionExpression: validateNode, CallExpression: validateNode, FunctionDeclaration: validateNode, FunctionExpression: validateNode, NewExpression: validateNode }; } }; },{"../util/ast-utils":405}],160:[function(require,module,exports){ /** * @fileoverview Rule to check the spacing around the * in generator functions. * @author Jamund Ferguson */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var OVERRIDE_SCHEMA = { oneOf: [{ enum: ["before", "after", "both", "neither"] }, { type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }] }; module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing around `*` operators in generator functions", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/generator-star-spacing" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["before", "after", "both", "neither"] }, { type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" }, named: OVERRIDE_SCHEMA, anonymous: OVERRIDE_SCHEMA, method: OVERRIDE_SCHEMA }, additionalProperties: false }] }], messages: { missingBefore: "Missing space before *.", missingAfter: "Missing space after *.", unexpectedBefore: "Unexpected space before *.", unexpectedAfter: "Unexpected space after *." } }, create: function create(context) { var optionDefinitions = { before: { before: true, after: false }, after: { before: false, after: true }, both: { before: true, after: true }, neither: { before: false, after: false } }; /** * Returns resolved option definitions based on an option and defaults * * @param {any} option - The option object or string value * @param {Object} defaults - The defaults to use if options are not present * @returns {Object} the resolved object definition */ function optionToDefinition(option, defaults) { if (!option) { return defaults; } return typeof option === "string" ? optionDefinitions[option] : Object.assign({}, defaults, option); } var modes = function (option) { var defaults = optionToDefinition(option, optionDefinitions.before); return { named: optionToDefinition(option.named, defaults), anonymous: optionToDefinition(option.anonymous, defaults), method: optionToDefinition(option.method, defaults) }; }(context.options[0] || {}); var sourceCode = context.getSourceCode(); /** * Checks if the given token is a star token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a star token. */ function isStarToken(token) { return token.value === "*" && token.type === "Punctuator"; } /** * Gets the generator star token of the given function node. * * @param {ASTNode} node - The function node to get. * @returns {Token} Found star token. */ function getStarToken(node) { return sourceCode.getFirstToken(node.parent.method || node.parent.type === "MethodDefinition" ? node.parent : node, isStarToken); } /** * capitalize a given string. * @param {string} str the given string. * @returns {string} the capitalized string. */ function capitalize(str) { return str[0].toUpperCase() + str.slice(1); } /** * Checks the spacing between two tokens before or after the star token. * * @param {string} kind Either "named", "anonymous", or "method" * @param {string} side Either "before" or "after". * @param {Token} leftToken `function` keyword token if side is "before", or * star token if side is "after". * @param {Token} rightToken Star token if side is "before", or identifier * token if side is "after". * @returns {void} */ function checkSpacing(kind, side, leftToken, rightToken) { if (!!(rightToken.range[0] - leftToken.range[1]) !== modes[kind][side]) { var after = leftToken.value === "*"; var spaceRequired = modes[kind][side]; var node = after ? leftToken : rightToken; var messageId = "" + (spaceRequired ? "missing" : "unexpected") + capitalize(side); context.report({ node: node, messageId: messageId, fix: function fix(fixer) { if (spaceRequired) { if (after) { return fixer.insertTextAfter(node, " "); } return fixer.insertTextBefore(node, " "); } return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); } }); } } /** * Enforces the spacing around the star if node is a generator function. * * @param {ASTNode} node A function expression or declaration node. * @returns {void} */ function checkFunction(node) { if (!node.generator) { return; } var starToken = getStarToken(node); var prevToken = sourceCode.getTokenBefore(starToken); var nextToken = sourceCode.getTokenAfter(starToken); var kind = "named"; if (node.parent.type === "MethodDefinition" || node.parent.type === "Property" && node.parent.method) { kind = "method"; } else if (!node.id) { kind = "anonymous"; } // Only check before when preceded by `function`|`static` keyword if (!(kind === "method" && starToken === sourceCode.getFirstToken(node.parent))) { checkSpacing(kind, "before", prevToken, starToken); } checkSpacing(kind, "after", starToken, nextToken); } return { FunctionDeclaration: checkFunction, FunctionExpression: checkFunction }; } }; },{}],161:[function(require,module,exports){ /** * @fileoverview Enforces that a return statement is present in property getters. * @author Aladdin-ADD(hh_2013@foxmail.com) */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/; /** * Checks a given code path segment is reachable. * * @param {CodePathSegment} segment - A segment to check. * @returns {boolean} `true` if the segment is reachable. */ function isReachable(segment) { return segment.reachable; } /** * Gets a readable location. * * - FunctionExpression -> the function name or `function` keyword. * * @param {ASTNode} node - A function node to get. * @returns {ASTNode|Token} The node or the token of a location. */ function getId(node) { return node.id || node; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "enforce `return` statements in getters", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/getter-return" }, fixable: null, schema: [{ type: "object", properties: { allowImplicit: { type: "boolean" } }, additionalProperties: false }], messages: { expected: "Expected to return a value in {{name}}.", expectedAlways: "Expected {{name}} to always return a value." } }, create: function create(context) { var options = context.options[0] || { allowImplicit: false }; var funcInfo = { upper: null, codePath: null, hasReturn: false, shouldCheck: false, node: null }; /** * Checks whether or not the last code path segment is reachable. * Then reports this function if the segment is reachable. * * If the last code path segment is reachable, there are paths which are not * returned or thrown. * * @param {ASTNode} node - A node to check. * @returns {void} */ function checkLastSegment(node) { if (funcInfo.shouldCheck && funcInfo.codePath.currentSegments.some(isReachable)) { context.report({ node: node, loc: getId(node).loc.start, messageId: funcInfo.hasReturn ? "expectedAlways" : "expected", data: { name: astUtils.getFunctionNameWithKind(funcInfo.node) } }); } } /** * Checks whether a node means a getter function. * @param {ASTNode} node - a node to check. * @returns {boolean} if node means a getter, return true; else return false. */ function isGetter(node) { var parent = node.parent; if (TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement") { if (parent.kind === "get") { return true; } if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") { // Object.defineProperty() if (parent.parent.parent.type === "CallExpression" && astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") { return true; } // Object.defineProperties() if (parent.parent.parent.type === "Property" && parent.parent.parent.parent.type === "ObjectExpression" && parent.parent.parent.parent.parent.type === "CallExpression" && astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") { return true; } } } return false; } return { // Stacks this function's information. onCodePathStart: function onCodePathStart(codePath, node) { funcInfo = { upper: funcInfo, codePath: codePath, hasReturn: false, shouldCheck: isGetter(node), node: node }; }, // Pops this function's information. onCodePathEnd: function onCodePathEnd() { funcInfo = funcInfo.upper; }, // Checks the return statement is valid. ReturnStatement: function ReturnStatement(node) { if (funcInfo.shouldCheck) { funcInfo.hasReturn = true; // if allowImplicit: false, should also check node.argument if (!options.allowImplicit && !node.argument) { context.report({ node: node, messageId: "expected", data: { name: astUtils.getFunctionNameWithKind(funcInfo.node) } }); } } }, // Reports a given function if the last path is reachable. "FunctionExpression:exit": checkLastSegment, "ArrowFunctionExpression:exit": checkLastSegment }; } }; },{"../util/ast-utils":405}],162:[function(require,module,exports){ /** * @fileoverview Rule for disallowing require() outside of the top-level module context * @author Jamund Ferguson */ "use strict"; var ACCEPTABLE_PARENTS = ["AssignmentExpression", "VariableDeclarator", "MemberExpression", "ExpressionStatement", "CallExpression", "ConditionalExpression", "Program", "VariableDeclaration"]; /** * Finds the eslint-scope reference in the given scope. * @param {Object} scope The scope to search. * @param {ASTNode} node The identifier node. * @returns {Reference|null} Returns the found reference or null if none were found. */ function findReference(scope, node) { var references = scope.references.filter(function (reference) { return reference.identifier.range[0] === node.range[0] && reference.identifier.range[1] === node.range[1]; }); /* istanbul ignore else: correctly returns null */ if (references.length === 1) { return references[0]; } return null; } /** * Checks if the given identifier node is shadowed in the given scope. * @param {Object} scope The current scope. * @param {ASTNode} node The identifier node to check. * @returns {boolean} Whether or not the name is shadowed. */ function isShadowed(scope, node) { var reference = findReference(scope, node); return reference && reference.resolved && reference.resolved.defs.length > 0; } module.exports = { meta: { type: "suggestion", docs: { description: "require `require()` calls to be placed at top-level module scope", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/global-require" }, schema: [] }, create: function create(context) { return { CallExpression: function CallExpression(node) { var currentScope = context.getScope(); if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) { var isGoodRequire = context.getAncestors().every(function (parent) { return ACCEPTABLE_PARENTS.indexOf(parent.type) > -1; }); if (!isGoodRequire) { context.report({ node: node, message: "Unexpected require()." }); } } } }; } }; },{}],163:[function(require,module,exports){ /** * @fileoverview Rule to flag for-in loops without if statements inside * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `for-in` loops to include an `if` statement", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/guard-for-in" }, schema: [] }, create: function create(context) { return { ForInStatement: function ForInStatement(node) { var body = node.body; // empty statement if (body.type === "EmptyStatement") { return; } // if statement if (body.type === "IfStatement") { return; } // empty block if (body.type === "BlockStatement" && body.body.length === 0) { return; } // block with just if statement if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") { return; } // block that starts with if statement if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") { var i = body.body[0]; // ... whose consequent is a continue if (i.consequent.type === "ContinueStatement") { return; } // ... whose consequent is a block that contains only a continue if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") { return; } } context.report({ node: node, message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." }); } }; } }; },{}],164:[function(require,module,exports){ /** * @fileoverview Ensure handling of errors when we know they exist. * @author Jamund Ferguson */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require error handling in callbacks", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/handle-callback-err" }, schema: [{ type: "string" }] }, create: function create(context) { var errorArgument = context.options[0] || "err"; /** * Checks if the given argument should be interpreted as a regexp pattern. * @param {string} stringToCheck The string which should be checked. * @returns {boolean} Whether or not the string should be interpreted as a pattern. */ function isPattern(stringToCheck) { var firstChar = stringToCheck[0]; return firstChar === "^"; } /** * Checks if the given name matches the configured error argument. * @param {string} name The name which should be compared. * @returns {boolean} Whether or not the given name matches the configured error variable name. */ function matchesConfiguredErrorName(name) { if (isPattern(errorArgument)) { var regexp = new RegExp(errorArgument); return regexp.test(name); } return name === errorArgument; } /** * Get the parameters of a given function scope. * @param {Object} scope The function scope. * @returns {Array} All parameters of the given scope. */ function getParameters(scope) { return scope.variables.filter(function (variable) { return variable.defs[0] && variable.defs[0].type === "Parameter"; }); } /** * Check to see if we're handling the error object properly. * @param {ASTNode} node The AST node to check. * @returns {void} */ function checkForError(node) { var scope = context.getScope(), parameters = getParameters(scope), firstParameter = parameters[0]; if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) { if (firstParameter.references.length === 0) { context.report({ node: node, message: "Expected error to be handled." }); } } } return { FunctionDeclaration: checkForError, FunctionExpression: checkForError, ArrowFunctionExpression: checkForError }; } }; },{}],165:[function(require,module,exports){ /** * @fileoverview Rule that warns when identifier names that are * blacklisted in the configuration are used. * @author Keith Cirkel (http://keithcirkel.co.uk) */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow specified identifiers", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/id-blacklist" }, schema: { type: "array", items: { type: "string" }, uniqueItems: true } }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var blacklist = context.options; /** * Checks if a string matches the provided pattern * @param {string} name The string to check. * @returns {boolean} if the string is a match * @private */ function isInvalid(name) { return blacklist.indexOf(name) !== -1; } /** * Verifies if we should report an error or not based on the effective * parent node and the identifier name. * @param {ASTNode} effectiveParent The effective parent node of the node to be reported * @param {string} name The identifier name of the identifier node * @returns {boolean} whether an error should be reported or not */ function shouldReport(effectiveParent, name) { return effectiveParent.type !== "CallExpression" && effectiveParent.type !== "NewExpression" && isInvalid(name); } /** * Reports an AST node as a rule violation. * @param {ASTNode} node The node to report. * @returns {void} * @private */ function report(node) { context.report({ node: node, message: "Identifier '{{name}}' is blacklisted.", data: { name: node.name } }); } return { Identifier: function Identifier(node) { var name = node.name, effectiveParent = node.parent.type === "MemberExpression" ? node.parent.parent : node.parent; // MemberExpressions get special rules if (node.parent.type === "MemberExpression") { // Always check object names if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name) { if (isInvalid(name)) { report(node); } // Report AssignmentExpressions only if they are the left side of the assignment } else if (effectiveParent.type === "AssignmentExpression" && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { if (isInvalid(name)) { report(node); } } // Properties have their own rules } else if (node.parent.type === "Property") { if (shouldReport(effectiveParent, name)) { report(node); } // Report anything that is a match and not a CallExpression } else if (shouldReport(effectiveParent, name)) { report(node); } } }; } }; },{}],166:[function(require,module,exports){ /** * @fileoverview Rule that warns when identifier names are shorter or longer * than the values provided in configuration. * @author Burak Yigit Kaya aka BYK */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce minimum and maximum identifier lengths", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/id-length" }, schema: [{ type: "object", properties: { min: { type: "number" }, max: { type: "number" }, exceptions: { type: "array", uniqueItems: true, items: { type: "string" } }, properties: { enum: ["always", "never"] } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] || {}; var minLength = typeof options.min !== "undefined" ? options.min : 2; var maxLength = typeof options.max !== "undefined" ? options.max : Infinity; var properties = options.properties !== "never"; var exceptions = (options.exceptions ? options.exceptions : []).reduce(function (obj, item) { obj[item] = true; return obj; }, {}); var SUPPORTED_EXPRESSIONS = { MemberExpression: properties && function (parent) { return !parent.computed && ( // regular property assignment parent.parent.left === parent && parent.parent.type === "AssignmentExpression" || // or the last identifier in an ObjectPattern destructuring parent.parent.type === "Property" && parent.parent.value === parent && parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent); }, AssignmentPattern: function AssignmentPattern(parent, node) { return parent.left === node; }, VariableDeclarator: function VariableDeclarator(parent, node) { return parent.id === node; }, Property: properties && function (parent, node) { return parent.key === node; }, ImportDefaultSpecifier: true, RestElement: true, FunctionExpression: true, ArrowFunctionExpression: true, ClassDeclaration: true, FunctionDeclaration: true, MethodDefinition: true, CatchClause: true }; return { Identifier: function Identifier(node) { var name = node.name; var parent = node.parent; var isShort = name.length < minLength; var isLong = name.length > maxLength; if (!(isShort || isLong) || exceptions[name]) { return; // Nothing to report } var isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) { context.report({ node: node, message: isShort ? "Identifier name '{{name}}' is too short (< {{min}})." : "Identifier name '{{name}}' is too long (> {{max}}).", data: { name: name, min: minLength, max: maxLength } }); } } }; } }; },{}],167:[function(require,module,exports){ /** * @fileoverview Rule to flag non-matching identifiers * @author Matthieu Larcher */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require identifiers to match a specified regular expression", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/id-match" }, schema: [{ type: "string" }, { type: "object", properties: { properties: { type: "boolean" }, onlyDeclarations: { type: "boolean" }, ignoreDestructuring: { type: "boolean" } } }] }, create: function create(context) { //-------------------------------------------------------------------------- // Options //-------------------------------------------------------------------------- var pattern = context.options[0] || "^.+$", regexp = new RegExp(pattern); var options = context.options[1] || {}, properties = !!options.properties, onlyDeclarations = !!options.onlyDeclarations, ignoreDestructuring = !!options.ignoreDestructuring; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- // contains reported nodes to avoid reporting twice on destructuring with shorthand notation var reported = new Map(); var ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); var DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]); var IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]); /** * Checks if a string matches the provided pattern * @param {string} name The string to check. * @returns {boolean} if the string is a match * @private */ function isInvalid(name) { return !regexp.test(name); } /** * Checks if a parent of a node is an ObjectPattern. * @param {ASTNode} node The node to check. * @returns {boolean} if the node is inside an ObjectPattern * @private */ function isInsideObjectPattern(node) { var parent = node.parent; while (parent) { if (parent.type === "ObjectPattern") { return true; } parent = parent.parent; } return false; } /** * Verifies if we should report an error or not based on the effective * parent node and the identifier name. * @param {ASTNode} effectiveParent The effective parent node of the node to be reported * @param {string} name The identifier name of the identifier node * @returns {boolean} whether an error should be reported or not */ function shouldReport(effectiveParent, name) { return (!onlyDeclarations || DECLARATION_TYPES.has(effectiveParent.type)) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && isInvalid(name); } /** * Reports an AST node as a rule violation. * @param {ASTNode} node The node to report. * @returns {void} * @private */ function report(node) { if (!reported.has(node)) { context.report({ node: node, message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", data: { name: node.name, pattern: pattern } }); reported.set(node, true); } } return { Identifier: function Identifier(node) { var name = node.name, parent = node.parent, effectiveParent = parent.type === "MemberExpression" ? parent.parent : parent; if (parent.type === "MemberExpression") { if (!properties) { return; } // Always check object names if (parent.object.type === "Identifier" && parent.object.name === name) { if (isInvalid(name)) { report(node); } // Report AssignmentExpressions left side's assigned variable id } else if (effectiveParent.type === "AssignmentExpression" && effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name) { if (isInvalid(name)) { report(node); } // Report AssignmentExpressions only if they are the left side of the assignment } else if (effectiveParent.type === "AssignmentExpression" && effectiveParent.right.type !== "MemberExpression") { if (isInvalid(name)) { report(node); } } /* * Properties have their own rules, and * AssignmentPattern nodes can be treated like Properties: * e.g.: const { no_camelcased = false } = bar; */ } else if (parent.type === "Property" || parent.type === "AssignmentPattern") { if (parent.parent && parent.parent.type === "ObjectPattern") { if (parent.shorthand && parent.value.left && isInvalid(name)) { report(node); } var assignmentKeyEqualsValue = parent.key.name === parent.value.name; // prevent checking righthand side of destructured object if (!assignmentKeyEqualsValue && parent.key === node) { return; } var valueIsInvalid = parent.value.name && isInvalid(name); // ignore destructuring if the option is set, unless a new identifier is created if (valueIsInvalid && !(assignmentKeyEqualsValue && ignoreDestructuring)) { report(node); } } // never check properties or always ignore destructuring if (!properties || ignoreDestructuring && isInsideObjectPattern(node)) { return; } // don't check right hand side of AssignmentExpression to prevent duplicate warnings if (parent.right !== node && shouldReport(effectiveParent, name)) { report(node); } // Check if it's an import specifier } else if (IMPORT_TYPES.has(parent.type)) { // Report only if the local imported identifier is invalid if (parent.local && parent.local.name === node.name && isInvalid(name)) { report(node); } // Report anything that is invalid that isn't a CallExpression } else if (shouldReport(effectiveParent, name)) { report(node); } } }; } }; },{}],168:[function(require,module,exports){ /** * @fileoverview enforce the location of arrow function bodies * @author Sharmila Jesupaul */ "use strict"; var _require = require("../util/ast-utils"), isArrowToken = _require.isArrowToken, isParenthesised = _require.isParenthesised, isOpeningParenToken = _require.isOpeningParenToken; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce the location of arrow function bodies", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/implicit-arrow-linebreak" }, fixable: "whitespace", schema: [{ enum: ["beside", "below"] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Gets the applicable preference for a particular keyword * @returns {string} The applicable option for the keyword, e.g. 'beside' */ function getOption() { return context.options[0] || "beside"; } /** * Formats the comments depending on whether it's a line or block comment. * @param {Comment[]} comments The array of comments between the arrow and body * @param {Integer} column The column number of the first token * @returns {string} A string of comment text joined by line breaks */ function formatComments(comments, column) { var whiteSpaces = " ".repeat(column); return comments.map(function (comment) { if (comment.type === "Line") { return "//" + comment.value; } return "/*" + comment.value + "*/"; }).join("\n" + whiteSpaces) + "\n" + whiteSpaces; } /** * Finds the first token to prepend comments to depending on the parent type * @param {Node} node The validated node * @returns {Token|Node} The node to prepend comments to */ function findFirstToken(node) { switch (node.parent.type) { case "VariableDeclarator": // If the parent is first or only declarator, return the declaration, else, declarator return sourceCode.getFirstToken(node.parent.parent.declarations.length === 1 || node.parent.parent.declarations[0].id.name === node.parent.id.name ? node.parent.parent : node.parent); case "CallExpression": case "Property": // find the object key return sourceCode.getFirstToken(node.parent); default: return node; } } /** * Helper function for adding parentheses fixes for nodes containing nested arrow functions * @param {Fixer} fixer Fixer * @param {Token} arrow - The arrow token * @param {ASTNode} arrowBody - The arrow function body * @returns {Function[]} autofixer -- wraps function bodies with parentheses */ function addParentheses(fixer, arrow, arrowBody) { var parenthesesFixes = []; var closingParentheses = ""; var followingBody = arrowBody; var currentArrow = arrow; while (currentArrow) { if (!isParenthesised(sourceCode, followingBody)) { parenthesesFixes.push(fixer.insertTextAfter(currentArrow, " (")); var paramsToken = sourceCode.getTokenBefore(currentArrow, function (token) { return isOpeningParenToken(token) || token.type === "Identifier"; }); var whiteSpaces = " ".repeat(paramsToken.loc.start.column); closingParentheses = "\n" + whiteSpaces + ")" + closingParentheses; } currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken); if (currentArrow) { followingBody = sourceCode.getTokenAfter(currentArrow, function (token) { return !isOpeningParenToken(token); }); } } return [].concat(parenthesesFixes, [fixer.insertTextAfter(arrowBody, closingParentheses)]); } /** * Autofixes the function body to collapse onto the same line as the arrow. * If comments exist, prepends the comments before the arrow function. * If the function body contains arrow functions, appends the function bodies with parentheses. * @param {Token} arrowToken The arrow token. * @param {ASTNode} arrowBody the function body * @param {ASTNode} node The evaluated node * @returns {Function} autofixer -- validates the node to adhere to besides */ function autoFixBesides(arrowToken, arrowBody, node) { return function (fixer) { var placeBesides = fixer.replaceTextRange([arrowToken.range[1], arrowBody.range[0]], " "); var comments = sourceCode.getCommentsInside(node).filter(function (comment) { return comment.loc.start.line < arrowBody.loc.start.line; }); if (comments.length) { // If the grandparent is not a variable declarator if (arrowBody.parent && arrowBody.parent.parent && arrowBody.parent.parent.type !== "VariableDeclarator") { // If any arrow functions follow, return the necessary parens fixes. if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") { return addParentheses(fixer, arrowToken, arrowBody); } // If any arrow functions precede, the necessary fixes have already been returned, so return null. if (sourceCode.getTokenBefore(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") { return null; } } var firstToken = findFirstToken(node); var commentText = formatComments(comments, firstToken.loc.start.column); var commentBeforeExpression = fixer.insertTextBeforeRange(firstToken.range, commentText); return [placeBesides, commentBeforeExpression]; } return placeBesides; }; } /** * Validates the location of an arrow function body * @param {ASTNode} node The arrow function body * @returns {void} */ function validateExpression(node) { var option = getOption(); var tokenBefore = sourceCode.getTokenBefore(node.body); var hasParens = tokenBefore.value === "("; if (node.type === "BlockStatement") { return; } var fixerTarget = node.body; if (hasParens) { // Gets the first token before the function body that is not an open paren tokenBefore = sourceCode.getTokenBefore(node.body, function (token) { return token.value !== "("; }); fixerTarget = sourceCode.getTokenAfter(tokenBefore); } if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") { context.report({ node: fixerTarget, message: "Expected a linebreak before this expression.", fix: function fix(fixer) { return fixer.insertTextBefore(fixerTarget, "\n"); } }); } else if (tokenBefore.loc.end.line !== fixerTarget.loc.start.line && option === "beside") { context.report({ node: fixerTarget, message: "Expected no linebreak before this expression.", fix: autoFixBesides(tokenBefore, fixerTarget, node) }); } } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { ArrowFunctionExpression: function ArrowFunctionExpression(node) { return validateExpression(node); } }; } }; },{"../util/ast-utils":405}],169:[function(require,module,exports){ /** * @fileoverview This option sets a specific tab width for your code * * This rule has been ported and modified from nodeca. * @author Vitaly Puzrin * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /* istanbul ignore next: this rule has known coverage issues, but it's deprecated and shouldn't be updated in the future anyway. */ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent indentation", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/indent-legacy" }, deprecated: true, replacedBy: ["indent"], fixable: "whitespace", schema: [{ oneOf: [{ enum: ["tab"] }, { type: "integer", minimum: 0 }] }, { type: "object", properties: { SwitchCase: { type: "integer", minimum: 0 }, VariableDeclarator: { oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { var: { type: "integer", minimum: 0 }, let: { type: "integer", minimum: 0 }, const: { type: "integer", minimum: 0 } } }] }, outerIIFEBody: { type: "integer", minimum: 0 }, MemberExpression: { type: "integer", minimum: 0 }, FunctionDeclaration: { type: "object", properties: { parameters: { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["first"] }] }, body: { type: "integer", minimum: 0 } } }, FunctionExpression: { type: "object", properties: { parameters: { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["first"] }] }, body: { type: "integer", minimum: 0 } } }, CallExpression: { type: "object", properties: { parameters: { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["first"] }] } } }, ArrayExpression: { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["first"] }] }, ObjectExpression: { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["first"] }] } }, additionalProperties: false }] }, create: function create(context) { var DEFAULT_VARIABLE_INDENT = 1; var DEFAULT_PARAMETER_INDENT = null; // For backwards compatibility, don't check parameter indentation unless specified in the config var DEFAULT_FUNCTION_BODY_INDENT = 1; var indentType = "space"; var indentSize = 4; var options = { SwitchCase: 0, VariableDeclarator: { var: DEFAULT_VARIABLE_INDENT, let: DEFAULT_VARIABLE_INDENT, const: DEFAULT_VARIABLE_INDENT }, outerIIFEBody: null, FunctionDeclaration: { parameters: DEFAULT_PARAMETER_INDENT, body: DEFAULT_FUNCTION_BODY_INDENT }, FunctionExpression: { parameters: DEFAULT_PARAMETER_INDENT, body: DEFAULT_FUNCTION_BODY_INDENT }, CallExpression: { arguments: DEFAULT_PARAMETER_INDENT }, ArrayExpression: 1, ObjectExpression: 1 }; var sourceCode = context.getSourceCode(); if (context.options.length) { if (context.options[0] === "tab") { indentSize = 1; indentType = "tab"; } else /* istanbul ignore else : this will be caught by options validation */if (typeof context.options[0] === "number") { indentSize = context.options[0]; indentType = "space"; } if (context.options[1]) { var opts = context.options[1]; options.SwitchCase = opts.SwitchCase || 0; var variableDeclaratorRules = opts.VariableDeclarator; if (typeof variableDeclaratorRules === "number") { options.VariableDeclarator = { var: variableDeclaratorRules, let: variableDeclaratorRules, const: variableDeclaratorRules }; } else if ((typeof variableDeclaratorRules === "undefined" ? "undefined" : _typeof(variableDeclaratorRules)) === "object") { Object.assign(options.VariableDeclarator, variableDeclaratorRules); } if (typeof opts.outerIIFEBody === "number") { options.outerIIFEBody = opts.outerIIFEBody; } if (typeof opts.MemberExpression === "number") { options.MemberExpression = opts.MemberExpression; } if (_typeof(opts.FunctionDeclaration) === "object") { Object.assign(options.FunctionDeclaration, opts.FunctionDeclaration); } if (_typeof(opts.FunctionExpression) === "object") { Object.assign(options.FunctionExpression, opts.FunctionExpression); } if (_typeof(opts.CallExpression) === "object") { Object.assign(options.CallExpression, opts.CallExpression); } if (typeof opts.ArrayExpression === "number" || typeof opts.ArrayExpression === "string") { options.ArrayExpression = opts.ArrayExpression; } if (typeof opts.ObjectExpression === "number" || typeof opts.ObjectExpression === "string") { options.ObjectExpression = opts.ObjectExpression; } } } var caseIndentStore = {}; /** * Creates an error message for a line, given the expected/actual indentation. * @param {int} expectedAmount The expected amount of indentation characters for this line * @param {int} actualSpaces The actual number of indentation spaces that were found on this line * @param {int} actualTabs The actual number of indentation tabs that were found on this line * @returns {string} An error message for this line */ function createErrorMessage(expectedAmount, actualSpaces, actualTabs) { var expectedStatement = expectedAmount + " " + indentType + (expectedAmount === 1 ? "" : "s"); // e.g. "2 tabs" var foundSpacesWord = "space" + (actualSpaces === 1 ? "" : "s"); // e.g. "space" var foundTabsWord = "tab" + (actualTabs === 1 ? "" : "s"); // e.g. "tabs" var foundStatement = void 0; if (actualSpaces > 0 && actualTabs > 0) { foundStatement = actualSpaces + " " + foundSpacesWord + " and " + actualTabs + " " + foundTabsWord; // e.g. "1 space and 2 tabs" } else if (actualSpaces > 0) { /* * Abbreviate the message if the expected indentation is also spaces. * e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' */ foundStatement = indentType === "space" ? actualSpaces : actualSpaces + " " + foundSpacesWord; } else if (actualTabs > 0) { foundStatement = indentType === "tab" ? actualTabs : actualTabs + " " + foundTabsWord; } else { foundStatement = "0"; } return "Expected indentation of " + expectedStatement + " but found " + foundStatement + "."; } /** * Reports a given indent violation * @param {ASTNode} node Node violating the indent rule * @param {int} needed Expected indentation character count * @param {int} gottenSpaces Indentation space count in the actual node/code * @param {int} gottenTabs Indentation tab count in the actual node/code * @param {Object=} loc Error line and column location * @param {boolean} isLastNodeCheck Is the error for last node check * @returns {void} */ function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) { if (gottenSpaces && gottenTabs) { // To avoid conflicts with `no-mixed-spaces-and-tabs`, don't report lines that have both spaces and tabs. return; } var desiredIndent = (indentType === "space" ? " " : "\t").repeat(needed); var textRange = isLastNodeCheck ? [node.range[1] - node.loc.end.column, node.range[1] - node.loc.end.column + gottenSpaces + gottenTabs] : [node.range[0] - node.loc.start.column, node.range[0] - node.loc.start.column + gottenSpaces + gottenTabs]; context.report({ node: node, loc: loc, message: createErrorMessage(needed, gottenSpaces, gottenTabs), fix: function fix(fixer) { return fixer.replaceTextRange(textRange, desiredIndent); } }); } /** * Get the actual indent of node * @param {ASTNode|Token} node Node to examine * @param {boolean} [byLastLine=false] get indent of node's last line * @returns {Object} The node's indent. Contains keys `space` and `tab`, representing the indent of each character. Also * contains keys `goodChar` and `badChar`, where `goodChar` is the amount of the user's desired indentation character, and * `badChar` is the amount of the other indentation character. */ function getNodeIndent(node, byLastLine) { var token = byLastLine ? sourceCode.getLastToken(node) : sourceCode.getFirstToken(node); var srcCharsBeforeNode = sourceCode.getText(token, token.loc.start.column).split(""); var indentChars = srcCharsBeforeNode.slice(0, srcCharsBeforeNode.findIndex(function (char) { return char !== " " && char !== "\t"; })); var spaces = indentChars.filter(function (char) { return char === " "; }).length; var tabs = indentChars.filter(function (char) { return char === "\t"; }).length; return { space: spaces, tab: tabs, goodChar: indentType === "space" ? spaces : tabs, badChar: indentType === "space" ? tabs : spaces }; } /** * Checks node is the first in its own start line. By default it looks by start line. * @param {ASTNode} node The node to check * @param {boolean} [byEndLocation=false] Lookup based on start position or end * @returns {boolean} true if its the first in the its start line */ function isNodeFirstInLine(node, byEndLocation) { var firstToken = byEndLocation === true ? sourceCode.getLastToken(node, 1) : sourceCode.getTokenBefore(node), startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line, endLine = firstToken ? firstToken.loc.end.line : -1; return startLine !== endLine; } /** * Check indent for node * @param {ASTNode} node Node to check * @param {int} neededIndent needed indent * @returns {void} */ function checkNodeIndent(node, neededIndent) { var actualIndent = getNodeIndent(node, false); if (node.type !== "ArrayExpression" && node.type !== "ObjectExpression" && (actualIndent.goodChar !== neededIndent || actualIndent.badChar !== 0) && isNodeFirstInLine(node)) { report(node, neededIndent, actualIndent.space, actualIndent.tab); } if (node.type === "IfStatement" && node.alternate) { var elseToken = sourceCode.getTokenBefore(node.alternate); checkNodeIndent(elseToken, neededIndent); if (!isNodeFirstInLine(node.alternate)) { checkNodeIndent(node.alternate, neededIndent); } } if (node.type === "TryStatement" && node.handler) { var catchToken = sourceCode.getFirstToken(node.handler); checkNodeIndent(catchToken, neededIndent); } if (node.type === "TryStatement" && node.finalizer) { var finallyToken = sourceCode.getTokenBefore(node.finalizer); checkNodeIndent(finallyToken, neededIndent); } if (node.type === "DoWhileStatement") { var whileToken = sourceCode.getTokenAfter(node.body); checkNodeIndent(whileToken, neededIndent); } } /** * Check indent for nodes list * @param {ASTNode[]} nodes list of node objects * @param {int} indent needed indent * @returns {void} */ function checkNodesIndent(nodes, indent) { nodes.forEach(function (node) { return checkNodeIndent(node, indent); }); } /** * Check last node line indent this detects, that block closed correctly * @param {ASTNode} node Node to examine * @param {int} lastLineIndent needed indent * @returns {void} */ function checkLastNodeLineIndent(node, lastLineIndent) { var lastToken = sourceCode.getLastToken(node); var endIndent = getNodeIndent(lastToken, true); if ((endIndent.goodChar !== lastLineIndent || endIndent.badChar !== 0) && isNodeFirstInLine(node, true)) { report(node, lastLineIndent, endIndent.space, endIndent.tab, { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, true); } } /** * Check last node line indent this detects, that block closed correctly * This function for more complicated return statement case, where closing parenthesis may be followed by ';' * @param {ASTNode} node Node to examine * @param {int} firstLineIndent first line needed indent * @returns {void} */ function checkLastReturnStatementLineIndent(node, firstLineIndent) { /* * in case if return statement ends with ');' we have traverse back to ')' * otherwise we'll measure indent for ';' and replace ')' */ var lastToken = sourceCode.getLastToken(node, astUtils.isClosingParenToken); var textBeforeClosingParenthesis = sourceCode.getText(lastToken, lastToken.loc.start.column).slice(0, -1); if (textBeforeClosingParenthesis.trim()) { // There are tokens before the closing paren, don't report this case return; } var endIndent = getNodeIndent(lastToken, true); if (endIndent.goodChar !== firstLineIndent) { report(node, firstLineIndent, endIndent.space, endIndent.tab, { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, true); } } /** * Check first node line indent is correct * @param {ASTNode} node Node to examine * @param {int} firstLineIndent needed indent * @returns {void} */ function checkFirstNodeLineIndent(node, firstLineIndent) { var startIndent = getNodeIndent(node, false); if ((startIndent.goodChar !== firstLineIndent || startIndent.badChar !== 0) && isNodeFirstInLine(node)) { report(node, firstLineIndent, startIndent.space, startIndent.tab, { line: node.loc.start.line, column: node.loc.start.column }); } } /** * Returns a parent node of given node based on a specified type * if not present then return null * @param {ASTNode} node node to examine * @param {string} type type that is being looked for * @param {string} stopAtList end points for the evaluating code * @returns {ASTNode|void} if found then node otherwise null */ function getParentNodeByType(node, type, stopAtList) { var parent = node.parent; var stopAtSet = new Set(stopAtList || ["Program"]); while (parent.type !== type && !stopAtSet.has(parent.type) && parent.type !== "Program") { parent = parent.parent; } return parent.type === type ? parent : null; } /** * Returns the VariableDeclarator based on the current node * if not present then return null * @param {ASTNode} node node to examine * @returns {ASTNode|void} if found then node otherwise null */ function getVariableDeclaratorNode(node) { return getParentNodeByType(node, "VariableDeclarator"); } /** * Check to see if the node is part of the multi-line variable declaration. * Also if its on the same line as the varNode * @param {ASTNode} node node to check * @param {ASTNode} varNode variable declaration node to check against * @returns {boolean} True if all the above condition satisfy */ function isNodeInVarOnTop(node, varNode) { return varNode && varNode.parent.loc.start.line === node.loc.start.line && varNode.parent.declarations.length > 1; } /** * Check to see if the argument before the callee node is multi-line and * there should only be 1 argument before the callee node * @param {ASTNode} node node to check * @returns {boolean} True if arguments are multi-line */ function isArgBeforeCalleeNodeMultiline(node) { var parent = node.parent; if (parent.arguments.length >= 2 && parent.arguments[1] === node) { return parent.arguments[0].loc.end.line > parent.arguments[0].loc.start.line; } return false; } /** * Check to see if the node is a file level IIFE * @param {ASTNode} node The function node to check. * @returns {boolean} True if the node is the outer IIFE */ function isOuterIIFE(node) { var parent = node.parent; var stmt = parent.parent; /* * Verify that the node is an IIEF */ if (parent.type !== "CallExpression" || parent.callee !== node) { return false; } /* * Navigate legal ancestors to determine whether this IIEF is outer */ while (stmt.type === "UnaryExpression" && (stmt.operator === "!" || stmt.operator === "~" || stmt.operator === "+" || stmt.operator === "-") || stmt.type === "AssignmentExpression" || stmt.type === "LogicalExpression" || stmt.type === "SequenceExpression" || stmt.type === "VariableDeclarator") { stmt = stmt.parent; } return (stmt.type === "ExpressionStatement" || stmt.type === "VariableDeclaration") && stmt.parent && stmt.parent.type === "Program"; } /** * Check indent for function block content * @param {ASTNode} node A BlockStatement node that is inside of a function. * @returns {void} */ function checkIndentInFunctionBlock(node) { /* * Search first caller in chain. * Ex.: * * Models <- Identifier * .User * .find() * .exec(function() { * // function body * }); * * Looks for 'Models' */ var calleeNode = node.parent; // FunctionExpression var indent = void 0; if (calleeNode.parent && (calleeNode.parent.type === "Property" || calleeNode.parent.type === "ArrayExpression")) { // If function is part of array or object, comma can be put at left indent = getNodeIndent(calleeNode, false).goodChar; } else { // If function is standalone, simple calculate indent indent = getNodeIndent(calleeNode).goodChar; } if (calleeNode.parent.type === "CallExpression") { var calleeParent = calleeNode.parent; if (calleeNode.type !== "FunctionExpression" && calleeNode.type !== "ArrowFunctionExpression") { if (calleeParent && calleeParent.loc.start.line < node.loc.start.line) { indent = getNodeIndent(calleeParent).goodChar; } } else { if (isArgBeforeCalleeNodeMultiline(calleeNode) && calleeParent.callee.loc.start.line === calleeParent.callee.loc.end.line && !isNodeFirstInLine(calleeNode)) { indent = getNodeIndent(calleeParent).goodChar; } } } /* * function body indent should be indent + indent size, unless this * is a FunctionDeclaration, FunctionExpression, or outer IIFE and the corresponding options are enabled. */ var functionOffset = indentSize; if (options.outerIIFEBody !== null && isOuterIIFE(calleeNode)) { functionOffset = options.outerIIFEBody * indentSize; } else if (calleeNode.type === "FunctionExpression") { functionOffset = options.FunctionExpression.body * indentSize; } else if (calleeNode.type === "FunctionDeclaration") { functionOffset = options.FunctionDeclaration.body * indentSize; } indent += functionOffset; // check if the node is inside a variable var parentVarNode = getVariableDeclaratorNode(node); if (parentVarNode && isNodeInVarOnTop(node, parentVarNode)) { indent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; } if (node.body.length > 0) { checkNodesIndent(node.body, indent); } checkLastNodeLineIndent(node, indent - functionOffset); } /** * Checks if the given node starts and ends on the same line * @param {ASTNode} node The node to check * @returns {boolean} Whether or not the block starts and ends on the same line. */ function isSingleLineNode(node) { var lastToken = sourceCode.getLastToken(node), startLine = node.loc.start.line, endLine = lastToken.loc.end.line; return startLine === endLine; } /** * Check to see if the first element inside an array is an object and on the same line as the node * If the node is not an array then it will return false. * @param {ASTNode} node node to check * @returns {boolean} success/failure */ function isFirstArrayElementOnSameLine(node) { if (node.type === "ArrayExpression" && node.elements[0]) { return node.elements[0].loc.start.line === node.loc.start.line && node.elements[0].type === "ObjectExpression"; } return false; } /** * Check indent for array block content or object block content * @param {ASTNode} node node to examine * @returns {void} */ function checkIndentInArrayOrObjectBlock(node) { // Skip inline if (isSingleLineNode(node)) { return; } var elements = node.type === "ArrayExpression" ? node.elements : node.properties; // filter out empty elements example would be [ , 2] so remove first element as espree considers it as null elements = elements.filter(function (elem) { return elem !== null; }); var nodeIndent = void 0; var elementsIndent = void 0; var parentVarNode = getVariableDeclaratorNode(node); // TODO - come up with a better strategy in future if (isNodeFirstInLine(node)) { var parent = node.parent; nodeIndent = getNodeIndent(parent).goodChar; if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) { if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) { if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) { nodeIndent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") { var parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements; if (parentElements[0] && parentElements[0].loc.start.line === parent.loc.start.line && parentElements[0].loc.end.line !== parent.loc.start.line) { /* * If the first element of the array spans multiple lines, don't increase the expected indentation of the rest. * e.g. [{ * foo: 1 * }, * { * bar: 1 * }] * the second object is not indented. */ } else if (typeof options[parent.type] === "number") { nodeIndent += options[parent.type] * indentSize; } else { nodeIndent = parentElements[0].loc.start.column; } } else if (parent.type === "CallExpression" || parent.type === "NewExpression") { if (typeof options.CallExpression.arguments === "number") { nodeIndent += options.CallExpression.arguments * indentSize; } else if (options.CallExpression.arguments === "first") { if (parent.arguments.indexOf(node) !== -1) { nodeIndent = parent.arguments[0].loc.start.column; } } else { nodeIndent += indentSize; } } else if (parent.type === "LogicalExpression" || parent.type === "ArrowFunctionExpression") { nodeIndent += indentSize; } } } else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && parent.type !== "MemberExpression" && parent.type !== "ExpressionStatement" && parent.type !== "AssignmentExpression" && parent.type !== "Property") { nodeIndent += indentSize; } checkFirstNodeLineIndent(node, nodeIndent); } else { nodeIndent = getNodeIndent(node).goodChar; } if (options[node.type] === "first") { elementsIndent = elements.length ? elements[0].loc.start.column : 0; // If there are no elements, elementsIndent doesn't matter. } else { elementsIndent = nodeIndent + indentSize * options[node.type]; } /* * Check if the node is a multiple variable declaration; if so, then * make sure indentation takes that into account. */ if (isNodeInVarOnTop(node, parentVarNode)) { elementsIndent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; } checkNodesIndent(elements, elementsIndent); if (elements.length > 0) { // Skip last block line check if last item in same line if (elements[elements.length - 1].loc.end.line === node.loc.end.line) { return; } } checkLastNodeLineIndent(node, nodeIndent + (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0)); } /** * Check if the node or node body is a BlockStatement or not * @param {ASTNode} node node to test * @returns {boolean} True if it or its body is a block statement */ function isNodeBodyBlock(node) { return node.type === "BlockStatement" || node.type === "ClassBody" || node.body && node.body.type === "BlockStatement" || node.consequent && node.consequent.type === "BlockStatement"; } /** * Check indentation for blocks * @param {ASTNode} node node to check * @returns {void} */ function blockIndentationCheck(node) { // Skip inline blocks if (isSingleLineNode(node)) { return; } if (node.parent && (node.parent.type === "FunctionExpression" || node.parent.type === "FunctionDeclaration" || node.parent.type === "ArrowFunctionExpression")) { checkIndentInFunctionBlock(node); return; } var indent = void 0; var nodesToCheck = []; /* * For this statements we should check indent from statement beginning, * not from the beginning of the block. */ var statementsWithProperties = ["IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration", "TryStatement"]; if (node.parent && statementsWithProperties.indexOf(node.parent.type) !== -1 && isNodeBodyBlock(node)) { indent = getNodeIndent(node.parent).goodChar; } else if (node.parent && node.parent.type === "CatchClause") { indent = getNodeIndent(node.parent.parent).goodChar; } else { indent = getNodeIndent(node).goodChar; } if (node.type === "IfStatement" && node.consequent.type !== "BlockStatement") { nodesToCheck = [node.consequent]; } else if (Array.isArray(node.body)) { nodesToCheck = node.body; } else { nodesToCheck = [node.body]; } if (nodesToCheck.length > 0) { checkNodesIndent(nodesToCheck, indent + indentSize); } if (node.type === "BlockStatement") { checkLastNodeLineIndent(node, indent); } } /** * Filter out the elements which are on the same line of each other or the node. * basically have only 1 elements from each line except the variable declaration line. * @param {ASTNode} node Variable declaration node * @returns {ASTNode[]} Filtered elements */ function filterOutSameLineVars(node) { return node.declarations.reduce(function (finalCollection, elem) { var lastElem = finalCollection[finalCollection.length - 1]; if (elem.loc.start.line !== node.loc.start.line && !lastElem || lastElem && lastElem.loc.start.line !== elem.loc.start.line) { finalCollection.push(elem); } return finalCollection; }, []); } /** * Check indentation for variable declarations * @param {ASTNode} node node to examine * @returns {void} */ function checkIndentInVariableDeclarations(node) { var elements = filterOutSameLineVars(node); var nodeIndent = getNodeIndent(node).goodChar; var lastElement = elements[elements.length - 1]; var elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind]; checkNodesIndent(elements, elementsIndent); // Only check the last line if there is any token after the last item if (sourceCode.getLastToken(node).loc.end.line <= lastElement.loc.end.line) { return; } var tokenBeforeLastElement = sourceCode.getTokenBefore(lastElement); if (tokenBeforeLastElement.value === ",") { // Special case for comma-first syntax where the semicolon is indented checkLastNodeLineIndent(node, getNodeIndent(tokenBeforeLastElement).goodChar); } else { checkLastNodeLineIndent(node, elementsIndent - indentSize); } } /** * Check and decide whether to check for indentation for blockless nodes * Scenarios are for or while statements without braces around them * @param {ASTNode} node node to examine * @returns {void} */ function blockLessNodes(node) { if (node.body.type !== "BlockStatement") { blockIndentationCheck(node); } } /** * Returns the expected indentation for the case statement * @param {ASTNode} node node to examine * @param {int} [providedSwitchIndent] indent for switch statement * @returns {int} indent size */ function expectedCaseIndent(node, providedSwitchIndent) { var switchNode = node.type === "SwitchStatement" ? node : node.parent; var switchIndent = typeof providedSwitchIndent === "undefined" ? getNodeIndent(switchNode).goodChar : providedSwitchIndent; var caseIndent = void 0; if (caseIndentStore[switchNode.loc.start.line]) { return caseIndentStore[switchNode.loc.start.line]; } if (switchNode.cases.length > 0 && options.SwitchCase === 0) { caseIndent = switchIndent; } else { caseIndent = switchIndent + indentSize * options.SwitchCase; } caseIndentStore[switchNode.loc.start.line] = caseIndent; return caseIndent; } /** * Checks wether a return statement is wrapped in () * @param {ASTNode} node node to examine * @returns {boolean} the result */ function isWrappedInParenthesis(node) { var regex = /^return\s*?\(\s*?\);*?/; var statementWithoutArgument = sourceCode.getText(node).replace(sourceCode.getText(node.argument), ""); return regex.test(statementWithoutArgument); } return { Program: function Program(node) { if (node.body.length > 0) { // Root nodes should have no indent checkNodesIndent(node.body, getNodeIndent(node).goodChar); } }, ClassBody: blockIndentationCheck, BlockStatement: blockIndentationCheck, WhileStatement: blockLessNodes, ForStatement: blockLessNodes, ForInStatement: blockLessNodes, ForOfStatement: blockLessNodes, DoWhileStatement: blockLessNodes, IfStatement: function IfStatement(node) { if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) { blockIndentationCheck(node); } }, VariableDeclaration: function VariableDeclaration(node) { if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) { checkIndentInVariableDeclarations(node); } }, ObjectExpression: function ObjectExpression(node) { checkIndentInArrayOrObjectBlock(node); }, ArrayExpression: function ArrayExpression(node) { checkIndentInArrayOrObjectBlock(node); }, MemberExpression: function MemberExpression(node) { if (typeof options.MemberExpression === "undefined") { return; } if (isSingleLineNode(node)) { return; } /* * The typical layout of variable declarations and assignments * alter the expectation of correct indentation. Skip them. * TODO: Add appropriate configuration options for variable * declarations and assignments. */ if (getParentNodeByType(node, "VariableDeclarator", ["FunctionExpression", "ArrowFunctionExpression"])) { return; } if (getParentNodeByType(node, "AssignmentExpression", ["FunctionExpression"])) { return; } var propertyIndent = getNodeIndent(node).goodChar + indentSize * options.MemberExpression; var checkNodes = [node.property]; var dot = sourceCode.getTokenBefore(node.property); if (dot.type === "Punctuator" && dot.value === ".") { checkNodes.push(dot); } checkNodesIndent(checkNodes, propertyIndent); }, SwitchStatement: function SwitchStatement(node) { // Switch is not a 'BlockStatement' var switchIndent = getNodeIndent(node).goodChar; var caseIndent = expectedCaseIndent(node, switchIndent); checkNodesIndent(node.cases, caseIndent); checkLastNodeLineIndent(node, switchIndent); }, SwitchCase: function SwitchCase(node) { // Skip inline cases if (isSingleLineNode(node)) { return; } var caseIndent = expectedCaseIndent(node); checkNodesIndent(node.consequent, caseIndent + indentSize); }, FunctionDeclaration: function FunctionDeclaration(node) { if (isSingleLineNode(node)) { return; } if (options.FunctionDeclaration.parameters === "first" && node.params.length) { checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); } else if (options.FunctionDeclaration.parameters !== null) { checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionDeclaration.parameters); } }, FunctionExpression: function FunctionExpression(node) { if (isSingleLineNode(node)) { return; } if (options.FunctionExpression.parameters === "first" && node.params.length) { checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); } else if (options.FunctionExpression.parameters !== null) { checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionExpression.parameters); } }, ReturnStatement: function ReturnStatement(node) { if (isSingleLineNode(node)) { return; } var firstLineIndent = getNodeIndent(node).goodChar; // in case if return statement is wrapped in parenthesis if (isWrappedInParenthesis(node)) { checkLastReturnStatementLineIndent(node, firstLineIndent); } else { checkNodeIndent(node, firstLineIndent); } }, CallExpression: function CallExpression(node) { if (isSingleLineNode(node)) { return; } if (options.CallExpression.arguments === "first" && node.arguments.length) { checkNodesIndent(node.arguments.slice(1), node.arguments[0].loc.start.column); } else if (options.CallExpression.arguments !== null) { checkNodesIndent(node.arguments, getNodeIndent(node).goodChar + indentSize * options.CallExpression.arguments); } } }; } }; },{"../util/ast-utils":405}],170:[function(require,module,exports){ /** * @fileoverview This rule sets a specific indentation style and width for your code * * @author Teddy Katz * @author Vitaly Puzrin * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); var createTree = require("functional-red-black-tree"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var KNOWN_NODES = new Set(["AssignmentExpression", "AssignmentPattern", "ArrayExpression", "ArrayPattern", "ArrowFunctionExpression", "AwaitExpression", "BlockStatement", "BinaryExpression", "BreakStatement", "CallExpression", "CatchClause", "ClassBody", "ClassDeclaration", "ClassExpression", "ConditionalExpression", "ContinueStatement", "DoWhileStatement", "DebuggerStatement", "EmptyStatement", "ExperimentalRestProperty", "ExperimentalSpreadProperty", "ExpressionStatement", "ForStatement", "ForInStatement", "ForOfStatement", "FunctionDeclaration", "FunctionExpression", "Identifier", "IfStatement", "Literal", "LabeledStatement", "LogicalExpression", "MemberExpression", "MetaProperty", "MethodDefinition", "NewExpression", "ObjectExpression", "ObjectPattern", "Program", "Property", "RestElement", "ReturnStatement", "SequenceExpression", "SpreadElement", "Super", "SwitchCase", "SwitchStatement", "TaggedTemplateExpression", "TemplateElement", "TemplateLiteral", "ThisExpression", "ThrowStatement", "TryStatement", "UnaryExpression", "UpdateExpression", "VariableDeclaration", "VariableDeclarator", "WhileStatement", "WithStatement", "YieldExpression", "JSXIdentifier", "JSXNamespacedName", "JSXMemberExpression", "JSXEmptyExpression", "JSXExpressionContainer", "JSXElement", "JSXClosingElement", "JSXOpeningElement", "JSXAttribute", "JSXSpreadAttribute", "JSXText", "ExportDefaultDeclaration", "ExportNamedDeclaration", "ExportAllDeclaration", "ExportSpecifier", "ImportDeclaration", "ImportSpecifier", "ImportDefaultSpecifier", "ImportNamespaceSpecifier"]); /* * General rule strategy: * 1. An OffsetStorage instance stores a map of desired offsets, where each token has a specified offset from another * specified token or to the first column. * 2. As the AST is traversed, modify the desired offsets of tokens accordingly. For example, when entering a * BlockStatement, offset all of the tokens in the BlockStatement by 1 indent level from the opening curly * brace of the BlockStatement. * 3. After traversing the AST, calculate the expected indentation levels of every token according to the * OffsetStorage container. * 4. For each line, compare the expected indentation of the first token to the actual indentation in the file, * and report the token if the two values are not equal. */ /** * A mutable balanced binary search tree that stores (key, value) pairs. The keys are numeric, and must be unique. * This is intended to be a generic wrapper around a balanced binary search tree library, so that the underlying implementation * can easily be swapped out. */ var BinarySearchTree = function () { /** * Creates an empty tree */ function BinarySearchTree() { _classCallCheck(this, BinarySearchTree); this._rbTree = createTree(); } /** * Inserts an entry into the tree. * @param {number} key The entry's key * @param {*} value The entry's value * @returns {void} */ _createClass(BinarySearchTree, [{ key: "insert", value: function insert(key, value) { var iterator = this._rbTree.find(key); if (iterator.valid) { this._rbTree = iterator.update(value); } else { this._rbTree = this._rbTree.insert(key, value); } } /** * Finds the entry with the largest key less than or equal to the provided key * @param {number} key The provided key * @returns {{key: number, value: *}|null} The found entry, or null if no such entry exists. */ }, { key: "findLe", value: function findLe(key) { var iterator = this._rbTree.le(key); return iterator && { key: iterator.key, value: iterator.value }; } /** * Deletes all of the keys in the interval [start, end) * @param {number} start The start of the range * @param {number} end The end of the range * @returns {void} */ }, { key: "deleteRange", value: function deleteRange(start, end) { // Exit without traversing the tree if the range has zero size. if (start === end) { return; } var iterator = this._rbTree.ge(start); while (iterator.valid && iterator.key < end) { this._rbTree = this._rbTree.remove(iterator.key); iterator.next(); } } }]); return BinarySearchTree; }(); /** * A helper class to get token-based info related to indentation */ var TokenInfo = function () { /** * @param {SourceCode} sourceCode A SourceCode object */ function TokenInfo(sourceCode) { _classCallCheck(this, TokenInfo); this.sourceCode = sourceCode; this.firstTokensByLineNumber = sourceCode.tokensAndComments.reduce(function (map, token) { if (!map.has(token.loc.start.line)) { map.set(token.loc.start.line, token); } if (!map.has(token.loc.end.line) && sourceCode.text.slice(token.range[1] - token.loc.end.column, token.range[1]).trim()) { map.set(token.loc.end.line, token); } return map; }, new Map()); } /** * Gets the first token on a given token's line * @param {Token|ASTNode} token a node or token * @returns {Token} The first token on the given line */ _createClass(TokenInfo, [{ key: "getFirstTokenOfLine", value: function getFirstTokenOfLine(token) { return this.firstTokensByLineNumber.get(token.loc.start.line); } /** * Determines whether a token is the first token in its line * @param {Token} token The token * @returns {boolean} `true` if the token is the first on its line */ }, { key: "isFirstTokenOfLine", value: function isFirstTokenOfLine(token) { return this.getFirstTokenOfLine(token) === token; } /** * Get the actual indent of a token * @param {Token} token Token to examine. This should be the first token on its line. * @returns {string} The indentation characters that precede the token */ }, { key: "getTokenIndent", value: function getTokenIndent(token) { return this.sourceCode.text.slice(token.range[0] - token.loc.start.column, token.range[0]); } }]); return TokenInfo; }(); /** * A class to store information on desired offsets of tokens from each other */ var OffsetStorage = function () { /** * @param {TokenInfo} tokenInfo a TokenInfo instance * @param {number} indentSize The desired size of each indentation level * @param {string} indentType The indentation character */ function OffsetStorage(tokenInfo, indentSize, indentType) { _classCallCheck(this, OffsetStorage); this._tokenInfo = tokenInfo; this._indentSize = indentSize; this._indentType = indentType; this._tree = new BinarySearchTree(); this._tree.insert(0, { offset: 0, from: null, force: false }); this._lockedFirstTokens = new WeakMap(); this._desiredIndentCache = new WeakMap(); this._ignoredTokens = new WeakSet(); } _createClass(OffsetStorage, [{ key: "_getOffsetDescriptor", value: function _getOffsetDescriptor(token) { return this._tree.findLe(token.range[0]).value; } /** * Sets the offset column of token B to match the offset column of token A. * **WARNING**: This matches a *column*, even if baseToken is not the first token on its line. In * most cases, `setDesiredOffset` should be used instead. * @param {Token} baseToken The first token * @param {Token} offsetToken The second token, whose offset should be matched to the first token * @returns {void} */ }, { key: "matchOffsetOf", value: function matchOffsetOf(baseToken, offsetToken) { /* * lockedFirstTokens is a map from a token whose indentation is controlled by the "first" option to * the token that it depends on. For example, with the `ArrayExpression: first` option, the first * token of each element in the array after the first will be mapped to the first token of the first * element. The desired indentation of each of these tokens is computed based on the desired indentation * of the "first" element, rather than through the normal offset mechanism. */ this._lockedFirstTokens.set(offsetToken, baseToken); } /** * Sets the desired offset of a token. * * This uses a line-based offset collapsing behavior to handle tokens on the same line. * For example, consider the following two cases: * * ( * [ * bar * ] * ) * * ([ * bar * ]) * * Based on the first case, it's clear that the `bar` token needs to have an offset of 1 indent level (4 spaces) from * the `[` token, and the `[` token has to have an offset of 1 indent level from the `(` token. Since the `(` token is * the first on its line (with an indent of 0 spaces), the `bar` token needs to be offset by 2 indent levels (8 spaces) * from the start of its line. * * However, in the second case `bar` should only be indented by 4 spaces. This is because the offset of 1 indent level * between the `(` and the `[` tokens gets "collapsed" because the two tokens are on the same line. As a result, the * `(` token is mapped to the `[` token with an offset of 0, and the rule correctly decides that `bar` should be indented * by 1 indent level from the start of the line. * * This is useful because rule listeners can usually just call `setDesiredOffset` for all the tokens in the node, * without needing to check which lines those tokens are on. * * Note that since collapsing only occurs when two tokens are on the same line, there are a few cases where non-intuitive * behavior can occur. For example, consider the following cases: * * foo( * ). * bar( * baz * ) * * foo( * ).bar( * baz * ) * * Based on the first example, it would seem that `bar` should be offset by 1 indent level from `foo`, and `baz` * should be offset by 1 indent level from `bar`. However, this is not correct, because it would result in `baz` * being indented by 2 indent levels in the second case (since `foo`, `bar`, and `baz` are all on separate lines, no * collapsing would occur). * * Instead, the correct way would be to offset `baz` by 1 level from `bar`, offset `bar` by 1 level from the `)`, and * offset the `)` by 0 levels from `foo`. This ensures that the offset between `bar` and the `)` are correctly collapsed * in the second case. * * @param {Token} token The token * @param {Token} fromToken The token that `token` should be offset from * @param {number} offset The desired indent level * @returns {void} */ }, { key: "setDesiredOffset", value: function setDesiredOffset(token, fromToken, offset) { return this.setDesiredOffsets(token.range, fromToken, offset); } /** * Sets the desired offset of all tokens in a range * It's common for node listeners in this file to need to apply the same offset to a large, contiguous range of tokens. * Moreover, the offset of any given token is usually updated multiple times (roughly once for each node that contains * it). This means that the offset of each token is updated O(AST depth) times. * It would not be performant to store and update the offsets for each token independently, because the rule would end * up having a time complexity of O(number of tokens * AST depth), which is quite slow for large files. * * Instead, the offset tree is represented as a collection of contiguous offset ranges in a file. For example, the following * list could represent the state of the offset tree at a given point: * * * Tokens starting in the interval [0, 15) are aligned with the beginning of the file * * Tokens starting in the interval [15, 30) are offset by 1 indent level from the `bar` token * * Tokens starting in the interval [30, 43) are offset by 1 indent level from the `foo` token * * Tokens starting in the interval [43, 820) are offset by 2 indent levels from the `bar` token * * Tokens starting in the interval [820, ∞) are offset by 1 indent level from the `baz` token * * The `setDesiredOffsets` methods inserts ranges like the ones above. The third line above would be inserted by using: * `setDesiredOffsets([30, 43], fooToken, 1);` * * @param {[number, number]} range A [start, end] pair. All tokens with range[0] <= token.start < range[1] will have the offset applied. * @param {Token} fromToken The token that this is offset from * @param {number} offset The desired indent level * @param {boolean} force `true` if this offset should not use the normal collapsing behavior. This should almost always be false. * @returns {void} */ }, { key: "setDesiredOffsets", value: function setDesiredOffsets(range, fromToken, offset, force) { /* * Offset ranges are stored as a collection of nodes, where each node maps a numeric key to an offset * descriptor. The tree for the example above would have the following nodes: * * * key: 0, value: { offset: 0, from: null } * * key: 15, value: { offset: 1, from: barToken } * * key: 30, value: { offset: 1, from: fooToken } * * key: 43, value: { offset: 2, from: barToken } * * key: 820, value: { offset: 1, from: bazToken } * * To find the offset descriptor for any given token, one needs to find the node with the largest key * which is <= token.start. To make this operation fast, the nodes are stored in a balanced binary * search tree indexed by key. */ var descriptorToInsert = { offset: offset, from: fromToken, force: force }; var descriptorAfterRange = this._tree.findLe(range[1]).value; var fromTokenIsInRange = fromToken && fromToken.range[0] >= range[0] && fromToken.range[1] <= range[1]; var fromTokenDescriptor = fromTokenIsInRange && this._getOffsetDescriptor(fromToken); // First, remove any existing nodes in the range from the tree. this._tree.deleteRange(range[0] + 1, range[1]); // Insert a new node into the tree for this range this._tree.insert(range[0], descriptorToInsert); /* * To avoid circular offset dependencies, keep the `fromToken` token mapped to whatever it was mapped to previously, * even if it's in the current range. */ if (fromTokenIsInRange) { this._tree.insert(fromToken.range[0], fromTokenDescriptor); this._tree.insert(fromToken.range[1], descriptorToInsert); } /* * To avoid modifying the offset of tokens after the range, insert another node to keep the offset of the following * tokens the same as it was before. */ this._tree.insert(range[1], descriptorAfterRange); } /** * Gets the desired indent of a token * @param {Token} token The token * @returns {string} The desired indent of the token */ }, { key: "getDesiredIndent", value: function getDesiredIndent(token) { if (!this._desiredIndentCache.has(token)) { if (this._ignoredTokens.has(token)) { /* * If the token is ignored, use the actual indent of the token as the desired indent. * This ensures that no errors are reported for this token. */ this._desiredIndentCache.set(token, this._tokenInfo.getTokenIndent(token)); } else if (this._lockedFirstTokens.has(token)) { var firstToken = this._lockedFirstTokens.get(token); this._desiredIndentCache.set(token, // (indentation for the first element's line) this.getDesiredIndent(this._tokenInfo.getFirstTokenOfLine(firstToken)) + // (space between the start of the first element's line and the first element) this._indentType.repeat(firstToken.loc.start.column - this._tokenInfo.getFirstTokenOfLine(firstToken).loc.start.column)); } else { var offsetInfo = this._getOffsetDescriptor(token); var offset = offsetInfo.from && offsetInfo.from.loc.start.line === token.loc.start.line && !/^\s*?\n/.test(token.value) && !offsetInfo.force ? 0 : offsetInfo.offset * this._indentSize; this._desiredIndentCache.set(token, (offsetInfo.from ? this.getDesiredIndent(offsetInfo.from) : "") + this._indentType.repeat(offset)); } } return this._desiredIndentCache.get(token); } /** * Ignores a token, preventing it from being reported. * @param {Token} token The token * @returns {void} */ }, { key: "ignoreToken", value: function ignoreToken(token) { if (this._tokenInfo.isFirstTokenOfLine(token)) { this._ignoredTokens.add(token); } } /** * Gets the first token that the given token's indentation is dependent on * @param {Token} token The token * @returns {Token} The token that the given token depends on, or `null` if the given token is at the top level */ }, { key: "getFirstDependency", value: function getFirstDependency(token) { return this._getOffsetDescriptor(token).from; } }]); return OffsetStorage; }(); var ELEMENT_LIST_SCHEMA = { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["first", "off"] }] }; module.exports = { meta: { type: "layout", docs: { description: "enforce consistent indentation", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/indent" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["tab"] }, { type: "integer", minimum: 0 }] }, { type: "object", properties: { SwitchCase: { type: "integer", minimum: 0 }, VariableDeclarator: { oneOf: [ELEMENT_LIST_SCHEMA, { type: "object", properties: { var: ELEMENT_LIST_SCHEMA, let: ELEMENT_LIST_SCHEMA, const: ELEMENT_LIST_SCHEMA }, additionalProperties: false }] }, outerIIFEBody: { type: "integer", minimum: 0 }, MemberExpression: { oneOf: [{ type: "integer", minimum: 0 }, { enum: ["off"] }] }, FunctionDeclaration: { type: "object", properties: { parameters: ELEMENT_LIST_SCHEMA, body: { type: "integer", minimum: 0 } }, additionalProperties: false }, FunctionExpression: { type: "object", properties: { parameters: ELEMENT_LIST_SCHEMA, body: { type: "integer", minimum: 0 } }, additionalProperties: false }, CallExpression: { type: "object", properties: { arguments: ELEMENT_LIST_SCHEMA }, additionalProperties: false }, ArrayExpression: ELEMENT_LIST_SCHEMA, ObjectExpression: ELEMENT_LIST_SCHEMA, ImportDeclaration: ELEMENT_LIST_SCHEMA, flatTernaryExpressions: { type: "boolean" }, ignoredNodes: { type: "array", items: { type: "string", not: { pattern: ":exit$" } } }, ignoreComments: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var DEFAULT_VARIABLE_INDENT = 1; var DEFAULT_PARAMETER_INDENT = 1; var DEFAULT_FUNCTION_BODY_INDENT = 1; var indentType = "space"; var indentSize = 4; var options = { SwitchCase: 0, VariableDeclarator: { var: DEFAULT_VARIABLE_INDENT, let: DEFAULT_VARIABLE_INDENT, const: DEFAULT_VARIABLE_INDENT }, outerIIFEBody: 1, FunctionDeclaration: { parameters: DEFAULT_PARAMETER_INDENT, body: DEFAULT_FUNCTION_BODY_INDENT }, FunctionExpression: { parameters: DEFAULT_PARAMETER_INDENT, body: DEFAULT_FUNCTION_BODY_INDENT }, CallExpression: { arguments: DEFAULT_PARAMETER_INDENT }, MemberExpression: 1, ArrayExpression: 1, ObjectExpression: 1, ImportDeclaration: 1, flatTernaryExpressions: false, ignoredNodes: [], ignoreComments: false }; if (context.options.length) { if (context.options[0] === "tab") { indentSize = 1; indentType = "tab"; } else { indentSize = context.options[0]; indentType = "space"; } if (context.options[1]) { lodash.merge(options, context.options[1]); if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") { options.VariableDeclarator = { var: options.VariableDeclarator, let: options.VariableDeclarator, const: options.VariableDeclarator }; } } } var sourceCode = context.getSourceCode(); var tokenInfo = new TokenInfo(sourceCode); var offsets = new OffsetStorage(tokenInfo, indentSize, indentType === "space" ? " " : "\t"); var parameterParens = new WeakSet(); /** * Creates an error message for a line, given the expected/actual indentation. * @param {int} expectedAmount The expected amount of indentation characters for this line * @param {int} actualSpaces The actual number of indentation spaces that were found on this line * @param {int} actualTabs The actual number of indentation tabs that were found on this line * @returns {string} An error message for this line */ function createErrorMessage(expectedAmount, actualSpaces, actualTabs) { var expectedStatement = expectedAmount + " " + indentType + (expectedAmount === 1 ? "" : "s"); // e.g. "2 tabs" var foundSpacesWord = "space" + (actualSpaces === 1 ? "" : "s"); // e.g. "space" var foundTabsWord = "tab" + (actualTabs === 1 ? "" : "s"); // e.g. "tabs" var foundStatement = void 0; if (actualSpaces > 0) { /* * Abbreviate the message if the expected indentation is also spaces. * e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' */ foundStatement = indentType === "space" ? actualSpaces : actualSpaces + " " + foundSpacesWord; } else if (actualTabs > 0) { foundStatement = indentType === "tab" ? actualTabs : actualTabs + " " + foundTabsWord; } else { foundStatement = "0"; } return "Expected indentation of " + expectedStatement + " but found " + foundStatement + "."; } /** * Reports a given indent violation * @param {Token} token Token violating the indent rule * @param {string} neededIndent Expected indentation string * @returns {void} */ function report(token, neededIndent) { var actualIndent = Array.from(tokenInfo.getTokenIndent(token)); var numSpaces = actualIndent.filter(function (char) { return char === " "; }).length; var numTabs = actualIndent.filter(function (char) { return char === "\t"; }).length; context.report({ node: token, message: createErrorMessage(neededIndent.length, numSpaces, numTabs), loc: { start: { line: token.loc.start.line, column: 0 }, end: { line: token.loc.start.line, column: token.loc.start.column } }, fix: function fix(fixer) { var range = [token.range[0] - token.loc.start.column, token.range[0]]; var newText = neededIndent; return fixer.replaceTextRange(range, newText); } }); } /** * Checks if a token's indentation is correct * @param {Token} token Token to examine * @param {string} desiredIndent Desired indentation of the string * @returns {boolean} `true` if the token's indentation is correct */ function validateTokenIndent(token, desiredIndent) { var indentation = tokenInfo.getTokenIndent(token); return indentation === desiredIndent || // To avoid conflicts with no-mixed-spaces-and-tabs, don't report mixed spaces and tabs. indentation.includes(" ") && indentation.includes("\t"); } /** * Check to see if the node is a file level IIFE * @param {ASTNode} node The function node to check. * @returns {boolean} True if the node is the outer IIFE */ function isOuterIIFE(node) { /* * Verify that the node is an IIFE */ if (!node.parent || node.parent.type !== "CallExpression" || node.parent.callee !== node) { return false; } /* * Navigate legal ancestors to determine whether this IIFE is outer. * A "legal ancestor" is an expression or statement that causes the function to get executed immediately. * For example, `!(function(){})()` is an outer IIFE even though it is preceded by a ! operator. */ var statement = node.parent && node.parent.parent; while (statement.type === "UnaryExpression" && ["!", "~", "+", "-"].indexOf(statement.operator) > -1 || statement.type === "AssignmentExpression" || statement.type === "LogicalExpression" || statement.type === "SequenceExpression" || statement.type === "VariableDeclarator") { statement = statement.parent; } return (statement.type === "ExpressionStatement" || statement.type === "VariableDeclaration") && statement.parent.type === "Program"; } /** * Counts the number of linebreaks that follow the last non-whitespace character in a string * @param {string} string The string to check * @returns {number} The number of JavaScript linebreaks that follow the last non-whitespace character, * or the total number of linebreaks if the string is all whitespace. */ function countTrailingLinebreaks(string) { var trailingWhitespace = string.match(/\s*$/)[0]; var linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher()); return linebreakMatches === null ? 0 : linebreakMatches.length; } /** * Check indentation for lists of elements (arrays, objects, function params) * @param {ASTNode[]} elements List of elements that should be offset * @param {Token} startToken The start token of the list that element should be aligned against, e.g. '[' * @param {Token} endToken The end token of the list, e.g. ']' * @param {number|string} offset The amount that the elements should be offset * @returns {void} */ function addElementListIndent(elements, startToken, endToken, offset) { /** * Gets the first token of a given element, including surrounding parentheses. * @param {ASTNode} element A node in the `elements` list * @returns {Token} The first token of this element */ function getFirstToken(element) { var token = sourceCode.getTokenBefore(element); while (astUtils.isOpeningParenToken(token) && token !== startToken) { token = sourceCode.getTokenBefore(token); } return sourceCode.getTokenAfter(token); } // Run through all the tokens in the list, and offset them by one indent level (mainly for comments, other things will end up overridden) offsets.setDesiredOffsets([startToken.range[1], endToken.range[0]], startToken, typeof offset === "number" ? offset : 1); offsets.setDesiredOffset(endToken, startToken, 0); // If the preference is "first" but there is no first element (e.g. sparse arrays w/ empty first slot), fall back to 1 level. if (offset === "first" && elements.length && !elements[0]) { return; } elements.forEach(function (element, index) { if (!element) { // Skip holes in arrays return; } if (offset === "off") { // Ignore the first token of every element if the "off" option is used offsets.ignoreToken(getFirstToken(element)); } // Offset the following elements correctly relative to the first element if (index === 0) { return; } if (offset === "first" && tokenInfo.isFirstTokenOfLine(getFirstToken(element))) { offsets.matchOffsetOf(getFirstToken(elements[0]), getFirstToken(element)); } else { var previousElement = elements[index - 1]; var firstTokenOfPreviousElement = previousElement && getFirstToken(previousElement); var previousElementLastToken = previousElement && sourceCode.getLastToken(previousElement); if (previousElement && previousElementLastToken.loc.end.line - countTrailingLinebreaks(previousElementLastToken.value) > startToken.loc.end.line) { offsets.setDesiredOffsets([previousElement.range[1], element.range[1]], firstTokenOfPreviousElement, 0); } } }); } /** * Check and decide whether to check for indentation for blockless nodes * Scenarios are for or while statements without braces around them * @param {ASTNode} node node to examine * @returns {void} */ function addBlocklessNodeIndent(node) { if (node.type !== "BlockStatement") { var lastParentToken = sourceCode.getTokenBefore(node, astUtils.isNotOpeningParenToken); var firstBodyToken = sourceCode.getFirstToken(node); var lastBodyToken = sourceCode.getLastToken(node); while (astUtils.isOpeningParenToken(sourceCode.getTokenBefore(firstBodyToken)) && astUtils.isClosingParenToken(sourceCode.getTokenAfter(lastBodyToken))) { firstBodyToken = sourceCode.getTokenBefore(firstBodyToken); lastBodyToken = sourceCode.getTokenAfter(lastBodyToken); } offsets.setDesiredOffsets([firstBodyToken.range[0], lastBodyToken.range[1]], lastParentToken, 1); /* * For blockless nodes with semicolon-first style, don't indent the semicolon. * e.g. * if (foo) bar() * ; [1, 2, 3].map(foo) */ var lastToken = sourceCode.getLastToken(node); if (node.type !== "EmptyStatement" && astUtils.isSemicolonToken(lastToken)) { offsets.setDesiredOffset(lastToken, lastParentToken, 0); } } } /** * Checks the indentation for nodes that are like function calls (`CallExpression` and `NewExpression`) * @param {ASTNode} node A CallExpression or NewExpression node * @returns {void} */ function addFunctionCallIndent(node) { var openingParen = void 0; if (node.arguments.length) { openingParen = sourceCode.getFirstTokenBetween(node.callee, node.arguments[0], astUtils.isOpeningParenToken); } else { openingParen = sourceCode.getLastToken(node, 1); } var closingParen = sourceCode.getLastToken(node); parameterParens.add(openingParen); parameterParens.add(closingParen); offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0); addElementListIndent(node.arguments, openingParen, closingParen, options.CallExpression.arguments); } /** * Checks the indentation of parenthesized values, given a list of tokens in a program * @param {Token[]} tokens A list of tokens * @returns {void} */ function addParensIndent(tokens) { var parenStack = []; var parenPairs = []; tokens.forEach(function (nextToken) { // Accumulate a list of parenthesis pairs if (astUtils.isOpeningParenToken(nextToken)) { parenStack.push(nextToken); } else if (astUtils.isClosingParenToken(nextToken)) { parenPairs.unshift({ left: parenStack.pop(), right: nextToken }); } }); parenPairs.forEach(function (pair) { var leftParen = pair.left; var rightParen = pair.right; // We only want to handle parens around expressions, so exclude parentheses that are in function parameters and function call arguments. if (!parameterParens.has(leftParen) && !parameterParens.has(rightParen)) { var parenthesizedTokens = new Set(sourceCode.getTokensBetween(leftParen, rightParen)); parenthesizedTokens.forEach(function (token) { if (!parenthesizedTokens.has(offsets.getFirstDependency(token))) { offsets.setDesiredOffset(token, leftParen, 1); } }); } offsets.setDesiredOffset(rightParen, leftParen, 0); }); } /** * Ignore all tokens within an unknown node whose offset do not depend * on another token's offset within the unknown node * @param {ASTNode} node Unknown Node * @returns {void} */ function ignoreNode(node) { var unknownNodeTokens = new Set(sourceCode.getTokens(node, { includeComments: true })); unknownNodeTokens.forEach(function (token) { if (!unknownNodeTokens.has(offsets.getFirstDependency(token))) { var firstTokenOfLine = tokenInfo.getFirstTokenOfLine(token); if (token === firstTokenOfLine) { offsets.ignoreToken(token); } else { offsets.setDesiredOffset(token, firstTokenOfLine, 0); } } }); } /** * Check whether the given token is on the first line of a statement. * @param {Token} token The token to check. * @param {ASTNode} leafNode The expression node that the token belongs directly. * @returns {boolean} `true` if the token is on the first line of a statement. */ function isOnFirstLineOfStatement(token, leafNode) { var node = leafNode; while (node.parent && !node.parent.type.endsWith("Statement") && !node.parent.type.endsWith("Declaration")) { node = node.parent; } node = node.parent; return !node || node.loc.start.line === token.loc.start.line; } /** * Check whether there are any blank (whitespace-only) lines between * two tokens on separate lines. * @param {Token} firstToken The first token. * @param {Token} secondToken The second token. * @returns {boolean} `true` if the tokens are on separate lines and * there exists a blank line between them, `false` otherwise. */ function hasBlankLinesBetween(firstToken, secondToken) { var firstTokenLine = firstToken.loc.end.line; var secondTokenLine = secondToken.loc.start.line; if (firstTokenLine === secondTokenLine || firstTokenLine === secondTokenLine - 1) { return false; } for (var line = firstTokenLine + 1; line < secondTokenLine; ++line) { if (!tokenInfo.firstTokensByLineNumber.has(line)) { return true; } } return false; } var ignoredNodeFirstTokens = new Set(); var baseOffsetListeners = { "ArrayExpression, ArrayPattern": function ArrayExpressionArrayPattern(node) { var openingBracket = sourceCode.getFirstToken(node); var closingBracket = sourceCode.getTokenAfter(lodash.findLast(node.elements) || openingBracket, astUtils.isClosingBracketToken); addElementListIndent(node.elements, openingBracket, closingBracket, options.ArrayExpression); }, "ObjectExpression, ObjectPattern": function ObjectExpressionObjectPattern(node) { var openingCurly = sourceCode.getFirstToken(node); var closingCurly = sourceCode.getTokenAfter(node.properties.length ? node.properties[node.properties.length - 1] : openingCurly, astUtils.isClosingBraceToken); addElementListIndent(node.properties, openingCurly, closingCurly, options.ObjectExpression); }, ArrowFunctionExpression: function ArrowFunctionExpression(node) { var firstToken = sourceCode.getFirstToken(node); if (astUtils.isOpeningParenToken(firstToken)) { var openingParen = firstToken; var closingParen = sourceCode.getTokenBefore(node.body, astUtils.isClosingParenToken); parameterParens.add(openingParen); parameterParens.add(closingParen); addElementListIndent(node.params, openingParen, closingParen, options.FunctionExpression.parameters); } addBlocklessNodeIndent(node.body); }, AssignmentExpression: function AssignmentExpression(node) { var operator = sourceCode.getFirstTokenBetween(node.left, node.right, function (token) { return token.value === node.operator; }); offsets.setDesiredOffsets([operator.range[0], node.range[1]], sourceCode.getLastToken(node.left), 1); offsets.ignoreToken(operator); offsets.ignoreToken(sourceCode.getTokenAfter(operator)); }, "BinaryExpression, LogicalExpression": function BinaryExpressionLogicalExpression(node) { var operator = sourceCode.getFirstTokenBetween(node.left, node.right, function (token) { return token.value === node.operator; }); /* * For backwards compatibility, don't check BinaryExpression indents, e.g. * var foo = bar && * baz; */ var tokenAfterOperator = sourceCode.getTokenAfter(operator); offsets.ignoreToken(operator); offsets.ignoreToken(tokenAfterOperator); offsets.setDesiredOffset(tokenAfterOperator, operator, 0); }, "BlockStatement, ClassBody": function BlockStatementClassBody(node) { var blockIndentLevel = void 0; if (node.parent && isOuterIIFE(node.parent)) { blockIndentLevel = options.outerIIFEBody; } else if (node.parent && (node.parent.type === "FunctionExpression" || node.parent.type === "ArrowFunctionExpression")) { blockIndentLevel = options.FunctionExpression.body; } else if (node.parent && node.parent.type === "FunctionDeclaration") { blockIndentLevel = options.FunctionDeclaration.body; } else { blockIndentLevel = 1; } /* * For blocks that aren't lone statements, ensure that the opening curly brace * is aligned with the parent. */ if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { offsets.setDesiredOffset(sourceCode.getFirstToken(node), sourceCode.getFirstToken(node.parent), 0); } addElementListIndent(node.body, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), blockIndentLevel); }, CallExpression: addFunctionCallIndent, "ClassDeclaration[superClass], ClassExpression[superClass]": function ClassDeclarationSuperClassClassExpressionSuperClass(node) { var classToken = sourceCode.getFirstToken(node); var extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken); offsets.setDesiredOffsets([extendsToken.range[0], node.body.range[0]], classToken, 1); }, ConditionalExpression: function ConditionalExpression(node) { var firstToken = sourceCode.getFirstToken(node); // `flatTernaryExpressions` option is for the following style: // var a = // foo > 0 ? bar : // foo < 0 ? baz : // /*else*/ qiz ; if (!options.flatTernaryExpressions || !astUtils.isTokenOnSameLine(node.test, node.consequent) || isOnFirstLineOfStatement(firstToken, node)) { var questionMarkToken = sourceCode.getFirstTokenBetween(node.test, node.consequent, function (token) { return token.type === "Punctuator" && token.value === "?"; }); var colonToken = sourceCode.getFirstTokenBetween(node.consequent, node.alternate, function (token) { return token.type === "Punctuator" && token.value === ":"; }); var firstConsequentToken = sourceCode.getTokenAfter(questionMarkToken); var lastConsequentToken = sourceCode.getTokenBefore(colonToken); var firstAlternateToken = sourceCode.getTokenAfter(colonToken); offsets.setDesiredOffset(questionMarkToken, firstToken, 1); offsets.setDesiredOffset(colonToken, firstToken, 1); offsets.setDesiredOffset(firstConsequentToken, firstToken, 1); /* * The alternate and the consequent should usually have the same indentation. * If they share part of a line, align the alternate against the first token of the consequent. * This allows the alternate to be indented correctly in cases like this: * foo ? ( * bar * ) : ( // this '(' is aligned with the '(' above, so it's considered to be aligned with `foo` * baz // as a result, `baz` is offset by 1 rather than 2 * ) */ if (lastConsequentToken.loc.end.line === firstAlternateToken.loc.start.line) { offsets.setDesiredOffset(firstAlternateToken, firstConsequentToken, 0); } else { /** * If the alternate and consequent do not share part of a line, offset the alternate from the first * token of the conditional expression. For example: * foo ? bar * : baz * * If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up * having no expected indentation. */ offsets.setDesiredOffset(firstAlternateToken, firstToken, 1); } } }, "DoWhileStatement, WhileStatement, ForInStatement, ForOfStatement": function DoWhileStatementWhileStatementForInStatementForOfStatement(node) { return addBlocklessNodeIndent(node.body); }, ExportNamedDeclaration: function ExportNamedDeclaration(node) { if (node.declaration === null) { var closingCurly = sourceCode.getLastToken(node, astUtils.isClosingBraceToken); // Indent the specifiers in `export {foo, bar, baz}` addElementListIndent(node.specifiers, sourceCode.getFirstToken(node, { skip: 1 }), closingCurly, 1); if (node.source) { // Indent everything after and including the `from` token in `export {foo, bar, baz} from 'qux'` offsets.setDesiredOffsets([closingCurly.range[1], node.range[1]], sourceCode.getFirstToken(node), 1); } } }, ForStatement: function ForStatement(node) { var forOpeningParen = sourceCode.getFirstToken(node, 1); if (node.init) { offsets.setDesiredOffsets(node.init.range, forOpeningParen, 1); } if (node.test) { offsets.setDesiredOffsets(node.test.range, forOpeningParen, 1); } if (node.update) { offsets.setDesiredOffsets(node.update.range, forOpeningParen, 1); } addBlocklessNodeIndent(node.body); }, "FunctionDeclaration, FunctionExpression": function FunctionDeclarationFunctionExpression(node) { var closingParen = sourceCode.getTokenBefore(node.body); var openingParen = sourceCode.getTokenBefore(node.params.length ? node.params[0] : closingParen); parameterParens.add(openingParen); parameterParens.add(closingParen); addElementListIndent(node.params, openingParen, closingParen, options[node.type].parameters); }, IfStatement: function IfStatement(node) { addBlocklessNodeIndent(node.consequent); if (node.alternate && node.alternate.type !== "IfStatement") { addBlocklessNodeIndent(node.alternate); } }, ImportDeclaration: function ImportDeclaration(node) { if (node.specifiers.some(function (specifier) { return specifier.type === "ImportSpecifier"; })) { var openingCurly = sourceCode.getFirstToken(node, astUtils.isOpeningBraceToken); var closingCurly = sourceCode.getLastToken(node, astUtils.isClosingBraceToken); addElementListIndent(node.specifiers.filter(function (specifier) { return specifier.type === "ImportSpecifier"; }), openingCurly, closingCurly, options.ImportDeclaration); } var fromToken = sourceCode.getLastToken(node, function (token) { return token.type === "Identifier" && token.value === "from"; }); var sourceToken = sourceCode.getLastToken(node, function (token) { return token.type === "String"; }); var semiToken = sourceCode.getLastToken(node, function (token) { return token.type === "Punctuator" && token.value === ";"; }); if (fromToken) { var end = semiToken && semiToken.range[1] === sourceToken.range[1] ? node.range[1] : sourceToken.range[1]; offsets.setDesiredOffsets([fromToken.range[0], end], sourceCode.getFirstToken(node), 1); } }, "MemberExpression, JSXMemberExpression, MetaProperty": function MemberExpressionJSXMemberExpressionMetaProperty(node) { var object = node.type === "MetaProperty" ? node.meta : node.object; var firstNonObjectToken = sourceCode.getFirstTokenBetween(object, node.property, astUtils.isNotClosingParenToken); var secondNonObjectToken = sourceCode.getTokenAfter(firstNonObjectToken); var objectParenCount = sourceCode.getTokensBetween(object, node.property, { filter: astUtils.isClosingParenToken }).length; var firstObjectToken = objectParenCount ? sourceCode.getTokenBefore(object, { skip: objectParenCount - 1 }) : sourceCode.getFirstToken(object); var lastObjectToken = sourceCode.getTokenBefore(firstNonObjectToken); var firstPropertyToken = node.computed ? firstNonObjectToken : secondNonObjectToken; if (node.computed) { // For computed MemberExpressions, match the closing bracket with the opening bracket. offsets.setDesiredOffset(sourceCode.getLastToken(node), firstNonObjectToken, 0); offsets.setDesiredOffsets(node.property.range, firstNonObjectToken, 1); } /* * If the object ends on the same line that the property starts, match against the last token * of the object, to ensure that the MemberExpression is not indented. * * Otherwise, match against the first token of the object, e.g. * foo * .bar * .baz // <-- offset by 1 from `foo` */ var offsetBase = lastObjectToken.loc.end.line === firstPropertyToken.loc.start.line ? lastObjectToken : firstObjectToken; if (typeof options.MemberExpression === "number") { // Match the dot (for non-computed properties) or the opening bracket (for computed properties) against the object. offsets.setDesiredOffset(firstNonObjectToken, offsetBase, options.MemberExpression); /* * For computed MemberExpressions, match the first token of the property against the opening bracket. * Otherwise, match the first token of the property against the object. */ offsets.setDesiredOffset(secondNonObjectToken, node.computed ? firstNonObjectToken : offsetBase, options.MemberExpression); } else { // If the MemberExpression option is off, ignore the dot and the first token of the property. offsets.ignoreToken(firstNonObjectToken); offsets.ignoreToken(secondNonObjectToken); // To ignore the property indentation, ensure that the property tokens depend on the ignored tokens. offsets.setDesiredOffset(firstNonObjectToken, offsetBase, 0); offsets.setDesiredOffset(secondNonObjectToken, firstNonObjectToken, 0); } }, NewExpression: function NewExpression(node) { // Only indent the arguments if the NewExpression has parens (e.g. `new Foo(bar)` or `new Foo()`, but not `new Foo` if (node.arguments.length > 0 || astUtils.isClosingParenToken(sourceCode.getLastToken(node)) && astUtils.isOpeningParenToken(sourceCode.getLastToken(node, 1))) { addFunctionCallIndent(node); } }, Property: function Property(node) { if (!node.shorthand && !node.method && node.kind === "init") { var colon = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isColonToken); offsets.ignoreToken(sourceCode.getTokenAfter(colon)); } }, SwitchStatement: function SwitchStatement(node) { var openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken); var closingCurly = sourceCode.getLastToken(node); offsets.setDesiredOffsets([openingCurly.range[1], closingCurly.range[0]], openingCurly, options.SwitchCase); if (node.cases.length) { sourceCode.getTokensBetween(node.cases[node.cases.length - 1], closingCurly, { includeComments: true, filter: astUtils.isCommentToken }).forEach(function (token) { return offsets.ignoreToken(token); }); } }, SwitchCase: function SwitchCase(node) { if (!(node.consequent.length === 1 && node.consequent[0].type === "BlockStatement")) { var caseKeyword = sourceCode.getFirstToken(node); var tokenAfterCurrentCase = sourceCode.getTokenAfter(node); offsets.setDesiredOffsets([caseKeyword.range[1], tokenAfterCurrentCase.range[0]], caseKeyword, 1); } }, TemplateLiteral: function TemplateLiteral(node) { node.expressions.forEach(function (expression, index) { var previousQuasi = node.quasis[index]; var nextQuasi = node.quasis[index + 1]; var tokenToAlignFrom = previousQuasi.loc.start.line === previousQuasi.loc.end.line ? sourceCode.getFirstToken(previousQuasi) : null; offsets.setDesiredOffsets([previousQuasi.range[1], nextQuasi.range[0]], tokenToAlignFrom, 1); offsets.setDesiredOffset(sourceCode.getFirstToken(nextQuasi), tokenToAlignFrom, 0); }); }, VariableDeclaration: function VariableDeclaration(node) { var variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind) ? options.VariableDeclarator[node.kind] : DEFAULT_VARIABLE_INDENT; var firstToken = sourceCode.getFirstToken(node), lastToken = sourceCode.getLastToken(node); if (options.VariableDeclarator[node.kind] === "first") { if (node.declarations.length > 1) { addElementListIndent(node.declarations, firstToken, lastToken, "first"); return; } variableIndent = DEFAULT_VARIABLE_INDENT; } if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) { /* * VariableDeclarator indentation is a bit different from other forms of indentation, in that the * indentation of an opening bracket sometimes won't match that of a closing bracket. For example, * the following indentations are correct: * * var foo = { * ok: true * }; * * var foo = { * ok: true, * }, * bar = 1; * * Account for when exiting the AST (after indentations have already been set for the nodes in * the declaration) by manually increasing the indentation level of the tokens in this declarator * on the same line as the start of the declaration, provided that there are declarators that * follow this one. */ offsets.setDesiredOffsets(node.range, firstToken, variableIndent, true); } else { offsets.setDesiredOffsets(node.range, firstToken, variableIndent); } if (astUtils.isSemicolonToken(lastToken)) { offsets.ignoreToken(lastToken); } }, VariableDeclarator: function VariableDeclarator(node) { if (node.init) { var equalOperator = sourceCode.getTokenBefore(node.init, astUtils.isNotOpeningParenToken); var tokenAfterOperator = sourceCode.getTokenAfter(equalOperator); offsets.ignoreToken(equalOperator); offsets.ignoreToken(tokenAfterOperator); offsets.setDesiredOffsets([tokenAfterOperator.range[0], node.range[1]], equalOperator, 1); offsets.setDesiredOffset(equalOperator, sourceCode.getLastToken(node.id), 0); } }, "JSXAttribute[value]": function JSXAttributeValue(node) { var equalsToken = sourceCode.getFirstTokenBetween(node.name, node.value, function (token) { return token.type === "Punctuator" && token.value === "="; }); offsets.setDesiredOffsets([equalsToken.range[0], node.value.range[1]], sourceCode.getFirstToken(node.name), 1); }, JSXElement: function JSXElement(node) { if (node.closingElement) { addElementListIndent(node.children, sourceCode.getFirstToken(node.openingElement), sourceCode.getFirstToken(node.closingElement), 1); } }, JSXOpeningElement: function JSXOpeningElement(node) { var firstToken = sourceCode.getFirstToken(node); var closingToken = void 0; if (node.selfClosing) { closingToken = sourceCode.getLastToken(node, { skip: 1 }); offsets.setDesiredOffset(sourceCode.getLastToken(node), closingToken, 0); } else { closingToken = sourceCode.getLastToken(node); } offsets.setDesiredOffsets(node.name.range, sourceCode.getFirstToken(node)); addElementListIndent(node.attributes, firstToken, closingToken, 1); }, JSXClosingElement: function JSXClosingElement(node) { var firstToken = sourceCode.getFirstToken(node); offsets.setDesiredOffsets(node.name.range, firstToken, 1); }, JSXExpressionContainer: function JSXExpressionContainer(node) { var openingCurly = sourceCode.getFirstToken(node); var closingCurly = sourceCode.getLastToken(node); offsets.setDesiredOffsets([openingCurly.range[1], closingCurly.range[0]], openingCurly, 1); }, "*": function _(node) { var firstToken = sourceCode.getFirstToken(node); // Ensure that the children of every node are indented at least as much as the first token. if (firstToken && !ignoredNodeFirstTokens.has(firstToken)) { offsets.setDesiredOffsets(node.range, firstToken, 0); } } }; var listenerCallQueue = []; /* * To ignore the indentation of a node: * 1. Don't call the node's listener when entering it (if it has a listener) * 2. Don't set any offsets against the first token of the node. * 3. Call `ignoreNode` on the node sometime after exiting it and before validating offsets. */ var offsetListeners = lodash.mapValues(baseOffsetListeners, /* * Offset listener calls are deferred until traversal is finished, and are called as * part of the final `Program:exit` listener. This is necessary because a node might * be matched by multiple selectors. * * Example: Suppose there is an offset listener for `Identifier`, and the user has * specified in configuration that `MemberExpression > Identifier` should be ignored. * Due to selector specificity rules, the `Identifier` listener will get called first. However, * if a given Identifier node is supposed to be ignored, then the `Identifier` offset listener * should not have been called at all. Without doing extra selector matching, we don't know * whether the Identifier matches the `MemberExpression > Identifier` selector until the * `MemberExpression > Identifier` listener is called. * * To avoid this, the `Identifier` listener isn't called until traversal finishes and all * ignored nodes are known. */ function (listener) { return function (node) { return listenerCallQueue.push({ listener: listener, node: node }); }; }); // For each ignored node selector, set up a listener to collect it into the `ignoredNodes` set. var ignoredNodes = new Set(); /** * Ignores a node * @param {ASTNode} node The node to ignore * @returns {void} */ function addToIgnoredNodes(node) { ignoredNodes.add(node); ignoredNodeFirstTokens.add(sourceCode.getFirstToken(node)); } var ignoredNodeListeners = options.ignoredNodes.reduce(function (listeners, ignoredSelector) { return Object.assign(listeners, _defineProperty({}, ignoredSelector, addToIgnoredNodes)); }, {}); /* * Join the listeners, and add a listener to verify that all tokens actually have the correct indentation * at the end. * * Using Object.assign will cause some offset listeners to be overwritten if the same selector also appears * in `ignoredNodeListeners`. This isn't a problem because all of the matching nodes will be ignored, * so those listeners wouldn't be called anyway. */ return Object.assign(offsetListeners, ignoredNodeListeners, { "*:exit": function exit(node) { // If a node's type is nonstandard, we can't tell how its children should be offset, so ignore it. if (!KNOWN_NODES.has(node.type)) { addToIgnoredNodes(node); } }, "Program:exit": function ProgramExit() { // If ignoreComments option is enabled, ignore all comment tokens. if (options.ignoreComments) { sourceCode.getAllComments().forEach(function (comment) { return offsets.ignoreToken(comment); }); } // Invoke the queued offset listeners for the nodes that aren't ignored. listenerCallQueue.filter(function (nodeInfo) { return !ignoredNodes.has(nodeInfo.node); }).forEach(function (nodeInfo) { return nodeInfo.listener(nodeInfo.node); }); // Update the offsets for ignored nodes to prevent their child tokens from being reported. ignoredNodes.forEach(ignoreNode); addParensIndent(sourceCode.ast.tokens); /* * Create a Map from (tokenOrComment) => (precedingToken). * This is necessary because sourceCode.getTokenBefore does not handle a comment as an argument correctly. */ var precedingTokens = sourceCode.ast.comments.reduce(function (commentMap, comment) { var tokenOrCommentBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); return commentMap.set(comment, commentMap.has(tokenOrCommentBefore) ? commentMap.get(tokenOrCommentBefore) : tokenOrCommentBefore); }, new WeakMap()); sourceCode.lines.forEach(function (line, lineIndex) { var lineNumber = lineIndex + 1; if (!tokenInfo.firstTokensByLineNumber.has(lineNumber)) { // Don't check indentation on blank lines return; } var firstTokenOfLine = tokenInfo.firstTokensByLineNumber.get(lineNumber); if (firstTokenOfLine.loc.start.line !== lineNumber) { // Don't check the indentation of multi-line tokens (e.g. template literals or block comments) twice. return; } // If the token matches the expected expected indentation, don't report it. if (validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(firstTokenOfLine))) { return; } if (astUtils.isCommentToken(firstTokenOfLine)) { var tokenBefore = precedingTokens.get(firstTokenOfLine); var tokenAfter = tokenBefore ? sourceCode.getTokenAfter(tokenBefore) : sourceCode.ast.tokens[0]; var mayAlignWithBefore = tokenBefore && !hasBlankLinesBetween(tokenBefore, firstTokenOfLine); var mayAlignWithAfter = tokenAfter && !hasBlankLinesBetween(firstTokenOfLine, tokenAfter); // If a comment matches the expected indentation of the token immediately before or after, don't report it. if (mayAlignWithBefore && validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(tokenBefore)) || mayAlignWithAfter && validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(tokenAfter))) { return; } } // Otherwise, report the token/comment. report(firstTokenOfLine, offsets.getDesiredIndent(firstTokenOfLine)); }); } }); } }; },{"../util/ast-utils":405,"functional-red-black-tree":83,"lodash":92}],171:[function(require,module,exports){ /** * @fileoverview A rule to control the style of variable initializations. * @author Colin Ihrig */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is a for loop. * @param {ASTNode} block - A node to check. * @returns {boolean} `true` when the node is a for loop. */ function isForLoop(block) { return block.type === "ForInStatement" || block.type === "ForOfStatement" || block.type === "ForStatement"; } /** * Checks whether or not a given declarator node has its initializer. * @param {ASTNode} node - A declarator node to check. * @returns {boolean} `true` when the node has its initializer. */ function isInitialized(node) { var declaration = node.parent; var block = declaration.parent; if (isForLoop(block)) { if (block.type === "ForStatement") { return block.init === declaration; } return block.left === declaration; } return Boolean(node.init); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow initialization in variable declarations", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/init-declarations" }, schema: { anyOf: [{ type: "array", items: [{ enum: ["always"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["never"] }, { type: "object", properties: { ignoreForLoopInit: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] } }, create: function create(context) { var MODE_ALWAYS = "always", MODE_NEVER = "never"; var mode = context.options[0] || MODE_ALWAYS; var params = context.options[1] || {}; //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { "VariableDeclaration:exit": function VariableDeclarationExit(node) { var kind = node.kind, declarations = node.declarations; for (var i = 0; i < declarations.length; ++i) { var declaration = declarations[i], id = declaration.id, initialized = isInitialized(declaration), isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); if (id.type !== "Identifier") { continue; } if (mode === MODE_ALWAYS && !initialized) { context.report({ node: declaration, message: "Variable '{{idName}}' should be initialized on declaration.", data: { idName: id.name } }); } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) { context.report({ node: declaration, message: "Variable '{{idName}}' should not be initialized on declaration.", data: { idName: id.name } }); } } } }; } }; },{}],172:[function(require,module,exports){ /** * @fileoverview A rule to ensure consistent quotes used in jsx syntax. * @author Mathias Schreck */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ var QUOTE_SETTINGS = { "prefer-double": { quote: "\"", description: "singlequote", convert: function convert(str) { return str.replace(/'/g, "\""); } }, "prefer-single": { quote: "'", description: "doublequote", convert: function convert(str) { return str.replace(/"/g, "'"); } } }; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce the consistent use of either double or single quotes in JSX attributes", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/jsx-quotes" }, fixable: "whitespace", schema: [{ enum: ["prefer-single", "prefer-double"] }] }, create: function create(context) { var quoteOption = context.options[0] || "prefer-double", setting = QUOTE_SETTINGS[quoteOption]; /** * Checks if the given string literal node uses the expected quotes * @param {ASTNode} node - A string literal node. * @returns {boolean} Whether or not the string literal used the expected quotes. * @public */ function usesExpectedQuotes(node) { return node.value.indexOf(setting.quote) !== -1 || astUtils.isSurroundedBy(node.raw, setting.quote); } return { JSXAttribute: function JSXAttribute(node) { var attributeValue = node.value; if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { context.report({ node: attributeValue, message: "Unexpected usage of {{description}}.", data: { description: setting.description }, fix: function fix(fixer) { return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); } }); } } }; } }; },{"../util/ast-utils":405}],173:[function(require,module,exports){ /** * @fileoverview Rule to specify spacing of object literal keys and values * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether a string contains a line terminator as defined in * http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 * @param {string} str String to test. * @returns {boolean} True if str contains a line terminator. */ function containsLineTerminator(str) { return astUtils.LINEBREAK_MATCHER.test(str); } /** * Gets the last element of an array. * @param {Array} arr An array. * @returns {any} Last element of arr. */ function last(arr) { return arr[arr.length - 1]; } /** * Checks whether a node is contained on a single line. * @param {ASTNode} node AST Node being evaluated. * @returns {boolean} True if the node is a single line. */ function isSingleLine(node) { return node.loc.end.line === node.loc.start.line; } /** * Initializes a single option property from the configuration with defaults for undefined values * @param {Object} toOptions Object to be initialized * @param {Object} fromOptions Object to be initialized from * @returns {Object} The object with correctly initialized options and values */ function initOptionProperty(toOptions, fromOptions) { toOptions.mode = fromOptions.mode || "strict"; // Set value of beforeColon if (typeof fromOptions.beforeColon !== "undefined") { toOptions.beforeColon = +fromOptions.beforeColon; } else { toOptions.beforeColon = 0; } // Set value of afterColon if (typeof fromOptions.afterColon !== "undefined") { toOptions.afterColon = +fromOptions.afterColon; } else { toOptions.afterColon = 1; } // Set align if exists if (typeof fromOptions.align !== "undefined") { if (_typeof(fromOptions.align) === "object") { toOptions.align = fromOptions.align; } else { // "string" toOptions.align = { on: fromOptions.align, mode: toOptions.mode, beforeColon: toOptions.beforeColon, afterColon: toOptions.afterColon }; } } return toOptions; } /** * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values * @param {Object} toOptions Object to be initialized * @param {Object} fromOptions Object to be initialized from * @returns {Object} The object with correctly initialized options and values */ function initOptions(toOptions, fromOptions) { if (_typeof(fromOptions.align) === "object") { // Initialize the alignment configuration toOptions.align = initOptionProperty({}, fromOptions.align); toOptions.align.on = fromOptions.align.on || "colon"; toOptions.align.mode = fromOptions.align.mode || "strict"; toOptions.multiLine = initOptionProperty({}, fromOptions.multiLine || fromOptions); toOptions.singleLine = initOptionProperty({}, fromOptions.singleLine || fromOptions); } else { // string or undefined toOptions.multiLine = initOptionProperty({}, fromOptions.multiLine || fromOptions); toOptions.singleLine = initOptionProperty({}, fromOptions.singleLine || fromOptions); // If alignment options are defined in multiLine, pull them out into the general align configuration if (toOptions.multiLine.align) { toOptions.align = { on: toOptions.multiLine.align.on, mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode, beforeColon: toOptions.multiLine.align.beforeColon, afterColon: toOptions.multiLine.align.afterColon }; } } return toOptions; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var messages = { key: "{{error}} space after {{computed}}key '{{key}}'.", value: "{{error}} space before value for {{computed}}key '{{key}}'." }; module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing between keys and values in object literal properties", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/key-spacing" }, fixable: "whitespace", schema: [{ anyOf: [{ type: "object", properties: { align: { anyOf: [{ enum: ["colon", "value"] }, { type: "object", properties: { mode: { enum: ["strict", "minimum"] }, on: { enum: ["colon", "value"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false }] }, mode: { enum: ["strict", "minimum"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false }, { type: "object", properties: { singleLine: { type: "object", properties: { mode: { enum: ["strict", "minimum"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false }, multiLine: { type: "object", properties: { align: { anyOf: [{ enum: ["colon", "value"] }, { type: "object", properties: { mode: { enum: ["strict", "minimum"] }, on: { enum: ["colon", "value"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false }] }, mode: { enum: ["strict", "minimum"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false } }, additionalProperties: false }, { type: "object", properties: { singleLine: { type: "object", properties: { mode: { enum: ["strict", "minimum"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false }, multiLine: { type: "object", properties: { mode: { enum: ["strict", "minimum"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false }, align: { type: "object", properties: { mode: { enum: ["strict", "minimum"] }, on: { enum: ["colon", "value"] }, beforeColon: { type: "boolean" }, afterColon: { type: "boolean" } }, additionalProperties: false } }, additionalProperties: false }] }] }, create: function create(context) { /** * OPTIONS * "key-spacing": [2, { * beforeColon: false, * afterColon: true, * align: "colon" // Optional, or "value" * } */ var options = context.options[0] || {}, ruleOptions = initOptions({}, options), multiLineOptions = ruleOptions.multiLine, singleLineOptions = ruleOptions.singleLine, alignmentOptions = ruleOptions.align || null; var sourceCode = context.getSourceCode(); /** * Checks whether a property is a member of the property group it follows. * @param {ASTNode} lastMember The last Property known to be in the group. * @param {ASTNode} candidate The next Property that might be in the group. * @returns {boolean} True if the candidate property is part of the group. */ function continuesPropertyGroup(lastMember, candidate) { var groupEndLine = lastMember.loc.start.line, candidateStartLine = candidate.loc.start.line; if (candidateStartLine - groupEndLine <= 1) { return true; } /* * Check that the first comment is adjacent to the end of the group, the * last comment is adjacent to the candidate property, and that successive * comments are adjacent to each other. */ var leadingComments = sourceCode.getCommentsBefore(candidate); if (leadingComments.length && leadingComments[0].loc.start.line - groupEndLine <= 1 && candidateStartLine - last(leadingComments).loc.end.line <= 1) { for (var i = 1; i < leadingComments.length; i++) { if (leadingComments[i].loc.start.line - leadingComments[i - 1].loc.end.line > 1) { return false; } } return true; } return false; } /** * Determines if the given property is key-value property. * @param {ASTNode} property Property node to check. * @returns {boolean} Whether the property is a key-value property. */ function isKeyValueProperty(property) { return !(property.method || property.shorthand || property.kind !== "init" || property.type !== "Property"); } /** * Starting from the given a node (a property.key node here) looks forward * until it finds the last token before a colon punctuator and returns it. * @param {ASTNode} node The node to start looking from. * @returns {ASTNode} The last token before a colon punctuator. */ function getLastTokenBeforeColon(node) { var colonToken = sourceCode.getTokenAfter(node, astUtils.isColonToken); return sourceCode.getTokenBefore(colonToken); } /** * Starting from the given a node (a property.key node here) looks forward * until it finds the colon punctuator and returns it. * @param {ASTNode} node The node to start looking from. * @returns {ASTNode} The colon punctuator. */ function getNextColon(node) { return sourceCode.getTokenAfter(node, astUtils.isColonToken); } /** * Gets an object literal property's key as the identifier name or string value. * @param {ASTNode} property Property node whose key to retrieve. * @returns {string} The property's key. */ function getKey(property) { var key = property.key; if (property.computed) { return sourceCode.getText().slice(key.range[0], key.range[1]); } return property.key.name || property.key.value; } /** * Reports an appropriately-formatted error if spacing is incorrect on one * side of the colon. * @param {ASTNode} property Key-value pair in an object literal. * @param {string} side Side being verified - either "key" or "value". * @param {string} whitespace Actual whitespace string. * @param {int} expected Expected whitespace length. * @param {string} mode Value of the mode as "strict" or "minimum" * @returns {void} */ function report(property, side, whitespace, expected, mode) { var diff = whitespace.length - expected, nextColon = getNextColon(property.key), tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }), tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }), isKeySide = side === "key", locStart = isKeySide ? tokenBeforeColon.loc.start : tokenAfterColon.loc.start, isExtra = diff > 0, diffAbs = Math.abs(diff), spaces = Array(diffAbs + 1).join(" "); if ((diff && mode === "strict" || diff < 0 && mode === "minimum" || diff > 0 && !expected && mode === "minimum") && !(expected && containsLineTerminator(whitespace))) { var fix = void 0; if (isExtra) { var range = void 0; // Remove whitespace if (isKeySide) { range = [tokenBeforeColon.range[1], tokenBeforeColon.range[1] + diffAbs]; } else { range = [tokenAfterColon.range[0] - diffAbs, tokenAfterColon.range[0]]; } fix = function fix(fixer) { return fixer.removeRange(range); }; } else { // Add whitespace if (isKeySide) { fix = function fix(fixer) { return fixer.insertTextAfter(tokenBeforeColon, spaces); }; } else { fix = function fix(fixer) { return fixer.insertTextBefore(tokenAfterColon, spaces); }; } } context.report({ node: property[side], loc: locStart, message: messages[side], data: { error: isExtra ? "Extra" : "Missing", computed: property.computed ? "computed " : "", key: getKey(property) }, fix: fix }); } } /** * Gets the number of characters in a key, including quotes around string * keys and braces around computed property keys. * @param {ASTNode} property Property of on object literal. * @returns {int} Width of the key. */ function getKeyWidth(property) { var startToken = sourceCode.getFirstToken(property); var endToken = getLastTokenBeforeColon(property.key); return endToken.range[1] - startToken.range[0]; } /** * Gets the whitespace around the colon in an object literal property. * @param {ASTNode} property Property node from an object literal. * @returns {Object} Whitespace before and after the property's colon. */ function getPropertyWhitespace(property) { var whitespace = /(\s*):(\s*)/.exec(sourceCode.getText().slice(property.key.range[1], property.value.range[0])); if (whitespace) { return { beforeColon: whitespace[1], afterColon: whitespace[2] }; } return null; } /** * Creates groups of properties. * @param {ASTNode} node ObjectExpression node being evaluated. * @returns {Array.} Groups of property AST node lists. */ function createGroups(node) { if (node.properties.length === 1) { return [node.properties]; } return node.properties.reduce(function (groups, property) { var currentGroup = last(groups), prev = last(currentGroup); if (!prev || continuesPropertyGroup(prev, property)) { currentGroup.push(property); } else { groups.push([property]); } return groups; }, [[]]); } /** * Verifies correct vertical alignment of a group of properties. * @param {ASTNode[]} properties List of Property AST nodes. * @returns {void} */ function verifyGroupAlignment(properties) { var length = properties.length, widths = properties.map(getKeyWidth), // Width of keys, including quotes align = alignmentOptions.on; // "value" or "colon" var targetWidth = Math.max.apply(Math, _toConsumableArray(widths)), beforeColon = void 0, afterColon = void 0, mode = void 0; if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration. beforeColon = alignmentOptions.beforeColon; afterColon = alignmentOptions.afterColon; mode = alignmentOptions.mode; } else { beforeColon = multiLineOptions.beforeColon; afterColon = multiLineOptions.afterColon; mode = alignmentOptions.mode; } // Conditionally include one space before or after colon targetWidth += align === "colon" ? beforeColon : afterColon; for (var i = 0; i < length; i++) { var property = properties[i]; var whitespace = getPropertyWhitespace(property); if (whitespace) { // Object literal getters/setters lack a colon var width = widths[i]; if (align === "value") { report(property, "key", whitespace.beforeColon, beforeColon, mode); report(property, "value", whitespace.afterColon, targetWidth - width, mode); } else { // align = "colon" report(property, "key", whitespace.beforeColon, targetWidth - width, mode); report(property, "value", whitespace.afterColon, afterColon, mode); } } } } /** * Verifies vertical alignment, taking into account groups of properties. * @param {ASTNode} node ObjectExpression node being evaluated. * @returns {void} */ function verifyAlignment(node) { createGroups(node).forEach(function (group) { verifyGroupAlignment(group.filter(isKeyValueProperty)); }); } /** * Verifies spacing of property conforms to specified options. * @param {ASTNode} node Property node being evaluated. * @param {Object} lineOptions Configured singleLine or multiLine options * @returns {void} */ function verifySpacing(node, lineOptions) { var actual = getPropertyWhitespace(node); if (actual) { // Object literal getters/setters lack colons report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode); report(node, "value", actual.afterColon, lineOptions.afterColon, lineOptions.mode); } } /** * Verifies spacing of each property in a list. * @param {ASTNode[]} properties List of Property AST nodes. * @returns {void} */ function verifyListSpacing(properties) { var length = properties.length; for (var i = 0; i < length; i++) { verifySpacing(properties[i], singleLineOptions); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- if (alignmentOptions) { // Verify vertical alignment return { ObjectExpression: function ObjectExpression(node) { if (isSingleLine(node)) { verifyListSpacing(node.properties.filter(isKeyValueProperty)); } else { verifyAlignment(node); } } }; } // Obey beforeColon and afterColon in each property as configured return { Property: function Property(node) { verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); } }; } }; },{"../util/ast-utils":405}],174:[function(require,module,exports){ /** * @fileoverview Rule to enforce spacing before and after keywords. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"), keywords = require("../util/keywords"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ var PREV_TOKEN = /^[)\]}>]$/; var NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/; var PREV_TOKEN_M = /^[)\]}>*]$/; var NEXT_TOKEN_M = /^[{*]$/; var TEMPLATE_OPEN_PAREN = /\$\{$/; var TEMPLATE_CLOSE_PAREN = /^\}/; var CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/; var KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]); // check duplications. (function () { KEYS.sort(); for (var i = 1; i < KEYS.length; ++i) { if (KEYS[i] === KEYS[i - 1]) { throw new Error("Duplication was found in the keyword list: " + KEYS[i]); } } })(); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given token is a "Template" token ends with "${". * * @param {Token} token - A token to check. * @returns {boolean} `true` if the token is a "Template" token ends with "${". */ function isOpenParenOfTemplate(token) { return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value); } /** * Checks whether or not a given token is a "Template" token starts with "}". * * @param {Token} token - A token to check. * @returns {boolean} `true` if the token is a "Template" token starts with "}". */ function isCloseParenOfTemplate(token) { return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before and after keywords", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/keyword-spacing" }, fixable: "whitespace", schema: [{ type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" }, overrides: { type: "object", properties: KEYS.reduce(function (retv, key) { retv[key] = { type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }; return retv; }, {}), additionalProperties: false } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Reports a given token if there are not space(s) before the token. * * @param {Token} token - A token to report. * @param {RegExp} pattern - A pattern of the previous token to check. * @returns {void} */ function expectSpaceBefore(token, pattern) { var prevToken = sourceCode.getTokenBefore(token); if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && !isOpenParenOfTemplate(prevToken) && astUtils.isTokenOnSameLine(prevToken, token) && !sourceCode.isSpaceBetweenTokens(prevToken, token)) { context.report({ loc: token.loc.start, message: "Expected space(s) before \"{{value}}\".", data: token, fix: function fix(fixer) { return fixer.insertTextBefore(token, " "); } }); } } /** * Reports a given token if there are space(s) before the token. * * @param {Token} token - A token to report. * @param {RegExp} pattern - A pattern of the previous token to check. * @returns {void} */ function unexpectSpaceBefore(token, pattern) { var prevToken = sourceCode.getTokenBefore(token); if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && !isOpenParenOfTemplate(prevToken) && astUtils.isTokenOnSameLine(prevToken, token) && sourceCode.isSpaceBetweenTokens(prevToken, token)) { context.report({ loc: token.loc.start, message: "Unexpected space(s) before \"{{value}}\".", data: token, fix: function fix(fixer) { return fixer.removeRange([prevToken.range[1], token.range[0]]); } }); } } /** * Reports a given token if there are not space(s) after the token. * * @param {Token} token - A token to report. * @param {RegExp} pattern - A pattern of the next token to check. * @returns {void} */ function expectSpaceAfter(token, pattern) { var nextToken = sourceCode.getTokenAfter(token); if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && !isCloseParenOfTemplate(nextToken) && astUtils.isTokenOnSameLine(token, nextToken) && !sourceCode.isSpaceBetweenTokens(token, nextToken)) { context.report({ loc: token.loc.start, message: "Expected space(s) after \"{{value}}\".", data: token, fix: function fix(fixer) { return fixer.insertTextAfter(token, " "); } }); } } /** * Reports a given token if there are space(s) after the token. * * @param {Token} token - A token to report. * @param {RegExp} pattern - A pattern of the next token to check. * @returns {void} */ function unexpectSpaceAfter(token, pattern) { var nextToken = sourceCode.getTokenAfter(token); if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && !isCloseParenOfTemplate(nextToken) && astUtils.isTokenOnSameLine(token, nextToken) && sourceCode.isSpaceBetweenTokens(token, nextToken)) { context.report({ loc: token.loc.start, message: "Unexpected space(s) after \"{{value}}\".", data: token, fix: function fix(fixer) { return fixer.removeRange([token.range[1], nextToken.range[0]]); } }); } } /** * Parses the option object and determines check methods for each keyword. * * @param {Object|undefined} options - The option object to parse. * @returns {Object} - Normalized option object. * Keys are keywords (there are for every keyword). * Values are instances of `{"before": function, "after": function}`. */ function parseOptions(options) { var before = !options || options.before !== false; var after = !options || options.after !== false; var defaultValue = { before: before ? expectSpaceBefore : unexpectSpaceBefore, after: after ? expectSpaceAfter : unexpectSpaceAfter }; var overrides = options && options.overrides || {}; var retv = Object.create(null); for (var i = 0; i < KEYS.length; ++i) { var key = KEYS[i]; var override = overrides[key]; if (override) { var thisBefore = "before" in override ? override.before : before; var thisAfter = "after" in override ? override.after : after; retv[key] = { before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore, after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter }; } else { retv[key] = defaultValue; } } return retv; } var checkMethodMap = parseOptions(context.options[0]); /** * Reports a given token if usage of spacing followed by the token is * invalid. * * @param {Token} token - A token to report. * @param {RegExp|undefined} pattern - Optional. A pattern of the previous * token to check. * @returns {void} */ function checkSpacingBefore(token, pattern) { checkMethodMap[token.value].before(token, pattern || PREV_TOKEN); } /** * Reports a given token if usage of spacing preceded by the token is * invalid. * * @param {Token} token - A token to report. * @param {RegExp|undefined} pattern - Optional. A pattern of the next * token to check. * @returns {void} */ function checkSpacingAfter(token, pattern) { checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN); } /** * Reports a given token if usage of spacing around the token is invalid. * * @param {Token} token - A token to report. * @returns {void} */ function checkSpacingAround(token) { checkSpacingBefore(token); checkSpacingAfter(token); } /** * Reports the first token of a given node if the first token is a keyword * and usage of spacing around the token is invalid. * * @param {ASTNode|null} node - A node to report. * @returns {void} */ function checkSpacingAroundFirstToken(node) { var firstToken = node && sourceCode.getFirstToken(node); if (firstToken && firstToken.type === "Keyword") { checkSpacingAround(firstToken); } } /** * Reports the first token of a given node if the first token is a keyword * and usage of spacing followed by the token is invalid. * * This is used for unary operators (e.g. `typeof`), `function`, and `super`. * Other rules are handling usage of spacing preceded by those keywords. * * @param {ASTNode|null} node - A node to report. * @returns {void} */ function checkSpacingBeforeFirstToken(node) { var firstToken = node && sourceCode.getFirstToken(node); if (firstToken && firstToken.type === "Keyword") { checkSpacingBefore(firstToken); } } /** * Reports the previous token of a given node if the token is a keyword and * usage of spacing around the token is invalid. * * @param {ASTNode|null} node - A node to report. * @returns {void} */ function checkSpacingAroundTokenBefore(node) { if (node) { var token = sourceCode.getTokenBefore(node, astUtils.isKeywordToken); checkSpacingAround(token); } } /** * Reports `async` or `function` keywords of a given node if usage of * spacing around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForFunction(node) { var firstToken = node && sourceCode.getFirstToken(node); if (firstToken && (firstToken.type === "Keyword" && firstToken.value === "function" || firstToken.value === "async")) { checkSpacingBefore(firstToken); } } /** * Reports `class` and `extends` keywords of a given node if usage of * spacing around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForClass(node) { checkSpacingAroundFirstToken(node); checkSpacingAroundTokenBefore(node.superClass); } /** * Reports `if` and `else` keywords of a given node if usage of spacing * around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForIfStatement(node) { checkSpacingAroundFirstToken(node); checkSpacingAroundTokenBefore(node.alternate); } /** * Reports `try`, `catch`, and `finally` keywords of a given node if usage * of spacing around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForTryStatement(node) { checkSpacingAroundFirstToken(node); checkSpacingAroundFirstToken(node.handler); checkSpacingAroundTokenBefore(node.finalizer); } /** * Reports `do` and `while` keywords of a given node if usage of spacing * around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForDoWhileStatement(node) { checkSpacingAroundFirstToken(node); checkSpacingAroundTokenBefore(node.test); } /** * Reports `for` and `in` keywords of a given node if usage of spacing * around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForForInStatement(node) { checkSpacingAroundFirstToken(node); checkSpacingAroundTokenBefore(node.right); } /** * Reports `for` and `of` keywords of a given node if usage of spacing * around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForForOfStatement(node) { if (node.await) { checkSpacingBefore(sourceCode.getFirstToken(node, 0)); checkSpacingAfter(sourceCode.getFirstToken(node, 1)); } else { checkSpacingAroundFirstToken(node); } checkSpacingAround(sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken)); } /** * Reports `import`, `export`, `as`, and `from` keywords of a given node if * usage of spacing around those keywords is invalid. * * This rule handles the `*` token in module declarations. * * import*as A from "./a"; /*error Expected space(s) after "import". * error Expected space(s) before "as". * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForModuleDeclaration(node) { var firstToken = sourceCode.getFirstToken(node); checkSpacingBefore(firstToken, PREV_TOKEN_M); checkSpacingAfter(firstToken, NEXT_TOKEN_M); if (node.type === "ExportDefaultDeclaration") { checkSpacingAround(sourceCode.getTokenAfter(firstToken)); } if (node.source) { var fromToken = sourceCode.getTokenBefore(node.source); checkSpacingBefore(fromToken, PREV_TOKEN_M); checkSpacingAfter(fromToken, NEXT_TOKEN_M); } } /** * Reports `as` keyword of a given node if usage of spacing around this * keyword is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForImportNamespaceSpecifier(node) { var asToken = sourceCode.getFirstToken(node, 1); checkSpacingBefore(asToken, PREV_TOKEN_M); } /** * Reports `static`, `get`, and `set` keywords of a given node if usage of * spacing around those keywords is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForProperty(node) { if (node.static) { checkSpacingAroundFirstToken(node); } if (node.kind === "get" || node.kind === "set" || (node.method || node.type === "MethodDefinition") && node.value.async) { var token = sourceCode.getTokenBefore(node.key, function (tok) { switch (tok.value) { case "get": case "set": case "async": return true; default: return false; } }); if (!token) { throw new Error("Failed to find token get, set, or async beside method name"); } checkSpacingAround(token); } } /** * Reports `await` keyword of a given node if usage of spacing before * this keyword is invalid. * * @param {ASTNode} node - A node to report. * @returns {void} */ function checkSpacingForAwaitExpression(node) { checkSpacingBefore(sourceCode.getFirstToken(node)); } return { // Statements DebuggerStatement: checkSpacingAroundFirstToken, WithStatement: checkSpacingAroundFirstToken, // Statements - Control flow BreakStatement: checkSpacingAroundFirstToken, ContinueStatement: checkSpacingAroundFirstToken, ReturnStatement: checkSpacingAroundFirstToken, ThrowStatement: checkSpacingAroundFirstToken, TryStatement: checkSpacingForTryStatement, // Statements - Choice IfStatement: checkSpacingForIfStatement, SwitchStatement: checkSpacingAroundFirstToken, SwitchCase: checkSpacingAroundFirstToken, // Statements - Loops DoWhileStatement: checkSpacingForDoWhileStatement, ForInStatement: checkSpacingForForInStatement, ForOfStatement: checkSpacingForForOfStatement, ForStatement: checkSpacingAroundFirstToken, WhileStatement: checkSpacingAroundFirstToken, // Statements - Declarations ClassDeclaration: checkSpacingForClass, ExportNamedDeclaration: checkSpacingForModuleDeclaration, ExportDefaultDeclaration: checkSpacingForModuleDeclaration, ExportAllDeclaration: checkSpacingForModuleDeclaration, FunctionDeclaration: checkSpacingForFunction, ImportDeclaration: checkSpacingForModuleDeclaration, VariableDeclaration: checkSpacingAroundFirstToken, // Expressions ArrowFunctionExpression: checkSpacingForFunction, AwaitExpression: checkSpacingForAwaitExpression, ClassExpression: checkSpacingForClass, FunctionExpression: checkSpacingForFunction, NewExpression: checkSpacingBeforeFirstToken, Super: checkSpacingBeforeFirstToken, ThisExpression: checkSpacingBeforeFirstToken, UnaryExpression: checkSpacingBeforeFirstToken, YieldExpression: checkSpacingBeforeFirstToken, // Others ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier, MethodDefinition: checkSpacingForProperty, Property: checkSpacingForProperty }; } }; },{"../util/ast-utils":405,"../util/keywords":409}],175:[function(require,module,exports){ /** * @fileoverview Rule to enforce the position of line comments * @author Alberto Rodríguez */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce position of line comments", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/line-comment-position" }, schema: [{ oneOf: [{ enum: ["above", "beside"] }, { type: "object", properties: { position: { enum: ["above", "beside"] }, ignorePattern: { type: "string" }, applyDefaultPatterns: { type: "boolean" }, applyDefaultIgnorePatterns: { type: "boolean" } }, additionalProperties: false }] }] }, create: function create(context) { var options = context.options[0]; var above = void 0, ignorePattern = void 0, applyDefaultIgnorePatterns = true; if (!options || typeof options === "string") { above = !options || options === "above"; } else { above = !options.position || options.position === "above"; ignorePattern = options.ignorePattern; if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) { applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false; } else { applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false; } } var defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; var fallThroughRegExp = /^\s*falls?\s?through/; var customIgnoreRegExp = new RegExp(ignorePattern); var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function Program() { var comments = sourceCode.getAllComments(); comments.filter(function (token) { return token.type === "Line"; }).forEach(function (node) { if (applyDefaultIgnorePatterns && (defaultIgnoreRegExp.test(node.value) || fallThroughRegExp.test(node.value))) { return; } if (ignorePattern && customIgnoreRegExp.test(node.value)) { return; } var previous = sourceCode.getTokenBefore(node, { includeComments: true }); var isOnSameLine = previous && previous.loc.end.line === node.loc.start.line; if (above) { if (isOnSameLine) { context.report({ node: node, message: "Expected comment to be above code." }); } } else { if (!isOnSameLine) { context.report({ node: node, message: "Expected comment to be beside code." }); } } }); } }; } }; },{"../util/ast-utils":405}],176:[function(require,module,exports){ /** * @fileoverview Rule to enforce a single linebreak style. * @author Erik Mueller */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent linebreak style", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/linebreak-style" }, fixable: "whitespace", schema: [{ enum: ["unix", "windows"] }] }, create: function create(context) { var EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.", EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'."; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Builds a fix function that replaces text at the specified range in the source text. * @param {int[]} range The range to replace * @param {string} text The text to insert. * @returns {Function} Fixer function * @private */ function createFix(range, text) { return function (fixer) { return fixer.replaceTextRange(range, text); }; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function checkForlinebreakStyle(node) { var linebreakStyle = context.options[0] || "unix", expectedLF = linebreakStyle === "unix", expectedLFChars = expectedLF ? "\n" : "\r\n", source = sourceCode.getText(), pattern = astUtils.createGlobalLinebreakMatcher(); var match = void 0; var i = 0; while ((match = pattern.exec(source)) !== null) { i++; if (match[0] === expectedLFChars) { continue; } var index = match.index; var range = [index, index + match[0].length]; context.report({ node: node, loc: { line: i, column: sourceCode.lines[i - 1].length }, message: expectedLF ? EXPECTED_LF_MSG : EXPECTED_CRLF_MSG, fix: createFix(range, expectedLFChars) }); } } }; } }; },{"../util/ast-utils":405}],177:[function(require,module,exports){ /** * @fileoverview Enforces empty lines around comments. * @author Jamund Ferguson */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"), astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Return an array with with any line numbers that are empty. * @param {Array} lines An array of each line of the file. * @returns {Array} An array of line numbers. */ function getEmptyLineNums(lines) { var emptyLines = lines.map(function (line, i) { return { code: line.trim(), num: i + 1 }; }).filter(function (line) { return !line.code; }).map(function (line) { return line.num; }); return emptyLines; } /** * Return an array with with any line numbers that contain comments. * @param {Array} comments An array of comment tokens. * @returns {Array} An array of line numbers. */ function getCommentLineNums(comments) { var lines = []; comments.forEach(function (token) { var start = token.loc.start.line; var end = token.loc.end.line; lines.push(start, end); }); return lines; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require empty lines around comments", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/lines-around-comment" }, fixable: "whitespace", schema: [{ type: "object", properties: { beforeBlockComment: { type: "boolean" }, afterBlockComment: { type: "boolean" }, beforeLineComment: { type: "boolean" }, afterLineComment: { type: "boolean" }, allowBlockStart: { type: "boolean" }, allowBlockEnd: { type: "boolean" }, allowClassStart: { type: "boolean" }, allowClassEnd: { type: "boolean" }, allowObjectStart: { type: "boolean" }, allowObjectEnd: { type: "boolean" }, allowArrayStart: { type: "boolean" }, allowArrayEnd: { type: "boolean" }, ignorePattern: { type: "string" }, applyDefaultIgnorePatterns: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] ? Object.assign({}, context.options[0]) : {}; var ignorePattern = options.ignorePattern; var defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; var customIgnoreRegExp = new RegExp(ignorePattern); var applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false; options.beforeLineComment = options.beforeLineComment || false; options.afterLineComment = options.afterLineComment || false; options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true; options.afterBlockComment = options.afterBlockComment || false; options.allowBlockStart = options.allowBlockStart || false; options.allowBlockEnd = options.allowBlockEnd || false; var sourceCode = context.getSourceCode(); var lines = sourceCode.lines, numLines = lines.length + 1, comments = sourceCode.getAllComments(), commentLines = getCommentLineNums(comments), emptyLines = getEmptyLineNums(lines), commentAndEmptyLines = commentLines.concat(emptyLines); /** * Returns whether or not comments are on lines starting with or ending with code * @param {token} token The comment token to check. * @returns {boolean} True if the comment is not alone. */ function codeAroundComment(token) { var currentToken = token; do { currentToken = sourceCode.getTokenBefore(currentToken, { includeComments: true }); } while (currentToken && astUtils.isCommentToken(currentToken)); if (currentToken && astUtils.isTokenOnSameLine(currentToken, token)) { return true; } currentToken = token; do { currentToken = sourceCode.getTokenAfter(currentToken, { includeComments: true }); } while (currentToken && astUtils.isCommentToken(currentToken)); if (currentToken && astUtils.isTokenOnSameLine(token, currentToken)) { return true; } return false; } /** * Returns whether or not comments are inside a node type or not. * @param {ASTNode} parent The Comment parent node. * @param {string} nodeType The parent type to check against. * @returns {boolean} True if the comment is inside nodeType. */ function isParentNodeType(parent, nodeType) { return parent.type === nodeType || parent.body && parent.body.type === nodeType || parent.consequent && parent.consequent.type === nodeType; } /** * Returns the parent node that contains the given token. * @param {token} token The token to check. * @returns {ASTNode} The parent node that contains the given token. */ function getParentNodeOfToken(token) { return sourceCode.getNodeByRangeIndex(token.range[0]); } /** * Returns whether or not comments are at the parent start or not. * @param {token} token The Comment token. * @param {string} nodeType The parent type to check against. * @returns {boolean} True if the comment is at parent start. */ function isCommentAtParentStart(token, nodeType) { var parent = getParentNodeOfToken(token); return parent && isParentNodeType(parent, nodeType) && token.loc.start.line - parent.loc.start.line === 1; } /** * Returns whether or not comments are at the parent end or not. * @param {token} token The Comment token. * @param {string} nodeType The parent type to check against. * @returns {boolean} True if the comment is at parent end. */ function isCommentAtParentEnd(token, nodeType) { var parent = getParentNodeOfToken(token); return parent && isParentNodeType(parent, nodeType) && parent.loc.end.line - token.loc.end.line === 1; } /** * Returns whether or not comments are at the block start or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at block start. */ function isCommentAtBlockStart(token) { return isCommentAtParentStart(token, "ClassBody") || isCommentAtParentStart(token, "BlockStatement") || isCommentAtParentStart(token, "SwitchCase"); } /** * Returns whether or not comments are at the block end or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at block end. */ function isCommentAtBlockEnd(token) { return isCommentAtParentEnd(token, "ClassBody") || isCommentAtParentEnd(token, "BlockStatement") || isCommentAtParentEnd(token, "SwitchCase") || isCommentAtParentEnd(token, "SwitchStatement"); } /** * Returns whether or not comments are at the class start or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at class start. */ function isCommentAtClassStart(token) { return isCommentAtParentStart(token, "ClassBody"); } /** * Returns whether or not comments are at the class end or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at class end. */ function isCommentAtClassEnd(token) { return isCommentAtParentEnd(token, "ClassBody"); } /** * Returns whether or not comments are at the object start or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at object start. */ function isCommentAtObjectStart(token) { return isCommentAtParentStart(token, "ObjectExpression") || isCommentAtParentStart(token, "ObjectPattern"); } /** * Returns whether or not comments are at the object end or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at object end. */ function isCommentAtObjectEnd(token) { return isCommentAtParentEnd(token, "ObjectExpression") || isCommentAtParentEnd(token, "ObjectPattern"); } /** * Returns whether or not comments are at the array start or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at array start. */ function isCommentAtArrayStart(token) { return isCommentAtParentStart(token, "ArrayExpression") || isCommentAtParentStart(token, "ArrayPattern"); } /** * Returns whether or not comments are at the array end or not. * @param {token} token The Comment token. * @returns {boolean} True if the comment is at array end. */ function isCommentAtArrayEnd(token) { return isCommentAtParentEnd(token, "ArrayExpression") || isCommentAtParentEnd(token, "ArrayPattern"); } /** * Checks if a comment token has lines around it (ignores inline comments) * @param {token} token The Comment token. * @param {Object} opts Options to determine the newline. * @param {boolean} opts.after Should have a newline after this line. * @param {boolean} opts.before Should have a newline before this line. * @returns {void} */ function checkForEmptyLine(token, opts) { if (applyDefaultIgnorePatterns && defaultIgnoreRegExp.test(token.value)) { return; } if (ignorePattern && customIgnoreRegExp.test(token.value)) { return; } var after = opts.after, before = opts.before; var prevLineNum = token.loc.start.line - 1, nextLineNum = token.loc.end.line + 1, commentIsNotAlone = codeAroundComment(token); var blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(token) && !(options.allowClassStart === false && isCommentAtClassStart(token)), blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(token) && !(options.allowClassEnd === false && isCommentAtClassEnd(token)), classStartAllowed = options.allowClassStart && isCommentAtClassStart(token), classEndAllowed = options.allowClassEnd && isCommentAtClassEnd(token), objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(token), objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(token), arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(token), arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(token); var exceptionStartAllowed = blockStartAllowed || classStartAllowed || objectStartAllowed || arrayStartAllowed; var exceptionEndAllowed = blockEndAllowed || classEndAllowed || objectEndAllowed || arrayEndAllowed; // ignore top of the file and bottom of the file if (prevLineNum < 1) { before = false; } if (nextLineNum >= numLines) { after = false; } // we ignore all inline comments if (commentIsNotAlone) { return; } var previousTokenOrComment = sourceCode.getTokenBefore(token, { includeComments: true }); var nextTokenOrComment = sourceCode.getTokenAfter(token, { includeComments: true }); // check for newline before if (!exceptionStartAllowed && before && !lodash.includes(commentAndEmptyLines, prevLineNum) && !(astUtils.isCommentToken(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, token))) { var lineStart = token.range[0] - token.loc.start.column; var range = [lineStart, lineStart]; context.report({ node: token, message: "Expected line before comment.", fix: function fix(fixer) { return fixer.insertTextBeforeRange(range, "\n"); } }); } // check for newline after if (!exceptionEndAllowed && after && !lodash.includes(commentAndEmptyLines, nextLineNum) && !(astUtils.isCommentToken(nextTokenOrComment) && astUtils.isTokenOnSameLine(token, nextTokenOrComment))) { context.report({ node: token, message: "Expected line after comment.", fix: function fix(fixer) { return fixer.insertTextAfter(token, "\n"); } }); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function Program() { comments.forEach(function (token) { if (token.type === "Line") { if (options.beforeLineComment || options.afterLineComment) { checkForEmptyLine(token, { after: options.afterLineComment, before: options.beforeLineComment }); } } else if (token.type === "Block") { if (options.beforeBlockComment || options.afterBlockComment) { checkForEmptyLine(token, { after: options.afterBlockComment, before: options.beforeBlockComment }); } } }); } }; } }; },{"../util/ast-utils":405,"lodash":92}],178:[function(require,module,exports){ /** * @fileoverview Require or disallow newlines around directives. * @author Kai Cataldo * @deprecated */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow newlines around directives", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/lines-around-directive" }, schema: [{ oneOf: [{ enum: ["always", "never"] }, { type: "object", properties: { before: { enum: ["always", "never"] }, after: { enum: ["always", "never"] } }, additionalProperties: false, minProperties: 2 }] }], fixable: "whitespace", deprecated: true, replacedBy: ["padding-line-between-statements"] }, create: function create(context) { var sourceCode = context.getSourceCode(); var config = context.options[0] || "always"; var expectLineBefore = typeof config === "string" ? config : config.before; var expectLineAfter = typeof config === "string" ? config : config.after; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Check if node is preceded by a blank newline. * @param {ASTNode} node Node to check. * @returns {boolean} Whether or not the passed in node is preceded by a blank newline. */ function hasNewlineBefore(node) { var tokenBefore = sourceCode.getTokenBefore(node, { includeComments: true }); var tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0; return node.loc.start.line - tokenLineBefore >= 2; } /** * Gets the last token of a node that is on the same line as the rest of the node. * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing * semicolon on a different line. * @param {ASTNode} node A directive node * @returns {Token} The last token of the node on the line */ function getLastTokenOnLine(node) { var lastToken = sourceCode.getLastToken(node); var secondToLastToken = sourceCode.getTokenBefore(lastToken); return astUtils.isSemicolonToken(lastToken) && lastToken.loc.start.line > secondToLastToken.loc.end.line ? secondToLastToken : lastToken; } /** * Check if node is followed by a blank newline. * @param {ASTNode} node Node to check. * @returns {boolean} Whether or not the passed in node is followed by a blank newline. */ function hasNewlineAfter(node) { var lastToken = getLastTokenOnLine(node); var tokenAfter = sourceCode.getTokenAfter(lastToken, { includeComments: true }); return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2; } /** * Report errors for newlines around directives. * @param {ASTNode} node Node to check. * @param {string} location Whether the error was found before or after the directive. * @param {boolean} expected Whether or not a newline was expected or unexpected. * @returns {void} */ function reportError(node, location, expected) { context.report({ node: node, message: "{{expected}} newline {{location}} \"{{value}}\" directive.", data: { expected: expected ? "Expected" : "Unexpected", value: node.expression.value, location: location }, fix: function fix(fixer) { var lastToken = getLastTokenOnLine(node); if (expected) { return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n"); } return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]); } }); } /** * Check lines around directives in node * @param {ASTNode} node - node to check * @returns {void} */ function checkDirectives(node) { var directives = astUtils.getDirectivePrologue(node); if (!directives.length) { return; } var firstDirective = directives[0]; var leadingComments = sourceCode.getCommentsBefore(firstDirective); /* * Only check before the first directive if it is preceded by a comment or if it is at the top of * the file and expectLineBefore is set to "never". This is to not force a newline at the top of * the file if there are no comments as well as for compatibility with padded-blocks. */ if (leadingComments.length) { if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) { reportError(firstDirective, "before", true); } if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) { reportError(firstDirective, "before", false); } } else if (node.type === "Program" && expectLineBefore === "never" && !leadingComments.length && hasNewlineBefore(firstDirective)) { reportError(firstDirective, "before", false); } var lastDirective = directives[directives.length - 1]; var statements = node.type === "Program" ? node.body : node.body.body; /* * Do not check after the last directive if the body only * contains a directive prologue and isn't followed by a comment to ensure * this rule behaves well with padded-blocks. */ if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) { return; } if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) { reportError(lastDirective, "after", true); } if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) { reportError(lastDirective, "after", false); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: checkDirectives, FunctionDeclaration: checkDirectives, FunctionExpression: checkDirectives, ArrowFunctionExpression: checkDirectives }; } }; },{"../util/ast-utils":405}],179:[function(require,module,exports){ /** * @fileoverview Rule to check empty newline between class members * @author 薛定谔的猫 */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow an empty line between class members", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/lines-between-class-members" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }, { type: "object", properties: { exceptAfterSingleLine: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = []; options[0] = context.options[0] || "always"; options[1] = context.options[1] || { exceptAfterSingleLine: false }; var ALWAYS_MESSAGE = "Expected blank line between class members."; var NEVER_MESSAGE = "Unexpected blank line between class members."; var sourceCode = context.getSourceCode(); /** * Checks if there is padding between two tokens * @param {Token} first The first token * @param {Token} second The second token * @returns {boolean} True if there is at least a line between the tokens */ function isPaddingBetweenTokens(first, second) { var comments = sourceCode.getCommentsBefore(second); var len = comments.length; // If there is no comments if (len === 0) { var _linesBetweenFstAndSnd = second.loc.start.line - first.loc.end.line - 1; return _linesBetweenFstAndSnd >= 1; } // If there are comments var sumOfCommentLines = 0; // the numbers of lines of comments var prevCommentLineNum = -1; // line number of the end of the previous comment for (var i = 0; i < len; i++) { var commentLinesOfThisComment = comments[i].loc.end.line - comments[i].loc.start.line + 1; sumOfCommentLines += commentLinesOfThisComment; /* * If this comment and the previous comment are in the same line, * the count of comment lines is duplicated. So decrement sumOfCommentLines. */ if (prevCommentLineNum === comments[i].loc.start.line) { sumOfCommentLines -= 1; } prevCommentLineNum = comments[i].loc.end.line; } /* * If the first block and the first comment are in the same line, * the count of comment lines is duplicated. So decrement sumOfCommentLines. */ if (first.loc.end.line === comments[0].loc.start.line) { sumOfCommentLines -= 1; } /* * If the last comment and the second block are in the same line, * the count of comment lines is duplicated. So decrement sumOfCommentLines. */ if (comments[len - 1].loc.end.line === second.loc.start.line) { sumOfCommentLines -= 1; } var linesBetweenFstAndSnd = second.loc.start.line - first.loc.end.line - 1; return linesBetweenFstAndSnd - sumOfCommentLines >= 1; } return { ClassBody: function ClassBody(node) { var body = node.body; var _loop = function _loop(i) { var curFirst = sourceCode.getFirstToken(body[i]); var curLast = sourceCode.getLastToken(body[i]); var nextFirst = sourceCode.getFirstToken(body[i + 1]); var isPadded = isPaddingBetweenTokens(curLast, nextFirst); var isMulti = !astUtils.isTokenOnSameLine(curFirst, curLast); var skip = !isMulti && options[1].exceptAfterSingleLine; if (options[0] === "always" && !skip && !isPadded || options[0] === "never" && isPadded) { context.report({ node: body[i + 1], message: isPadded ? NEVER_MESSAGE : ALWAYS_MESSAGE, fix: function fix(fixer) { return isPadded ? fixer.replaceTextRange([curLast.range[1], nextFirst.range[0]], "\n") : fixer.insertTextAfter(curLast, "\n"); } }); } }; for (var i = 0; i < body.length - 1; i++) { _loop(i); } } }; } }; },{"../util/ast-utils":405}],180:[function(require,module,exports){ /** * @fileoverview Enforce a maximum number of classes per file * @author James Garbutt */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum number of classes per file", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/max-classes-per-file" }, schema: [{ type: "integer", minimum: 1 }], messages: { maximumExceeded: "Number of classes per file must not exceed {{ max }}" } }, create: function create(context) { var maxClasses = context.options[0] || 1; var classCount = 0; return { Program: function Program() { classCount = 0; }, "Program:exit": function ProgramExit(node) { if (classCount > maxClasses) { context.report({ node: node, messageId: "maximumExceeded", data: { max: maxClasses } }); } }, "ClassDeclaration, ClassExpression": function ClassDeclarationClassExpression() { classCount++; } }; } }; },{}],181:[function(require,module,exports){ /** * @fileoverview A rule to set the maximum depth block can be nested in a function. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum depth that blocks can be nested", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-depth" }, schema: [{ oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { maximum: { type: "integer", minimum: 0 }, max: { type: "integer", minimum: 0 } }, additionalProperties: false }] }] }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var functionStack = [], option = context.options[0]; var maxDepth = 4; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") { maxDepth = option.maximum; } if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") { maxDepth = option.max; } if (typeof option === "number") { maxDepth = option; } /** * When parsing a new function, store it in our function stack * @returns {void} * @private */ function startFunction() { functionStack.push(0); } /** * When parsing is done then pop out the reference * @returns {void} * @private */ function endFunction() { functionStack.pop(); } /** * Save the block and Evaluate the node * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function pushBlock(node) { var len = ++functionStack[functionStack.length - 1]; if (len > maxDepth) { context.report({ node: node, message: "Blocks are nested too deeply ({{depth}}).", data: { depth: len } }); } } /** * Pop the saved block * @returns {void} * @private */ function popBlock() { functionStack[functionStack.length - 1]--; } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { Program: startFunction, FunctionDeclaration: startFunction, FunctionExpression: startFunction, ArrowFunctionExpression: startFunction, IfStatement: function IfStatement(node) { if (node.parent.type !== "IfStatement") { pushBlock(node); } }, SwitchStatement: pushBlock, TryStatement: pushBlock, DoWhileStatement: pushBlock, WhileStatement: pushBlock, WithStatement: pushBlock, ForStatement: pushBlock, ForInStatement: pushBlock, ForOfStatement: pushBlock, "IfStatement:exit": popBlock, "SwitchStatement:exit": popBlock, "TryStatement:exit": popBlock, "DoWhileStatement:exit": popBlock, "WhileStatement:exit": popBlock, "WithStatement:exit": popBlock, "ForStatement:exit": popBlock, "ForInStatement:exit": popBlock, "ForOfStatement:exit": popBlock, "FunctionDeclaration:exit": endFunction, "FunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction, "Program:exit": endFunction }; } }; },{}],182:[function(require,module,exports){ /** * @fileoverview Rule to check for max length on a line. * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var OPTIONS_SCHEMA = { type: "object", properties: { code: { type: "integer", minimum: 0 }, comments: { type: "integer", minimum: 0 }, tabWidth: { type: "integer", minimum: 0 }, ignorePattern: { type: "string" }, ignoreComments: { type: "boolean" }, ignoreStrings: { type: "boolean" }, ignoreUrls: { type: "boolean" }, ignoreTemplateLiterals: { type: "boolean" }, ignoreRegExpLiterals: { type: "boolean" }, ignoreTrailingComments: { type: "boolean" } }, additionalProperties: false }; var OPTIONS_OR_INTEGER_SCHEMA = { anyOf: [OPTIONS_SCHEMA, { type: "integer", minimum: 0 }] }; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce a maximum line length", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-len" }, schema: [OPTIONS_OR_INTEGER_SCHEMA, OPTIONS_OR_INTEGER_SCHEMA, OPTIONS_SCHEMA] }, create: function create(context) { /* * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: * - They're matching an entire string that we know is a URI * - We're matching part of a string where we think there *might* be a URL * - We're only concerned about URLs, as picking out any URI would cause * too many false positives * - We don't care about matching the entire URL, any small segment is fine */ var URL_REGEXP = /[^:/?#]:\/\/[^?#]/; var sourceCode = context.getSourceCode(); /** * Computes the length of a line that may contain tabs. The width of each * tab will be the number of spaces to the next tab stop. * @param {string} line The line. * @param {int} tabWidth The width of each tab stop in spaces. * @returns {int} The computed line length. * @private */ function computeLineLength(line, tabWidth) { var extraCharacterCount = 0; line.replace(/\t/g, function (match, offset) { var totalOffset = offset + extraCharacterCount, previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, spaceCount = tabWidth - previousTabStopOffset; extraCharacterCount += spaceCount - 1; // -1 for the replaced tab }); return Array.from(line).length + extraCharacterCount; } // The options object must be the last option specified… var lastOption = context.options[context.options.length - 1]; var options = (typeof lastOption === "undefined" ? "undefined" : _typeof(lastOption)) === "object" ? Object.create(lastOption) : {}; // …but max code length… if (typeof context.options[0] === "number") { options.code = context.options[0]; } // …and tabWidth can be optionally specified directly as integers. if (typeof context.options[1] === "number") { options.tabWidth = context.options[1]; } var maxLength = options.code || 80, tabWidth = options.tabWidth || 4, ignoreComments = options.ignoreComments || false, ignoreStrings = options.ignoreStrings || false, ignoreTemplateLiterals = options.ignoreTemplateLiterals || false, ignoreRegExpLiterals = options.ignoreRegExpLiterals || false, ignoreTrailingComments = options.ignoreTrailingComments || options.ignoreComments || false, ignoreUrls = options.ignoreUrls || false, maxCommentLength = options.comments; var ignorePattern = options.ignorePattern || null; if (ignorePattern) { ignorePattern = new RegExp(ignorePattern); } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Tells if a given comment is trailing: it starts on the current line and * extends to or past the end of the current line. * @param {string} line The source line we want to check for a trailing comment on * @param {number} lineNumber The one-indexed line number for line * @param {ASTNode} comment The comment to inspect * @returns {boolean} If the comment is trailing on the given line */ function isTrailingComment(line, lineNumber, comment) { return comment && comment.loc.start.line === lineNumber && lineNumber <= comment.loc.end.line && (comment.loc.end.line > lineNumber || comment.loc.end.column === line.length); } /** * Tells if a comment encompasses the entire line. * @param {string} line The source line with a trailing comment * @param {number} lineNumber The one-indexed line number this is on * @param {ASTNode} comment The comment to remove * @returns {boolean} If the comment covers the entire line */ function isFullLineComment(line, lineNumber, comment) { var start = comment.loc.start, end = comment.loc.end, isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim(); return comment && (start.line < lineNumber || start.line === lineNumber && isFirstTokenOnLine) && (end.line > lineNumber || end.line === lineNumber && end.column === line.length); } /** * Gets the line after the comment and any remaining trailing whitespace is * stripped. * @param {string} line The source line with a trailing comment * @param {ASTNode} comment The comment to remove * @returns {string} Line without comment and trailing whitepace */ function stripTrailingComment(line, comment) { // loc.column is zero-indexed return line.slice(0, comment.loc.start.column).replace(/\s+$/, ""); } /** * Ensure that an array exists at [key] on `object`, and add `value` to it. * * @param {Object} object the object to mutate * @param {string} key the object's key * @param {*} value the value to add * @returns {void} * @private */ function ensureArrayAndPush(object, key, value) { if (!Array.isArray(object[key])) { object[key] = []; } object[key].push(value); } /** * Retrieves an array containing all strings (" or ') in the source code. * * @returns {ASTNode[]} An array of string nodes. */ function getAllStrings() { return sourceCode.ast.tokens.filter(function (token) { return token.type === "String" || token.type === "JSXText" && sourceCode.getNodeByRangeIndex(token.range[0] - 1).type === "JSXAttribute"; }); } /** * Retrieves an array containing all template literals in the source code. * * @returns {ASTNode[]} An array of template literal nodes. */ function getAllTemplateLiterals() { return sourceCode.ast.tokens.filter(function (token) { return token.type === "Template"; }); } /** * Retrieves an array containing all RegExp literals in the source code. * * @returns {ASTNode[]} An array of RegExp literal nodes. */ function getAllRegExpLiterals() { return sourceCode.ast.tokens.filter(function (token) { return token.type === "RegularExpression"; }); } /** * A reducer to group an AST node by line number, both start and end. * * @param {Object} acc the accumulator * @param {ASTNode} node the AST node in question * @returns {Object} the modified accumulator * @private */ function groupByLineNumber(acc, node) { for (var i = node.loc.start.line; i <= node.loc.end.line; ++i) { ensureArrayAndPush(acc, i, node); } return acc; } /** * Check the program for max length * @param {ASTNode} node Node to examine * @returns {void} * @private */ function checkProgramForMaxLength(node) { // split (honors line-ending) var lines = sourceCode.lines, // list of comments to ignore comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? sourceCode.getAllComments() : []; // we iterate over comments in parallel with the lines var commentsIndex = 0; var strings = getAllStrings(); var stringsByLine = strings.reduce(groupByLineNumber, {}); var templateLiterals = getAllTemplateLiterals(); var templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {}); var regExpLiterals = getAllRegExpLiterals(); var regExpLiteralsByLine = regExpLiterals.reduce(groupByLineNumber, {}); lines.forEach(function (line, i) { // i is zero-indexed, line numbers are one-indexed var lineNumber = i + 1; /* * if we're checking comment length; we need to know whether this * line is a comment */ var lineIsComment = false; var textToMeasure = void 0; /* * We can short-circuit the comment checks if we're already out of * comments to check. */ if (commentsIndex < comments.length) { var comment = null; // iterate over comments until we find one past the current line do { comment = comments[++commentsIndex]; } while (comment && comment.loc.start.line <= lineNumber); // and step back by one comment = comments[--commentsIndex]; if (isFullLineComment(line, lineNumber, comment)) { lineIsComment = true; textToMeasure = line; } else if (ignoreTrailingComments && isTrailingComment(line, lineNumber, comment)) { textToMeasure = stripTrailingComment(line, comment); } else { textToMeasure = line; } } else { textToMeasure = line; } if (ignorePattern && ignorePattern.test(textToMeasure) || ignoreUrls && URL_REGEXP.test(textToMeasure) || ignoreStrings && stringsByLine[lineNumber] || ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] || ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber]) { // ignore this line return; } var lineLength = computeLineLength(textToMeasure, tabWidth); var commentLengthApplies = lineIsComment && maxCommentLength; if (lineIsComment && ignoreComments) { return; } if (commentLengthApplies) { if (lineLength > maxCommentLength) { context.report({ node: node, loc: { line: lineNumber, column: 0 }, message: "Line {{lineNumber}} exceeds the maximum comment line length of {{maxCommentLength}}.", data: { lineNumber: i + 1, maxCommentLength: maxCommentLength } }); } } else if (lineLength > maxLength) { context.report({ node: node, loc: { line: lineNumber, column: 0 }, message: "Line {{lineNumber}} exceeds the maximum line length of {{maxLength}}.", data: { lineNumber: i + 1, maxLength: maxLength } }); } }); } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { Program: checkProgramForMaxLength }; } }; },{}],183:[function(require,module,exports){ /** * @fileoverview A rule to set the maximum number of line of code in a function. * @author Pete Ward */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ var OPTIONS_SCHEMA = { type: "object", properties: { max: { type: "integer", minimum: 0 }, skipComments: { type: "boolean" }, skipBlankLines: { type: "boolean" }, IIFEs: { type: "boolean" } }, additionalProperties: false }; var OPTIONS_OR_INTEGER_SCHEMA = { oneOf: [OPTIONS_SCHEMA, { type: "integer", minimum: 1 }] }; /** * Given a list of comment nodes, return a map with numeric keys (source code line numbers) and comment token values. * @param {Array} comments An array of comment nodes. * @returns {Map.} A map with numeric keys (source code line numbers) and comment token values. */ function getCommentLineNumbers(comments) { var map = new Map(); if (!comments) { return map; } comments.forEach(function (comment) { for (var i = comment.loc.start.line; i <= comment.loc.end.line; i++) { map.set(i, comment); } }); return map; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum number of line of code in a function", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-lines-per-function" }, schema: [OPTIONS_OR_INTEGER_SCHEMA] }, create: function create(context) { var sourceCode = context.getSourceCode(); var lines = sourceCode.lines; var option = context.options[0]; var maxLines = 50; var skipComments = false; var skipBlankLines = false; var IIFEs = false; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object") { if (typeof option.max === "number") { maxLines = option.max; } if (typeof option.skipComments === "boolean") { skipComments = option.skipComments; } if (typeof option.skipBlankLines === "boolean") { skipBlankLines = option.skipBlankLines; } if (typeof option.IIFEs === "boolean") { IIFEs = option.IIFEs; } } else if (typeof option === "number") { maxLines = option; } var commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments()); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Tells if a comment encompasses the entire line. * @param {string} line The source line with a trailing comment * @param {number} lineNumber The one-indexed line number this is on * @param {ASTNode} comment The comment to remove * @returns {boolean} If the comment covers the entire line */ function isFullLineComment(line, lineNumber, comment) { var start = comment.loc.start, end = comment.loc.end, isFirstTokenOnLine = start.line === lineNumber && !line.slice(0, start.column).trim(), isLastTokenOnLine = end.line === lineNumber && !line.slice(end.column).trim(); return comment && (start.line < lineNumber || isFirstTokenOnLine) && (end.line > lineNumber || isLastTokenOnLine); } /** * Identifies is a node is a FunctionExpression which is part of an IIFE * @param {ASTNode} node Node to test * @returns {boolean} True if it's an IIFE */ function isIIFE(node) { return node.type === "FunctionExpression" && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node; } /** * Identifies is a node is a FunctionExpression which is embedded within a MethodDefinition or Property * @param {ASTNode} node Node to test * @returns {boolean} True if it's a FunctionExpression embedded within a MethodDefinition or Property */ function isEmbedded(node) { if (!node.parent) { return false; } if (node !== node.parent.value) { return false; } if (node.parent.type === "MethodDefinition") { return true; } if (node.parent.type === "Property") { return node.parent.method === true || node.parent.kind === "get" || node.parent.kind === "set"; } return false; } /** * Count the lines in the function * @param {ASTNode} funcNode Function AST node * @returns {void} * @private */ function processFunction(funcNode) { var node = isEmbedded(funcNode) ? funcNode.parent : funcNode; if (!IIFEs && isIIFE(node)) { return; } var lineCount = 0; for (var i = node.loc.start.line - 1; i < node.loc.end.line; ++i) { var line = lines[i]; if (skipComments) { if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) { continue; } } if (skipBlankLines) { if (line.match(/^\s*$/)) { continue; } } lineCount++; } if (lineCount > maxLines) { var name = astUtils.getFunctionNameWithKind(funcNode); context.report({ node: node, message: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}.", data: { name: name, lineCount: lineCount, maxLines: maxLines } }); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { FunctionDeclaration: processFunction, FunctionExpression: processFunction, ArrowFunctionExpression: processFunction }; } }; },{"../util/ast-utils":405}],184:[function(require,module,exports){ /** * @fileoverview enforce a maximum file length * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum number of lines per file", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-lines" }, schema: [{ oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { max: { type: "integer", minimum: 0 }, skipComments: { type: "boolean" }, skipBlankLines: { type: "boolean" } }, additionalProperties: false }] }] }, create: function create(context) { var option = context.options[0]; var max = 300; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") { max = option.max; } if (typeof option === "number") { max = option; } var skipComments = option && option.skipComments; var skipBlankLines = option && option.skipBlankLines; var sourceCode = context.getSourceCode(); /** * Returns whether or not a token is a comment node type * @param {Token} token The token to check * @returns {boolean} True if the token is a comment node */ function isCommentNodeType(token) { return token && (token.type === "Block" || token.type === "Line"); } /** * Returns the line numbers of a comment that don't have any code on the same line * @param {Node} comment The comment node to check * @returns {int[]} The line numbers */ function getLinesWithoutCode(comment) { var start = comment.loc.start.line; var end = comment.loc.end.line; var token = void 0; token = comment; do { token = sourceCode.getTokenBefore(token, { includeComments: true }); } while (isCommentNodeType(token)); if (token && astUtils.isTokenOnSameLine(token, comment)) { start += 1; } token = comment; do { token = sourceCode.getTokenAfter(token, { includeComments: true }); } while (isCommentNodeType(token)); if (token && astUtils.isTokenOnSameLine(comment, token)) { end -= 1; } if (start <= end) { return lodash.range(start, end + 1); } return []; } return { "Program:exit": function ProgramExit() { var lines = sourceCode.lines.map(function (text, i) { return { lineNumber: i + 1, text: text }; }); if (skipBlankLines) { lines = lines.filter(function (l) { return l.text.trim() !== ""; }); } if (skipComments) { var comments = sourceCode.getAllComments(); var commentLines = lodash.flatten(comments.map(function (comment) { return getLinesWithoutCode(comment); })); lines = lines.filter(function (l) { return !lodash.includes(commentLines, l.lineNumber); }); } if (lines.length > max) { context.report({ loc: { line: 1, column: 0 }, message: "File must be at most {{max}} lines long. It's {{actual}} lines long.", data: { max: max, actual: lines.length } }); } } }; } }; },{"../util/ast-utils":405,"lodash":92}],185:[function(require,module,exports){ /** * @fileoverview Rule to enforce a maximum number of nested callbacks. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum depth that callbacks can be nested", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-nested-callbacks" }, schema: [{ oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { maximum: { type: "integer", minimum: 0 }, max: { type: "integer", minimum: 0 } }, additionalProperties: false }] }] }, create: function create(context) { //-------------------------------------------------------------------------- // Constants //-------------------------------------------------------------------------- var option = context.options[0]; var THRESHOLD = 10; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") { THRESHOLD = option.maximum; } if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") { THRESHOLD = option.max; } if (typeof option === "number") { THRESHOLD = option; } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var callbackStack = []; /** * Checks a given function node for too many callbacks. * @param {ASTNode} node The node to check. * @returns {void} * @private */ function checkFunction(node) { var parent = node.parent; if (parent.type === "CallExpression") { callbackStack.push(node); } if (callbackStack.length > THRESHOLD) { var opts = { num: callbackStack.length, max: THRESHOLD }; context.report({ node: node, message: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", data: opts }); } } /** * Pops the call stack. * @returns {void} * @private */ function popStack() { callbackStack.pop(); } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { ArrowFunctionExpression: checkFunction, "ArrowFunctionExpression:exit": popStack, FunctionExpression: checkFunction, "FunctionExpression:exit": popStack }; } }; },{}],186:[function(require,module,exports){ /** * @fileoverview Rule to flag when a function has too many parameters * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum number of parameters in function definitions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-params" }, schema: [{ oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { maximum: { type: "integer", minimum: 0 }, max: { type: "integer", minimum: 0 } }, additionalProperties: false }] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var option = context.options[0]; var numParams = 3; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") { numParams = option.maximum; } if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") { numParams = option.max; } if (typeof option === "number") { numParams = option; } /** * Checks a function to see if it has too many parameters. * @param {ASTNode} node The node to check. * @returns {void} * @private */ function checkFunction(node) { if (node.params.length > numParams) { context.report({ loc: astUtils.getFunctionHeadLoc(node, sourceCode), node: node, message: "{{name}} has too many parameters ({{count}}). Maximum allowed is {{max}}.", data: { name: lodash.upperFirst(astUtils.getFunctionNameWithKind(node)), count: node.params.length, max: numParams } }); } } return { FunctionDeclaration: checkFunction, ArrowFunctionExpression: checkFunction, FunctionExpression: checkFunction }; } }; },{"../util/ast-utils":405,"lodash":92}],187:[function(require,module,exports){ /** * @fileoverview Specify the maximum number of statements allowed per line. * @author Kenneth Williams */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce a maximum number of statements allowed per line", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-statements-per-line" }, schema: [{ type: "object", properties: { max: { type: "integer", minimum: 1 } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(), options = context.options[0] || {}, maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1, message = "This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}."; var lastStatementLine = 0, numberOfStatementsOnThisLine = 0, firstExtraStatement = void 0; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/; /** * Reports with the first extra statement, and clears it. * * @returns {void} */ function reportFirstExtraStatementAndClear() { if (firstExtraStatement) { context.report({ node: firstExtraStatement, message: message, data: { numberOfStatementsOnThisLine: numberOfStatementsOnThisLine, maxStatementsPerLine: maxStatementsPerLine, statements: numberOfStatementsOnThisLine === 1 ? "statement" : "statements" } }); } firstExtraStatement = null; } /** * Gets the actual last token of a given node. * * @param {ASTNode} node - A node to get. This is a node except EmptyStatement. * @returns {Token} The actual last token. */ function getActualLastToken(node) { return sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); } /** * Addresses a given node. * It updates the state of this rule, then reports the node if the node violated this rule. * * @param {ASTNode} node - A node to check. * @returns {void} */ function enterStatement(node) { var line = node.loc.start.line; /* * Skip to allow non-block statements if this is direct child of control statements. * `if (a) foo();` is counted as 1. * But `if (a) foo(); else foo();` should be counted as 2. */ if (SINGLE_CHILD_ALLOWED.test(node.parent.type) && node.parent.alternate !== node) { return; } // Update state. if (line === lastStatementLine) { numberOfStatementsOnThisLine += 1; } else { reportFirstExtraStatementAndClear(); numberOfStatementsOnThisLine = 1; lastStatementLine = line; } // Reports if the node violated this rule. if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { firstExtraStatement = firstExtraStatement || node; } } /** * Updates the state of this rule with the end line of leaving node to check with the next statement. * * @param {ASTNode} node - A node to check. * @returns {void} */ function leaveStatement(node) { var line = getActualLastToken(node).loc.end.line; // Update state. if (line !== lastStatementLine) { reportFirstExtraStatementAndClear(); numberOfStatementsOnThisLine = 1; lastStatementLine = line; } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { BreakStatement: enterStatement, ClassDeclaration: enterStatement, ContinueStatement: enterStatement, DebuggerStatement: enterStatement, DoWhileStatement: enterStatement, ExpressionStatement: enterStatement, ForInStatement: enterStatement, ForOfStatement: enterStatement, ForStatement: enterStatement, FunctionDeclaration: enterStatement, IfStatement: enterStatement, ImportDeclaration: enterStatement, LabeledStatement: enterStatement, ReturnStatement: enterStatement, SwitchStatement: enterStatement, ThrowStatement: enterStatement, TryStatement: enterStatement, VariableDeclaration: enterStatement, WhileStatement: enterStatement, WithStatement: enterStatement, ExportNamedDeclaration: enterStatement, ExportDefaultDeclaration: enterStatement, ExportAllDeclaration: enterStatement, "BreakStatement:exit": leaveStatement, "ClassDeclaration:exit": leaveStatement, "ContinueStatement:exit": leaveStatement, "DebuggerStatement:exit": leaveStatement, "DoWhileStatement:exit": leaveStatement, "ExpressionStatement:exit": leaveStatement, "ForInStatement:exit": leaveStatement, "ForOfStatement:exit": leaveStatement, "ForStatement:exit": leaveStatement, "FunctionDeclaration:exit": leaveStatement, "IfStatement:exit": leaveStatement, "ImportDeclaration:exit": leaveStatement, "LabeledStatement:exit": leaveStatement, "ReturnStatement:exit": leaveStatement, "SwitchStatement:exit": leaveStatement, "ThrowStatement:exit": leaveStatement, "TryStatement:exit": leaveStatement, "VariableDeclaration:exit": leaveStatement, "WhileStatement:exit": leaveStatement, "WithStatement:exit": leaveStatement, "ExportNamedDeclaration:exit": leaveStatement, "ExportDefaultDeclaration:exit": leaveStatement, "ExportAllDeclaration:exit": leaveStatement, "Program:exit": reportFirstExtraStatementAndClear }; } }; },{"../util/ast-utils":405}],188:[function(require,module,exports){ /** * @fileoverview A rule to set the maximum number of statements in a function. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a maximum number of statements allowed in function blocks", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/max-statements" }, schema: [{ oneOf: [{ type: "integer", minimum: 0 }, { type: "object", properties: { maximum: { type: "integer", minimum: 0 }, max: { type: "integer", minimum: 0 } }, additionalProperties: false }] }, { type: "object", properties: { ignoreTopLevelFunctions: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var functionStack = [], option = context.options[0], ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false, topLevelFunctions = []; var maxStatements = 10; if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") { maxStatements = option.maximum; } if ((typeof option === "undefined" ? "undefined" : _typeof(option)) === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") { maxStatements = option.max; } if (typeof option === "number") { maxStatements = option; } /** * Reports a node if it has too many statements * @param {ASTNode} node node to evaluate * @param {int} count Number of statements in node * @param {int} max Maximum number of statements allowed * @returns {void} * @private */ function reportIfTooManyStatements(node, count, max) { if (count > max) { var name = lodash.upperFirst(astUtils.getFunctionNameWithKind(node)); context.report({ node: node, message: "{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}.", data: { name: name, count: count, max: max } }); } } /** * When parsing a new function, store it in our function stack * @returns {void} * @private */ function startFunction() { functionStack.push(0); } /** * Evaluate the node at the end of function * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function endFunction(node) { var count = functionStack.pop(); if (ignoreTopLevelFunctions && functionStack.length === 0) { topLevelFunctions.push({ node: node, count: count }); } else { reportIfTooManyStatements(node, count, maxStatements); } } /** * Increment the count of the functions * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function countStatements(node) { functionStack[functionStack.length - 1] += node.body.length; } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { FunctionDeclaration: startFunction, FunctionExpression: startFunction, ArrowFunctionExpression: startFunction, BlockStatement: countStatements, "FunctionDeclaration:exit": endFunction, "FunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction, "Program:exit": function ProgramExit() { if (topLevelFunctions.length === 1) { return; } topLevelFunctions.forEach(function (element) { var count = element.count; var node = element.node; reportIfTooManyStatements(node, count, maxStatements); }); } }; } }; },{"../util/ast-utils":405,"lodash":92}],189:[function(require,module,exports){ /** * @fileoverview enforce a particular style for multiline comments * @author Teddy Katz */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce a particular style for multiline comments", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/multiline-comment-style" }, fixable: "whitespace", schema: [{ enum: ["starred-block", "separate-lines", "bare-block"] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var option = context.options[0] || "starred-block"; var EXPECTED_BLOCK_ERROR = "Expected a block comment instead of consecutive line comments."; var START_NEWLINE_ERROR = "Expected a linebreak after '/*'."; var END_NEWLINE_ERROR = "Expected a linebreak before '*/'."; var MISSING_STAR_ERROR = "Expected a '*' at the start of this line."; var ALIGNMENT_ERROR = "Expected this line to be aligned with the start of the comment."; var EXPECTED_LINES_ERROR = "Expected multiple line comments instead of a block comment."; //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Gets a list of comment lines in a group * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment * @returns {string[]} A list of comment lines */ function getCommentLines(commentGroup) { if (commentGroup[0].type === "Line") { return commentGroup.map(function (comment) { return comment.value; }); } return commentGroup[0].value.split(astUtils.LINEBREAK_MATCHER).map(function (line) { return line.replace(/^\s*\*?/, ""); }); } /** * Converts a comment into starred-block form * @param {Token} firstComment The first comment of the group being converted * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment * @returns {string} A representation of the comment value in starred-block form, excluding start and end markers */ function convertToStarredBlock(firstComment, commentLinesList) { var initialOffset = sourceCode.text.slice(firstComment.range[0] - firstComment.loc.start.column, firstComment.range[0]); var starredLines = commentLinesList.map(function (line) { return initialOffset + " *" + line; }); return "\n" + starredLines.join("\n") + "\n" + initialOffset + " "; } /** * Converts a comment into separate-line form * @param {Token} firstComment The first comment of the group being converted * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment * @returns {string} A representation of the comment value in separate-line form */ function convertToSeparateLines(firstComment, commentLinesList) { var initialOffset = sourceCode.text.slice(firstComment.range[0] - firstComment.loc.start.column, firstComment.range[0]); var separateLines = commentLinesList.map(function (line) { return "// " + line.trim(); }); return separateLines.join("\n" + initialOffset); } /** * Converts a comment into bare-block form * @param {Token} firstComment The first comment of the group being converted * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment * @returns {string} A representation of the comment value in bare-block form */ function convertToBlock(firstComment, commentLinesList) { var initialOffset = sourceCode.text.slice(firstComment.range[0] - firstComment.loc.start.column, firstComment.range[0]); var blockLines = commentLinesList.map(function (line) { return line.trim(); }); return "/* " + blockLines.join("\n" + initialOffset + " ") + " */"; } /** * Check a comment is JSDoc form * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment * @returns {boolean} if commentGroup is JSDoc form, return true */ function isJSDoc(commentGroup) { var lines = commentGroup[0].value.split(astUtils.LINEBREAK_MATCHER); return commentGroup[0].type === "Block" && /^\*\s*$/.test(lines[0]) && lines.slice(1, -1).every(function (line) { return (/^\s* /.test(line) ); }) && /^\s*$/.test(lines[lines.length - 1]); } /** * Each method checks a group of comments to see if it's valid according to the given option. * @param {Token[]} commentGroup A list of comments that appear together. This will either contain a single * block comment or multiple line comments. * @returns {void} */ var commentGroupCheckers = { "starred-block": function starredBlock(commentGroup) { var commentLines = getCommentLines(commentGroup); if (commentLines.some(function (value) { return value.includes("*/"); })) { return; } if (commentGroup.length > 1) { context.report({ loc: { start: commentGroup[0].loc.start, end: commentGroup[commentGroup.length - 1].loc.end }, message: EXPECTED_BLOCK_ERROR, fix: function fix(fixer) { var range = [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]]; var starredBlock = "/*" + convertToStarredBlock(commentGroup[0], commentLines) + "*/"; return commentLines.some(function (value) { return value.startsWith("/"); }) ? null : fixer.replaceTextRange(range, starredBlock); } }); } else { (function () { var block = commentGroup[0]; var lines = block.value.split(astUtils.LINEBREAK_MATCHER); var expectedLinePrefix = sourceCode.text.slice(block.range[0] - block.loc.start.column, block.range[0]) + " *"; if (!/^\*?\s*$/.test(lines[0])) { var start = block.value.startsWith("*") ? block.range[0] + 1 : block.range[0]; context.report({ loc: { start: block.loc.start, end: { line: block.loc.start.line, column: block.loc.start.column + 2 } }, message: START_NEWLINE_ERROR, fix: function fix(fixer) { return fixer.insertTextAfterRange([start, start + 2], "\n" + expectedLinePrefix); } }); } if (!/^\s*$/.test(lines[lines.length - 1])) { context.report({ loc: { start: { line: block.loc.end.line, column: block.loc.end.column - 2 }, end: block.loc.end }, message: END_NEWLINE_ERROR, fix: function fix(fixer) { return fixer.replaceTextRange([block.range[1] - 2, block.range[1]], "\n" + expectedLinePrefix + "/"); } }); } var _loop = function _loop(lineNumber) { var lineText = sourceCode.lines[lineNumber - 1]; if (!lineText.startsWith(expectedLinePrefix)) { context.report({ loc: { start: { line: lineNumber, column: 0 }, end: { line: lineNumber, column: sourceCode.lines[lineNumber - 1].length } }, message: /^\s*\*/.test(lineText) ? ALIGNMENT_ERROR : MISSING_STAR_ERROR, fix: function fix(fixer) { var lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 }); var linePrefixLength = lineText.match(/^\s*\*? ?/)[0].length; var commentStartIndex = lineStartIndex + linePrefixLength; var replacementText = lineNumber === block.loc.end.line || lineText.length === linePrefixLength ? expectedLinePrefix : expectedLinePrefix + " "; return fixer.replaceTextRange([lineStartIndex, commentStartIndex], replacementText); } }); } }; for (var lineNumber = block.loc.start.line + 1; lineNumber <= block.loc.end.line; lineNumber++) { _loop(lineNumber); } })(); } }, "separate-lines": function separateLines(commentGroup) { if (!isJSDoc(commentGroup) && commentGroup[0].type === "Block") { var commentLines = getCommentLines(commentGroup); var block = commentGroup[0]; var tokenAfter = sourceCode.getTokenAfter(block, { includeComments: true }); if (tokenAfter && block.loc.end.line === tokenAfter.loc.start.line) { return; } context.report({ loc: { start: block.loc.start, end: { line: block.loc.start.line, column: block.loc.start.column + 2 } }, message: EXPECTED_LINES_ERROR, fix: function fix(fixer) { return fixer.replaceText(block, convertToSeparateLines(block, commentLines.filter(function (line) { return line; }))); } }); } }, "bare-block": function bareBlock(commentGroup) { if (!isJSDoc(commentGroup)) { var commentLines = getCommentLines(commentGroup); // disallows consecutive line comments in favor of using a block comment. if (commentGroup[0].type === "Line" && commentLines.length > 1 && !commentLines.some(function (value) { return value.includes("*/"); })) { context.report({ loc: { start: commentGroup[0].loc.start, end: commentGroup[commentGroup.length - 1].loc.end }, message: EXPECTED_BLOCK_ERROR, fix: function fix(fixer) { var range = [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]]; var block = convertToBlock(commentGroup[0], commentLines.filter(function (line) { return line; })); return fixer.replaceTextRange(range, block); } }); } // prohibits block comments from having a * at the beginning of each line. if (commentGroup[0].type === "Block") { var block = commentGroup[0]; var lines = block.value.split(astUtils.LINEBREAK_MATCHER).filter(function (line) { return line.trim(); }); if (lines.length > 0 && lines.every(function (line) { return (/^\s*\*/.test(line) ); })) { context.report({ loc: { start: block.loc.start, end: { line: block.loc.start.line, column: block.loc.start.column + 2 } }, message: EXPECTED_BLOCK_ERROR, fix: function fix(fixer) { return fixer.replaceText(block, convertToBlock(block, commentLines.filter(function (line) { return line; }))); } }); } } } } }; //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { Program: function Program() { return sourceCode.getAllComments().filter(function (comment) { return comment.type !== "Shebang"; }).filter(function (comment) { return !astUtils.COMMENTS_IGNORE_PATTERN.test(comment.value); }).filter(function (comment) { var tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); return !tokenBefore || tokenBefore.loc.end.line < comment.loc.start.line; }).reduce(function (commentGroups, comment, index, commentList) { var tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); if (comment.type === "Line" && index && commentList[index - 1].type === "Line" && tokenBefore && tokenBefore.loc.end.line === comment.loc.start.line - 1 && tokenBefore === commentList[index - 1]) { commentGroups[commentGroups.length - 1].push(comment); } else { commentGroups.push([comment]); } return commentGroups; }, []).filter(function (commentGroup) { return !(commentGroup.length === 1 && commentGroup[0].loc.start.line === commentGroup[0].loc.end.line); }).forEach(commentGroupCheckers[option]); } }; } }; },{"../util/ast-utils":405}],190:[function(require,module,exports){ /** * @fileoverview Enforce newlines between operands of ternary expressions * @author Kai Cataldo */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce newlines between operands of ternary expressions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/multiline-ternary" }, schema: [{ enum: ["always", "always-multiline", "never"] }] }, create: function create(context) { var option = context.options[0]; var multiline = option !== "never"; var allowSingleLine = option === "always-multiline"; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Tests whether node is preceded by supplied tokens * @param {ASTNode} node - node to check * @param {ASTNode} parentNode - parent of node to report * @param {boolean} expected - whether newline was expected or not * @returns {void} * @private */ function reportError(node, parentNode, expected) { context.report({ node: node, message: "{{expected}} newline between {{typeOfError}} of ternary expression.", data: { expected: expected ? "Expected" : "Unexpected", typeOfError: node === parentNode.test ? "test and consequent" : "consequent and alternate" } }); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ConditionalExpression: function ConditionalExpression(node) { var areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent); var areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate); if (!multiline) { if (!areTestAndConsequentOnSameLine) { reportError(node.test, node, false); } if (!areConsequentAndAlternateOnSameLine) { reportError(node.consequent, node, false); } } else { if (allowSingleLine && node.loc.start.line === node.loc.end.line) { return; } if (areTestAndConsequentOnSameLine) { reportError(node.test, node, true); } if (areConsequentAndAlternateOnSameLine) { reportError(node.consequent, node, true); } } } }; } }; },{"../util/ast-utils":405}],191:[function(require,module,exports){ /** * @fileoverview Rule to flag use of constructors without capital letters * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var CAPS_ALLOWED = ["Array", "Boolean", "Date", "Error", "Function", "Number", "Object", "RegExp", "String", "Symbol"]; /** * Ensure that if the key is provided, it must be an array. * @param {Object} obj Object to check with `key`. * @param {string} key Object key to check on `obj`. * @param {*} fallback If obj[key] is not present, this will be returned. * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback` */ function checkArray(obj, key, fallback) { /* istanbul ignore if */ if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) { throw new TypeError(key + ", if provided, must be an Array"); } return obj[key] || fallback; } /** * A reducer function to invert an array to an Object mapping the string form of the key, to `true`. * @param {Object} map Accumulator object for the reduce. * @param {string} key Object key to set to `true`. * @returns {Object} Returns the updated Object for further reduction. */ function invert(map, key) { map[key] = true; return map; } /** * Creates an object with the cap is new exceptions as its keys and true as their values. * @param {Object} config Rule configuration * @returns {Object} Object with cap is new exceptions. */ function calculateCapIsNewExceptions(config) { var capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); if (capIsNewExceptions !== CAPS_ALLOWED) { capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED); } return capIsNewExceptions.reduce(invert, {}); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require constructor names to begin with a capital letter", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/new-cap" }, schema: [{ type: "object", properties: { newIsCap: { type: "boolean" }, capIsNew: { type: "boolean" }, newIsCapExceptions: { type: "array", items: { type: "string" } }, newIsCapExceptionPattern: { type: "string" }, capIsNewExceptions: { type: "array", items: { type: "string" } }, capIsNewExceptionPattern: { type: "string" }, properties: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var config = context.options[0] ? Object.assign({}, context.options[0]) : {}; config.newIsCap = config.newIsCap !== false; config.capIsNew = config.capIsNew !== false; var skipProperties = config.properties === false; var newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); var newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null; var capIsNewExceptions = calculateCapIsNewExceptions(config); var capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern) : null; var listeners = {}; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Get exact callee name from expression * @param {ASTNode} node CallExpression or NewExpression node * @returns {string} name */ function extractNameFromExpression(node) { var name = ""; if (node.callee.type === "MemberExpression") { var property = node.callee.property; if (property.type === "Literal" && typeof property.value === "string") { name = property.value; } else if (property.type === "Identifier" && !node.callee.computed) { name = property.name; } } else { name = node.callee.name; } return name; } /** * Returns the capitalization state of the string - * Whether the first character is uppercase, lowercase, or non-alphabetic * @param {string} str String * @returns {string} capitalization state: "non-alpha", "lower", or "upper" */ function getCap(str) { var firstChar = str.charAt(0); var firstCharLower = firstChar.toLowerCase(); var firstCharUpper = firstChar.toUpperCase(); if (firstCharLower === firstCharUpper) { // char has no uppercase variant, so it's non-alphabetic return "non-alpha"; } if (firstChar === firstCharLower) { return "lower"; } return "upper"; } /** * Check if capitalization is allowed for a CallExpression * @param {Object} allowedMap Object mapping calleeName to a Boolean * @param {ASTNode} node CallExpression node * @param {string} calleeName Capitalized callee name from a CallExpression * @param {Object} pattern RegExp object from options pattern * @returns {boolean} Returns true if the callee may be capitalized */ function isCapAllowed(allowedMap, node, calleeName, pattern) { var sourceText = sourceCode.getText(node.callee); if (allowedMap[calleeName] || allowedMap[sourceText]) { return true; } if (pattern && pattern.test(sourceText)) { return true; } if (calleeName === "UTC" && node.callee.type === "MemberExpression") { // allow if callee is Date.UTC return node.callee.object.type === "Identifier" && node.callee.object.name === "Date"; } return skipProperties && node.callee.type === "MemberExpression"; } /** * Reports the given message for the given node. The location will be the start of the property or the callee. * @param {ASTNode} node CallExpression or NewExpression node. * @param {string} message The message to report. * @returns {void} */ function report(node, message) { var callee = node.callee; if (callee.type === "MemberExpression") { callee = callee.property; } context.report({ node: node, loc: callee.loc.start, message: message }); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- if (config.newIsCap) { listeners.NewExpression = function (node) { var constructorName = extractNameFromExpression(node); if (constructorName) { var capitalization = getCap(constructorName); var isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName, newIsCapExceptionPattern); if (!isAllowed) { report(node, "A constructor name should not start with a lowercase letter."); } } }; } if (config.capIsNew) { listeners.CallExpression = function (node) { var calleeName = extractNameFromExpression(node); if (calleeName) { var capitalization = getCap(calleeName); var isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName, capIsNewExceptionPattern); if (!isAllowed) { report(node, "A function with a name starting with an uppercase letter should only be used as a constructor."); } } }; } return listeners; } }; },{}],192:[function(require,module,exports){ /** * @fileoverview Rule to flag when using constructor without parentheses * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require parentheses when invoking a constructor with no arguments", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/new-parens" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { NewExpression: function NewExpression(node) { if (node.arguments.length !== 0) { return; // shortcut: if there are arguments, there have to be parens } var lastToken = sourceCode.getLastToken(node); var hasLastParen = lastToken && astUtils.isClosingParenToken(lastToken); var hasParens = hasLastParen && astUtils.isOpeningParenToken(sourceCode.getTokenBefore(lastToken)); if (!hasParens) { context.report({ node: node, message: "Missing '()' invoking a constructor.", fix: function fix(fixer) { return fixer.insertTextAfter(node, "()"); } }); } } }; } }; },{"../util/ast-utils":405}],193:[function(require,module,exports){ /** * @fileoverview Rule to check empty newline after "var" statement * @author Gopal Venkatesan * @deprecated */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow an empty line after variable declarations", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/newline-after-var" }, schema: [{ enum: ["never", "always"] }], fixable: "whitespace", deprecated: true, replacedBy: ["padding-line-between-statements"] }, create: function create(context) { var ALWAYS_MESSAGE = "Expected blank line after variable declarations.", NEVER_MESSAGE = "Unexpected blank line after variable declarations."; var sourceCode = context.getSourceCode(); // Default `mode` to "always". var mode = context.options[0] === "never" ? "never" : "always"; // Cache starting and ending line numbers of comments for faster lookup var commentEndLine = sourceCode.getAllComments().reduce(function (result, token) { result[token.loc.start.line] = token.loc.end.line; return result; }, {}); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Gets a token from the given node to compare line to the next statement. * * In general, the token is the last token of the node. However, the token is the second last token if the following conditions satisfy. * * - The last token is semicolon. * - The semicolon is on a different line from the previous token of the semicolon. * * This behavior would address semicolon-less style code. e.g.: * * var foo = 1 * * ;(a || b).doSomething() * * @param {ASTNode} node - The node to get. * @returns {Token} The token to compare line to the next statement. */ function getLastToken(node) { var lastToken = sourceCode.getLastToken(node); if (lastToken.type === "Punctuator" && lastToken.value === ";") { var prevToken = sourceCode.getTokenBefore(lastToken); if (prevToken.loc.end.line !== lastToken.loc.start.line) { return prevToken; } } return lastToken; } /** * Determine if provided keyword is a variable declaration * @private * @param {string} keyword - keyword to test * @returns {boolean} True if `keyword` is a type of var */ function isVar(keyword) { return keyword === "var" || keyword === "let" || keyword === "const"; } /** * Determine if provided keyword is a variant of for specifiers * @private * @param {string} keyword - keyword to test * @returns {boolean} True if `keyword` is a variant of for specifier */ function isForTypeSpecifier(keyword) { return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; } /** * Determine if provided keyword is an export specifiers * @private * @param {string} nodeType - nodeType to test * @returns {boolean} True if `nodeType` is an export specifier */ function isExportSpecifier(nodeType) { return nodeType === "ExportNamedDeclaration" || nodeType === "ExportSpecifier" || nodeType === "ExportDefaultDeclaration" || nodeType === "ExportAllDeclaration"; } /** * Determine if provided node is the last of their parent block. * @private * @param {ASTNode} node - node to test * @returns {boolean} True if `node` is last of their parent block. */ function isLastNode(node) { var token = sourceCode.getTokenAfter(node); return !token || token.type === "Punctuator" && token.value === "}"; } /** * Gets the last line of a group of consecutive comments * @param {number} commentStartLine The starting line of the group * @returns {number} The number of the last comment line of the group */ function getLastCommentLineOfBlock(commentStartLine) { var currentCommentEnd = commentEndLine[commentStartLine]; return commentEndLine[currentCommentEnd + 1] ? getLastCommentLineOfBlock(currentCommentEnd + 1) : currentCommentEnd; } /** * Determine if a token starts more than one line after a comment ends * @param {token} token The token being checked * @param {integer} commentStartLine The line number on which the comment starts * @returns {boolean} True if `token` does not start immediately after a comment */ function hasBlankLineAfterComment(token, commentStartLine) { return token.loc.start.line > getLastCommentLineOfBlock(commentStartLine) + 1; } /** * Checks that a blank line exists after a variable declaration when mode is * set to "always", or checks that there is no blank line when mode is set * to "never" * @private * @param {ASTNode} node - `VariableDeclaration` node to test * @returns {void} */ function checkForBlankLine(node) { /* * lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will * sometimes be second-last if there is a semicolon on a different line. */ var lastToken = getLastToken(node), /* * If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken * is the last token of the node. */ nextToken = lastToken === sourceCode.getLastToken(node) ? sourceCode.getTokenAfter(node) : sourceCode.getLastToken(node), nextLineNum = lastToken.loc.end.line + 1; // Ignore if there is no following statement if (!nextToken) { return; } // Ignore if parent of node is a for variant if (isForTypeSpecifier(node.parent.type)) { return; } // Ignore if parent of node is an export specifier if (isExportSpecifier(node.parent.type)) { return; } /* * Some coding styles use multiple `var` statements, so do nothing if * the next token is a `var` statement. */ if (nextToken.type === "Keyword" && isVar(nextToken.value)) { return; } // Ignore if it is last statement in a block if (isLastNode(node)) { return; } // Next statement is not a `var`... var noNextLineToken = nextToken.loc.start.line > nextLineNum; var hasNextLineComment = typeof commentEndLine[nextLineNum] !== "undefined"; if (mode === "never" && noNextLineToken && !hasNextLineComment) { context.report({ node: node, message: NEVER_MESSAGE, data: { identifier: node.name }, fix: function fix(fixer) { var linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(astUtils.LINEBREAK_MATCHER); return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], linesBetween.slice(0, -1).join("") + "\n" + linesBetween[linesBetween.length - 1]); } }); } // Token on the next line, or comment without blank line if (mode === "always" && (!noNextLineToken || hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum))) { context.report({ node: node, message: ALWAYS_MESSAGE, data: { identifier: node.name }, fix: function fix(fixer) { if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) { return fixer.insertTextBefore(nextToken, "\n\n"); } return fixer.insertTextBeforeRange([nextToken.range[0] - nextToken.loc.start.column, nextToken.range[1]], "\n"); } }); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { VariableDeclaration: checkForBlankLine }; } }; },{"../util/ast-utils":405}],194:[function(require,module,exports){ /** * @fileoverview Rule to require newlines before `return` statement * @author Kai Cataldo * @deprecated */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require an empty line before `return` statements", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/newline-before-return" }, fixable: "whitespace", schema: [], deprecated: true, replacedBy: ["padding-line-between-statements"] }, create: function create(context) { var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Tests whether node is preceded by supplied tokens * @param {ASTNode} node - node to check * @param {Array} testTokens - array of tokens to test against * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens * @private */ function isPrecededByTokens(node, testTokens) { var tokenBefore = sourceCode.getTokenBefore(node); return testTokens.some(function (token) { return tokenBefore.value === token; }); } /** * Checks whether node is the first node after statement or in block * @param {ASTNode} node - node to check * @returns {boolean} Whether or not the node is the first node after statement or in block * @private */ function isFirstNode(node) { var parentType = node.parent.type; if (node.parent.body) { return Array.isArray(node.parent.body) ? node.parent.body[0] === node : node.parent.body === node; } if (parentType === "IfStatement") { return isPrecededByTokens(node, ["else", ")"]); } if (parentType === "DoWhileStatement") { return isPrecededByTokens(node, ["do"]); } if (parentType === "SwitchCase") { return isPrecededByTokens(node, [":"]); } return isPrecededByTokens(node, [")"]); } /** * Returns the number of lines of comments that precede the node * @param {ASTNode} node - node to check for overlapping comments * @param {number} lineNumTokenBefore - line number of previous token, to check for overlapping comments * @returns {number} Number of lines of comments that precede the node * @private */ function calcCommentLines(node, lineNumTokenBefore) { var comments = sourceCode.getCommentsBefore(node); var numLinesComments = 0; if (!comments.length) { return numLinesComments; } comments.forEach(function (comment) { numLinesComments++; if (comment.type === "Block") { numLinesComments += comment.loc.end.line - comment.loc.start.line; } // avoid counting lines with inline comments twice if (comment.loc.start.line === lineNumTokenBefore) { numLinesComments--; } if (comment.loc.end.line === node.loc.start.line) { numLinesComments--; } }); return numLinesComments; } /** * Returns the line number of the token before the node that is passed in as an argument * @param {ASTNode} node - The node to use as the start of the calculation * @returns {number} Line number of the token before `node` * @private */ function getLineNumberOfTokenBefore(node) { var tokenBefore = sourceCode.getTokenBefore(node); var lineNumTokenBefore = void 0; /** * Global return (at the beginning of a script) is a special case. * If there is no token before `return`, then we expect no line * break before the return. Comments are allowed to occupy lines * before the global return, just no blank lines. * Setting lineNumTokenBefore to zero in that case results in the * desired behavior. */ if (tokenBefore) { lineNumTokenBefore = tokenBefore.loc.end.line; } else { lineNumTokenBefore = 0; // global return at beginning of script } return lineNumTokenBefore; } /** * Checks whether node is preceded by a newline * @param {ASTNode} node - node to check * @returns {boolean} Whether or not the node is preceded by a newline * @private */ function hasNewlineBefore(node) { var lineNumNode = node.loc.start.line; var lineNumTokenBefore = getLineNumberOfTokenBefore(node); var commentLines = calcCommentLines(node, lineNumTokenBefore); return lineNumNode - lineNumTokenBefore - commentLines > 1; } /** * Checks whether it is safe to apply a fix to a given return statement. * * The fix is not considered safe if the given return statement has leading comments, * as we cannot safely determine if the newline should be added before or after the comments. * For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211 * * @param {ASTNode} node - The return statement node to check. * @returns {boolean} `true` if it can fix the node. * @private */ function canFix(node) { var leadingComments = sourceCode.getCommentsBefore(node); var lastLeadingComment = leadingComments[leadingComments.length - 1]; var tokenBefore = sourceCode.getTokenBefore(node); if (leadingComments.length === 0) { return true; } /* * if the last leading comment ends in the same line as the previous token and * does not share a line with the `return` node, we can consider it safe to fix. * Example: * function a() { * var b; //comment * return; * } */ if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line && lastLeadingComment.loc.end.line !== node.loc.start.line) { return true; } return false; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ReturnStatement: function ReturnStatement(node) { if (!isFirstNode(node) && !hasNewlineBefore(node)) { context.report({ node: node, message: "Expected newline before return statement.", fix: function fix(fixer) { if (canFix(node)) { var tokenBefore = sourceCode.getTokenBefore(node); var newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n"; return fixer.insertTextBefore(node, newlines); } return null; } }); } } }; } }; },{}],195:[function(require,module,exports){ /** * @fileoverview Rule to ensure newline per method call when chaining calls * @author Rajendra Patil * @author Burak Yigit Kaya */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require a newline after each call in a method chain", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/newline-per-chained-call" }, fixable: "whitespace", schema: [{ type: "object", properties: { ignoreChainWithDepth: { type: "integer", minimum: 1, maximum: 10 } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] || {}, ignoreChainWithDepth = options.ignoreChainWithDepth || 2; var sourceCode = context.getSourceCode(); /** * Get the prefix of a given MemberExpression node. * If the MemberExpression node is a computed value it returns a * left bracket. If not it returns a period. * * @param {ASTNode} node - A MemberExpression node to get * @returns {string} The prefix of the node. */ function getPrefix(node) { return node.computed ? "[" : "."; } /** * Gets the property text of a given MemberExpression node. * If the text is multiline, this returns only the first line. * * @param {ASTNode} node - A MemberExpression node to get. * @returns {string} The property text of the node. */ function getPropertyText(node) { var prefix = getPrefix(node); var lines = sourceCode.getText(node.property).split(astUtils.LINEBREAK_MATCHER); var suffix = node.computed && lines.length === 1 ? "]" : ""; return prefix + lines[0] + suffix; } return { "CallExpression:exit": function CallExpressionExit(node) { if (!node.callee || node.callee.type !== "MemberExpression") { return; } var callee = node.callee; var parent = callee.object; var depth = 1; while (parent && parent.callee) { depth += 1; parent = parent.callee.object; } if (depth > ignoreChainWithDepth && astUtils.isTokenOnSameLine(callee.object, callee.property)) { context.report({ node: callee.property, loc: callee.property.loc.start, message: "Expected line break before `{{callee}}`.", data: { callee: getPropertyText(callee) }, fix: function fix(fixer) { var firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken); return fixer.insertTextBefore(firstTokenAfterObject, "\n"); } }); } } }; } }; },{"../util/ast-utils":405}],196:[function(require,module,exports){ /** * @fileoverview Rule to flag use of alert, confirm, prompt * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var getPropertyName = require("../util/ast-utils").getStaticPropertyName; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks if the given name is a prohibited identifier. * @param {string} name The name to check * @returns {boolean} Whether or not the name is prohibited. */ function isProhibitedIdentifier(name) { return (/^(alert|confirm|prompt)$/.test(name) ); } /** * Finds the eslint-scope reference in the given scope. * @param {Object} scope The scope to search. * @param {ASTNode} node The identifier node. * @returns {Reference|null} Returns the found reference or null if none were found. */ function findReference(scope, node) { var references = scope.references.filter(function (reference) { return reference.identifier.range[0] === node.range[0] && reference.identifier.range[1] === node.range[1]; }); if (references.length === 1) { return references[0]; } return null; } /** * Checks if the given identifier node is shadowed in the given scope. * @param {Object} scope The current scope. * @param {string} node The identifier node to check * @returns {boolean} Whether or not the name is shadowed. */ function isShadowed(scope, node) { var reference = findReference(scope, node); return reference && reference.resolved && reference.resolved.defs.length > 0; } /** * Checks if the given identifier node is a ThisExpression in the global scope or the global window property. * @param {Object} scope The current scope. * @param {string} node The identifier node to check * @returns {boolean} Whether or not the node is a reference to the global object. */ function isGlobalThisReferenceOrGlobalWindow(scope, node) { if (scope.type === "global" && node.type === "ThisExpression") { return true; } if (node.name === "window") { return !isShadowed(scope, node); } return false; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `alert`, `confirm`, and `prompt`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-alert" }, schema: [], messages: { unexpected: "Unexpected {{name}}." } }, create: function create(context) { return { CallExpression: function CallExpression(node) { var callee = node.callee, currentScope = context.getScope(); // without window. if (callee.type === "Identifier") { var name = callee.name; if (!isShadowed(currentScope, callee) && isProhibitedIdentifier(callee.name)) { context.report({ node: node, messageId: "unexpected", data: { name: name } }); } } else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, callee.object)) { var _name = getPropertyName(callee); if (isProhibitedIdentifier(_name)) { context.report({ node: node, messageId: "unexpected", data: { name: _name } }); } } } }; } }; },{"../util/ast-utils":405}],197:[function(require,module,exports){ /** * @fileoverview Disallow construction of dense arrays using the Array constructor * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `Array` constructors", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-array-constructor" }, schema: [], messages: { preferLiteral: "The array literal notation [] is preferable." } }, create: function create(context) { /** * Disallow construction of dense arrays using the Array constructor * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function check(node) { if (node.arguments.length !== 1 && node.callee.type === "Identifier" && node.callee.name === "Array") { context.report({ node: node, messageId: "preferLiteral" }); } } return { CallExpression: check, NewExpression: check }; } }; },{}],198:[function(require,module,exports){ /** * @fileoverview disallow using an async function as a Promise executor * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow using an async function as a Promise executor", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-async-promise-executor" }, fixable: null, schema: [] }, create: function create(context) { return { "NewExpression[callee.name='Promise'][arguments.0.async=true]": function NewExpressionCalleeNamePromiseArguments0AsyncTrue(node) { context.report({ node: context.getSourceCode().getFirstToken(node.arguments[0], function (token) { return token.value === "async"; }), message: "Promise executor functions should not be async." }); } }; } }; },{}],199:[function(require,module,exports){ /** * @fileoverview Rule to disallow uses of await inside of loops. * @author Nat Mote (nmote) */ "use strict"; /** * Check whether it should stop traversing ancestors at the given node. * @param {ASTNode} node A node to check. * @returns {boolean} `true` if it should stop traversing. */ function isBoundary(node) { var t = node.type; return t === "FunctionDeclaration" || t === "FunctionExpression" || t === "ArrowFunctionExpression" || /* * Don't report the await expressions on for-await-of loop since it's * asynchronous iteration intentionally. */ t === "ForOfStatement" && node.await === true; } /** * Check whether the given node is in loop. * @param {ASTNode} node A node to check. * @param {ASTNode} parent A parent node to check. * @returns {boolean} `true` if the node is in loop. */ function isLooped(node, parent) { switch (parent.type) { case "ForStatement": return node === parent.test || node === parent.update || node === parent.body; case "ForOfStatement": case "ForInStatement": return node === parent.body; case "WhileStatement": case "DoWhileStatement": return node === parent.test || node === parent.body; default: return false; } } module.exports = { meta: { type: "problem", docs: { description: "disallow `await` inside of loops", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-await-in-loop" }, schema: [], messages: { unexpectedAwait: "Unexpected `await` inside a loop." } }, create: function create(context) { /** * Validate an await expression. * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate. * @returns {void} */ function validate(awaitNode) { if (awaitNode.type === "ForOfStatement" && !awaitNode.await) { return; } var node = awaitNode; var parent = node.parent; while (parent && !isBoundary(parent)) { if (isLooped(node, parent)) { context.report({ node: awaitNode, messageId: "unexpectedAwait" }); return; } node = parent; parent = parent.parent; } } return { AwaitExpression: validate, ForOfStatement: validate }; } }; },{}],200:[function(require,module,exports){ /** * @fileoverview Rule to flag bitwise identifiers * @author Nicholas C. Zakas */ "use strict"; /* * * Set of bitwise operators. * */ var BITWISE_OPERATORS = ["^", "|", "&", "<<", ">>", ">>>", "^=", "|=", "&=", "<<=", ">>=", ">>>=", "~"]; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow bitwise operators", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-bitwise" }, schema: [{ type: "object", properties: { allow: { type: "array", items: { enum: BITWISE_OPERATORS }, uniqueItems: true }, int32Hint: { type: "boolean" } }, additionalProperties: false }], messages: { unexpected: "Unexpected use of '{{operator}}'." } }, create: function create(context) { var options = context.options[0] || {}; var allowed = options.allow || []; var int32Hint = options.int32Hint === true; /** * Reports an unexpected use of a bitwise operator. * @param {ASTNode} node Node which contains the bitwise operator. * @returns {void} */ function report(node) { context.report({ node: node, messageId: "unexpected", data: { operator: node.operator } }); } /** * Checks if the given node has a bitwise operator. * @param {ASTNode} node The node to check. * @returns {boolean} Whether or not the node has a bitwise operator. */ function hasBitwiseOperator(node) { return BITWISE_OPERATORS.indexOf(node.operator) !== -1; } /** * Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`. * @param {ASTNode} node The node to check. * @returns {boolean} Whether or not the node has a bitwise operator. */ function allowedOperator(node) { return allowed.indexOf(node.operator) !== -1; } /** * Checks if the given bitwise operator is used for integer typecasting, i.e. "|0" * @param {ASTNode} node The node to check. * @returns {boolean} whether the node is used in integer typecasting. */ function isInt32Hint(node) { return int32Hint && node.operator === "|" && node.right && node.right.type === "Literal" && node.right.value === 0; } /** * Report if the given node contains a bitwise operator. * @param {ASTNode} node The node to check. * @returns {void} */ function checkNodeForBitwiseOperator(node) { if (hasBitwiseOperator(node) && !allowedOperator(node) && !isInt32Hint(node)) { report(node); } } return { AssignmentExpression: checkNodeForBitwiseOperator, BinaryExpression: checkNodeForBitwiseOperator, UnaryExpression: checkNodeForBitwiseOperator }; } }; },{}],201:[function(require,module,exports){ /** * @fileoverview disallow use of the Buffer() constructor * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow use of the `Buffer()` constructor", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-buffer-constructor" }, schema: [], messages: { deprecated: "{{expr}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead." } }, create: function create(context) { //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { "CallExpression[callee.name='Buffer'], NewExpression[callee.name='Buffer']": function CallExpressionCalleeNameBufferNewExpressionCalleeNameBuffer(node) { context.report({ node: node, messageId: "deprecated", data: { expr: node.type === "CallExpression" ? "Buffer()" : "new Buffer()" } }); } }; } }; },{}],202:[function(require,module,exports){ /** * @fileoverview Rule to flag use of arguments.callee and arguments.caller. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `arguments.caller` or `arguments.callee`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-caller" }, schema: [], messages: { unexpected: "Avoid arguments.{{prop}}." } }, create: function create(context) { return { MemberExpression: function MemberExpression(node) { var objectName = node.object.name, propertyName = node.property.name; if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) { context.report({ node: node, messageId: "unexpected", data: { prop: propertyName } }); } } }; } }; },{}],203:[function(require,module,exports){ /** * @fileoverview Rule to flag use of an lexical declarations inside a case clause * @author Erik Arvidsson */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow lexical declarations in case clauses", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-case-declarations" }, schema: [], messages: { unexpected: "Unexpected lexical declaration in case block." } }, create: function create(context) { /** * Checks whether or not a node is a lexical declaration. * @param {ASTNode} node A direct child statement of a switch case. * @returns {boolean} Whether or not the node is a lexical declaration. */ function isLexicalDeclaration(node) { switch (node.type) { case "FunctionDeclaration": case "ClassDeclaration": return true; case "VariableDeclaration": return node.kind !== "var"; default: return false; } } return { SwitchCase: function SwitchCase(node) { for (var i = 0; i < node.consequent.length; i++) { var statement = node.consequent[i]; if (isLexicalDeclaration(statement)) { context.report({ node: statement, messageId: "unexpected" }); } } } }; } }; },{}],204:[function(require,module,exports){ /** * @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier * @author Ian Christian Myers * @deprecated in ESLint v5.1.0 */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `catch` clause parameters from shadowing variables in the outer scope", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-catch-shadow" }, replacedBy: ["no-shadow"], deprecated: true, schema: [], messages: { mutable: "Value of '{{name}}' may be overwritten in IE 8 and earlier." } }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Check if the parameters are been shadowed * @param {Object} scope current scope * @param {string} name parameter name * @returns {boolean} True is its been shadowed */ function paramIsShadowing(scope, name) { return astUtils.getVariableByName(scope, name) !== null; } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { "CatchClause[param!=null]": function CatchClauseParamNull(node) { var scope = context.getScope(); /* * When ecmaVersion >= 6, CatchClause creates its own scope * so start from one upper scope to exclude the current node */ if (scope.block === node) { scope = scope.upper; } if (paramIsShadowing(scope, node.param.name)) { context.report({ node: node, messageId: "mutable", data: { name: node.param.name } }); } } }; } }; },{"../util/ast-utils":405}],205:[function(require,module,exports){ /** * @fileoverview A rule to disallow modifying variables of class declarations * @author Toru Nagashima */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow reassigning class members", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/no-class-assign" }, schema: [], messages: { class: "'{{name}}' is a class." } }, create: function create(context) { /** * Finds and reports references that are non initializer and writable. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { astUtils.getModifyingReferences(variable.references).forEach(function (reference) { context.report({ node: reference.identifier, messageId: "class", data: { name: reference.identifier.name } }); }); } /** * Finds and reports references that are non initializer and writable. * @param {ASTNode} node - A ClassDeclaration/ClassExpression node to check. * @returns {void} */ function checkForClass(node) { context.getDeclaredVariables(node).forEach(checkVariable); } return { ClassDeclaration: checkForClass, ClassExpression: checkForClass }; } }; },{"../util/ast-utils":405}],206:[function(require,module,exports){ /** * @fileoverview The rule should warn against code that tries to compare against -0. * @author Aladdin-ADD */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow comparing against -0", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-compare-neg-zero" }, fixable: null, schema: [], messages: { unexpected: "Do not use the '{{operator}}' operator to compare against -0." } }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Checks a given node is -0 * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is -0. */ function isNegZero(node) { return node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "Literal" && node.argument.value === 0; } var OPERATORS_TO_CHECK = new Set([">", ">=", "<", "<=", "==", "===", "!=", "!=="]); return { BinaryExpression: function BinaryExpression(node) { if (OPERATORS_TO_CHECK.has(node.operator)) { if (isNegZero(node.left) || isNegZero(node.right)) { context.report({ node: node, messageId: "unexpected", data: { operator: node.operator } }); } } } }; } }; },{}],207:[function(require,module,exports){ /** * @fileoverview Rule to flag assignment in a conditional statement's test expression * @author Stephen Murray */ "use strict"; var astUtils = require("../util/ast-utils"); var NODE_DESCRIPTIONS = { DoWhileStatement: "a 'do...while' statement", ForStatement: "a 'for' statement", IfStatement: "an 'if' statement", WhileStatement: "a 'while' statement" }; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow assignment operators in conditional expressions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-cond-assign" }, schema: [{ enum: ["except-parens", "always"] }], messages: { unexpected: "Unexpected assignment within {{type}}.", // must match JSHint's error message missing: "Expected a conditional expression and instead saw an assignment." } }, create: function create(context) { var prohibitAssign = context.options[0] || "except-parens"; var sourceCode = context.getSourceCode(); /** * Check whether an AST node is the test expression for a conditional statement. * @param {!Object} node The node to test. * @returns {boolean} `true` if the node is the text expression for a conditional statement; otherwise, `false`. */ function isConditionalTestExpression(node) { return node.parent && node.parent.test && node === node.parent.test; } /** * Given an AST node, perform a bottom-up search for the first ancestor that represents a conditional statement. * @param {!Object} node The node to use at the start of the search. * @returns {?Object} The closest ancestor node that represents a conditional statement. */ function findConditionalAncestor(node) { var currentAncestor = node; do { if (isConditionalTestExpression(currentAncestor)) { return currentAncestor.parent; } } while ((currentAncestor = currentAncestor.parent) && !astUtils.isFunction(currentAncestor)); return null; } /** * Check whether the code represented by an AST node is enclosed in two sets of parentheses. * @param {!Object} node The node to test. * @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`. */ function isParenthesisedTwice(node) { var previousToken = sourceCode.getTokenBefore(node, 1), nextToken = sourceCode.getTokenAfter(node, 1); return astUtils.isParenthesised(sourceCode, node) && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; } /** * Check a conditional statement's test expression for top-level assignments that are not enclosed in parentheses. * @param {!Object} node The node for the conditional statement. * @returns {void} */ function testForAssign(node) { if (node.test && node.test.type === "AssignmentExpression" && (node.type === "ForStatement" ? !astUtils.isParenthesised(sourceCode, node.test) : !isParenthesisedTwice(node.test))) { context.report({ node: node, loc: node.test.loc.start, messageId: "missing" }); } } /** * Check whether an assignment expression is descended from a conditional statement's test expression. * @param {!Object} node The node for the assignment expression. * @returns {void} */ function testForConditionalAncestor(node) { var ancestor = findConditionalAncestor(node); if (ancestor) { context.report({ node: ancestor, messageId: "unexpected", data: { type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type } }); } } if (prohibitAssign === "always") { return { AssignmentExpression: testForConditionalAncestor }; } return { DoWhileStatement: testForAssign, ForStatement: testForAssign, IfStatement: testForAssign, WhileStatement: testForAssign, ConditionalExpression: testForAssign }; } }; },{"../util/ast-utils":405}],208:[function(require,module,exports){ /** * @fileoverview A rule to warn against using arrow functions when they could be * confused with comparisions * @author Jxck */ "use strict"; var astUtils = require("../util/ast-utils.js"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a node is a conditional expression. * @param {ASTNode} node - node to test * @returns {boolean} `true` if the node is a conditional expression. */ function isConditional(node) { return node && node.type === "ConditionalExpression"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow arrow functions where they could be confused with comparisons", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-confusing-arrow" }, fixable: "code", schema: [{ type: "object", properties: { allowParens: { type: "boolean" } }, additionalProperties: false }], messages: { confusing: "Arrow function used ambiguously with a conditional expression." } }, create: function create(context) { var config = context.options[0] || {}; var sourceCode = context.getSourceCode(); /** * Reports if an arrow function contains an ambiguous conditional. * @param {ASTNode} node - A node to check and report. * @returns {void} */ function checkArrowFunc(node) { var body = node.body; if (isConditional(body) && !(config.allowParens && astUtils.isParenthesised(sourceCode, body))) { context.report({ node: node, messageId: "confusing", fix: function fix(fixer) { // if `allowParens` is not set to true dont bother wrapping in parens return config.allowParens && fixer.replaceText(node.body, "(" + sourceCode.getText(node.body) + ")"); } }); } } return { ArrowFunctionExpression: checkArrowFunc }; } }; },{"../util/ast-utils.js":405}],209:[function(require,module,exports){ /** * @fileoverview Rule to flag use of console object * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `console`", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-console" }, schema: [{ type: "object", properties: { allow: { type: "array", items: { type: "string" }, minItems: 1, uniqueItems: true } }, additionalProperties: false }], messages: { unexpected: "Unexpected console statement." } }, create: function create(context) { var options = context.options[0] || {}; var allowed = options.allow || []; /** * Checks whether the given reference is 'console' or not. * * @param {eslint-scope.Reference} reference - The reference to check. * @returns {boolean} `true` if the reference is 'console'. */ function isConsole(reference) { var id = reference.identifier; return id && id.name === "console"; } /** * Checks whether the property name of the given MemberExpression node * is allowed by options or not. * * @param {ASTNode} node - The MemberExpression node to check. * @returns {boolean} `true` if the property name of the node is allowed. */ function isAllowed(node) { var propertyName = astUtils.getStaticPropertyName(node); return propertyName && allowed.indexOf(propertyName) !== -1; } /** * Checks whether the given reference is a member access which is not * allowed by options or not. * * @param {eslint-scope.Reference} reference - The reference to check. * @returns {boolean} `true` if the reference is a member access which * is not allowed by options. */ function isMemberAccessExceptAllowed(reference) { var node = reference.identifier; var parent = node.parent; return parent.type === "MemberExpression" && parent.object === node && !isAllowed(parent); } /** * Reports the given reference as a violation. * * @param {eslint-scope.Reference} reference - The reference to report. * @returns {void} */ function report(reference) { var node = reference.identifier.parent; context.report({ node: node, loc: node.loc, messageId: "unexpected" }); } return { "Program:exit": function ProgramExit() { var scope = context.getScope(); var consoleVar = astUtils.getVariableByName(scope, "console"); var shadowed = consoleVar && consoleVar.defs.length > 0; /* * 'scope.through' includes all references to undefined * variables. If the variable 'console' is not defined, it uses * 'scope.through'. */ var references = consoleVar ? consoleVar.references : scope.through.filter(isConsole); if (!shadowed) { references.filter(isMemberAccessExceptAllowed).forEach(report); } } }; } }; },{"../util/ast-utils":405}],210:[function(require,module,exports){ /** * @fileoverview A rule to disallow modifying variables that are declared using `const` * @author Toru Nagashima */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow reassigning `const` variables", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/no-const-assign" }, schema: [], messages: { const: "'{{name}}' is constant." } }, create: function create(context) { /** * Finds and reports references that are non initializer and writable. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { astUtils.getModifyingReferences(variable.references).forEach(function (reference) { context.report({ node: reference.identifier, messageId: "const", data: { name: reference.identifier.name } }); }); } return { VariableDeclaration: function VariableDeclaration(node) { if (node.kind === "const") { context.getDeclaredVariables(node).forEach(checkVariable); } } }; } }; },{"../util/ast-utils":405}],211:[function(require,module,exports){ /** * @fileoverview Rule to flag use constant conditions * @author Christian Schulz */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow constant expressions in conditions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-constant-condition" }, schema: [{ type: "object", properties: { checkLoops: { type: "boolean" } }, additionalProperties: false }], messages: { unexpected: "Unexpected constant condition." } }, create: function create(context) { var options = context.options[0] || {}, checkLoops = options.checkLoops !== false, loopSetStack = []; var loopsInCurrentScope = new Set(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Checks if a branch node of LogicalExpression short circuits the whole condition * @param {ASTNode} node The branch of main condition which needs to be checked * @param {string} operator The operator of the main LogicalExpression. * @returns {boolean} true when condition short circuits whole condition */ function isLogicalIdentity(node, operator) { switch (node.type) { case "Literal": return operator === "||" && node.value === true || operator === "&&" && node.value === false; case "UnaryExpression": return operator === "&&" && node.operator === "void"; case "LogicalExpression": return isLogicalIdentity(node.left, node.operator) || isLogicalIdentity(node.right, node.operator); // no default } return false; } /** * Checks if a node has a constant truthiness value. * @param {ASTNode} node The AST node to check. * @param {boolean} inBooleanPosition `false` if checking branch of a condition. * `true` in all other cases * @returns {Bool} true when node's truthiness is constant * @private */ function isConstant(node, inBooleanPosition) { switch (node.type) { case "Literal": case "ArrowFunctionExpression": case "FunctionExpression": case "ObjectExpression": case "ArrayExpression": return true; case "UnaryExpression": if (node.operator === "void") { return true; } return node.operator === "typeof" && inBooleanPosition || isConstant(node.argument, true); case "BinaryExpression": return isConstant(node.left, false) && isConstant(node.right, false) && node.operator !== "in"; case "LogicalExpression": { var isLeftConstant = isConstant(node.left, inBooleanPosition); var isRightConstant = isConstant(node.right, inBooleanPosition); var isLeftShortCircuit = isLeftConstant && isLogicalIdentity(node.left, node.operator); var isRightShortCircuit = isRightConstant && isLogicalIdentity(node.right, node.operator); return isLeftConstant && isRightConstant || isLeftShortCircuit || isRightShortCircuit; } case "AssignmentExpression": return node.operator === "=" && isConstant(node.right, inBooleanPosition); case "SequenceExpression": return isConstant(node.expressions[node.expressions.length - 1], inBooleanPosition); // no default } return false; } /** * Tracks when the given node contains a constant condition. * @param {ASTNode} node The AST node to check. * @returns {void} * @private */ function trackConstantConditionLoop(node) { if (node.test && isConstant(node.test, true)) { loopsInCurrentScope.add(node); } } /** * Reports when the set contains the given constant condition node * @param {ASTNode} node The AST node to check. * @returns {void} * @private */ function checkConstantConditionLoopInSet(node) { if (loopsInCurrentScope.has(node)) { loopsInCurrentScope.delete(node); context.report({ node: node.test, messageId: "unexpected" }); } } /** * Reports when the given node contains a constant condition. * @param {ASTNode} node The AST node to check. * @returns {void} * @private */ function reportIfConstant(node) { if (node.test && isConstant(node.test, true)) { context.report({ node: node.test, messageId: "unexpected" }); } } /** * Stores current set of constant loops in loopSetStack temporarily * and uses a new set to track constant loops * @returns {void} * @private */ function enterFunction() { loopSetStack.push(loopsInCurrentScope); loopsInCurrentScope = new Set(); } /** * Reports when the set still contains stored constant conditions * @returns {void} * @private */ function exitFunction() { loopsInCurrentScope = loopSetStack.pop(); } /** * Checks node when checkLoops option is enabled * @param {ASTNode} node The AST node to check. * @returns {void} * @private */ function checkLoop(node) { if (checkLoops) { trackConstantConditionLoop(node); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ConditionalExpression: reportIfConstant, IfStatement: reportIfConstant, WhileStatement: checkLoop, "WhileStatement:exit": checkConstantConditionLoopInSet, DoWhileStatement: checkLoop, "DoWhileStatement:exit": checkConstantConditionLoopInSet, ForStatement: checkLoop, "ForStatement > .test": function ForStatementTest(node) { return checkLoop(node.parent); }, "ForStatement:exit": checkConstantConditionLoopInSet, FunctionDeclaration: enterFunction, "FunctionDeclaration:exit": exitFunction, FunctionExpression: enterFunction, "FunctionExpression:exit": exitFunction, YieldExpression: function YieldExpression() { return loopsInCurrentScope.clear(); } }; } }; },{}],212:[function(require,module,exports){ /** * @fileoverview Rule to flag use of continue statement * @author Borislav Zhivkov */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `continue` statements", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-continue" }, schema: [], messages: { unexpected: "Unexpected use of continue statement." } }, create: function create(context) { return { ContinueStatement: function ContinueStatement(node) { context.report({ node: node, messageId: "unexpected" }); } }; } }; },{}],213:[function(require,module,exports){ /** * @fileoverview Rule to forbid control charactes from regular expressions. * @author Nicholas C. Zakas */ "use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var RegExpValidator = require("regexpp").RegExpValidator; var collector = new (function () { function _class() { _classCallCheck(this, _class); this.ecmaVersion = 2018; this._source = ""; this._controlChars = []; this._validator = new RegExpValidator(this); } _createClass(_class, [{ key: "onPatternEnter", value: function onPatternEnter() { this._controlChars = []; } }, { key: "onCharacter", value: function onCharacter(start, end, cp) { if (cp >= 0x00 && cp <= 0x1F && (this._source.codePointAt(start) === cp || this._source.slice(start, end).startsWith("\\x") || this._source.slice(start, end).startsWith("\\u"))) { this._controlChars.push("\\x" + ("0" + cp.toString(16)).slice(-2)); } } }, { key: "collectControlChars", value: function collectControlChars(regexpStr) { try { this._source = regexpStr; this._validator.validatePattern(regexpStr); // Call onCharacter hook } catch (err) { // Ignore syntax errors in RegExp. } return this._controlChars; } }]); return _class; }())(); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow control characters in regular expressions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-control-regex" }, schema: [], messages: { unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}." } }, create: function create(context) { /** * Get the regex expression * @param {ASTNode} node node to evaluate * @returns {RegExp|null} Regex if found else null * @private */ function getRegExpPattern(node) { if (node.regex) { return node.regex.pattern; } if (typeof node.value === "string" && (node.parent.type === "NewExpression" || node.parent.type === "CallExpression") && node.parent.callee.type === "Identifier" && node.parent.callee.name === "RegExp" && node.parent.arguments[0] === node) { return node.value; } return null; } return { Literal: function Literal(node) { var pattern = getRegExpPattern(node); if (pattern) { var controlCharacters = collector.collectControlChars(pattern); if (controlCharacters.length > 0) { context.report({ node: node, messageId: "unexpected", data: { controlChars: controlCharacters.join(", ") } }); } } } }; } }; },{"regexpp":104}],214:[function(require,module,exports){ /** * @fileoverview Rule to flag use of a debugger statement * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow the use of `debugger`", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-debugger" }, fixable: null, schema: [], messages: { unexpected: "Unexpected 'debugger' statement." } }, create: function create(context) { return { DebuggerStatement: function DebuggerStatement(node) { context.report({ node: node, messageId: "unexpected" }); } }; } }; },{}],215:[function(require,module,exports){ /** * @fileoverview Rule to flag when deleting variables * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow deleting variables", category: "Variables", recommended: true, url: "https://eslint.org/docs/rules/no-delete-var" }, schema: [], messages: { unexpected: "Variables should not be deleted." } }, create: function create(context) { return { UnaryExpression: function UnaryExpression(node) { if (node.operator === "delete" && node.argument.type === "Identifier") { context.report({ node: node, messageId: "unexpected" }); } } }; } }; },{}],216:[function(require,module,exports){ /** * @fileoverview Rule to check for ambiguous div operator in regexes * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow division operators explicitly at the beginning of regular expressions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-div-regex" }, schema: [], messages: { unexpected: "A regular expression literal can be confused with '/='." } }, create: function create(context) { var sourceCode = context.getSourceCode(); return { Literal: function Literal(node) { var token = sourceCode.getFirstToken(node); if (token.type === "RegularExpression" && token.value[1] === "=") { context.report({ node: node, messageId: "unexpected" }); } } }; } }; },{}],217:[function(require,module,exports){ /** * @fileoverview Rule to flag duplicate arguments * @author Jamund Ferguson */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow duplicate arguments in `function` definitions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-dupe-args" }, schema: [], messages: { unexpected: "Duplicate param '{{name}}'." } }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Checks whether or not a given definition is a parameter's. * @param {eslint-scope.DefEntry} def - A definition to check. * @returns {boolean} `true` if the definition is a parameter's. */ function isParameter(def) { return def.type === "Parameter"; } /** * Determines if a given node has duplicate parameters. * @param {ASTNode} node The node to check. * @returns {void} * @private */ function checkParams(node) { var variables = context.getDeclaredVariables(node); for (var i = 0; i < variables.length; ++i) { var variable = variables[i]; // Checks and reports duplications. var defs = variable.defs.filter(isParameter); if (defs.length >= 2) { context.report({ node: node, messageId: "unexpected", data: { name: variable.name } }); } } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { FunctionDeclaration: checkParams, FunctionExpression: checkParams }; } }; },{}],218:[function(require,module,exports){ /** * @fileoverview A rule to disallow duplicate name in class members. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow duplicate class members", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/no-dupe-class-members" }, schema: [], messages: { unexpected: "Duplicate name '{{name}}'." } }, create: function create(context) { var stack = []; /** * Gets state of a given member name. * @param {string} name - A name of a member. * @param {boolean} isStatic - A flag which specifies that is a static member. * @returns {Object} A state of a given member name. * - retv.init {boolean} A flag which shows the name is declared as normal member. * - retv.get {boolean} A flag which shows the name is declared as getter. * - retv.set {boolean} A flag which shows the name is declared as setter. */ function getState(name, isStatic) { var stateMap = stack[stack.length - 1]; var key = "$" + name; // to avoid "__proto__". if (!stateMap[key]) { stateMap[key] = { nonStatic: { init: false, get: false, set: false }, static: { init: false, get: false, set: false } }; } return stateMap[key][isStatic ? "static" : "nonStatic"]; } /** * Gets the name text of a given node. * * @param {ASTNode} node - A node to get the name. * @returns {string} The name text of the node. */ function getName(node) { switch (node.type) { case "Identifier": return node.name; case "Literal": return String(node.value); /* istanbul ignore next: syntax error */ default: return ""; } } return { // Initializes the stack of state of member declarations. Program: function Program() { stack = []; }, // Initializes state of member declarations for the class. ClassBody: function ClassBody() { stack.push(Object.create(null)); }, // Disposes the state for the class. "ClassBody:exit": function ClassBodyExit() { stack.pop(); }, // Reports the node if its name has been declared already. MethodDefinition: function MethodDefinition(node) { if (node.computed) { return; } var name = getName(node.key); var state = getState(name, node.static); var isDuplicate = false; if (node.kind === "get") { isDuplicate = state.init || state.get; state.get = true; } else if (node.kind === "set") { isDuplicate = state.init || state.set; state.set = true; } else { isDuplicate = state.init || state.get || state.set; state.init = true; } if (isDuplicate) { context.report({ node: node, messageId: "unexpected", data: { name: name } }); } } }; } }; },{}],219:[function(require,module,exports){ /** * @fileoverview Rule to flag use of duplicate keys in an object. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var GET_KIND = /^(?:init|get)$/; var SET_KIND = /^(?:init|set)$/; /** * The class which stores properties' information of an object. */ var ObjectInfo = function () { /** * @param {ObjectInfo|null} upper - The information of the outer object. * @param {ASTNode} node - The ObjectExpression node of this information. */ function ObjectInfo(upper, node) { _classCallCheck(this, ObjectInfo); this.upper = upper; this.node = node; this.properties = new Map(); } /** * Gets the information of the given Property node. * @param {ASTNode} node - The Property node to get. * @returns {{get: boolean, set: boolean}} The information of the property. */ _createClass(ObjectInfo, [{ key: "getPropertyInfo", value: function getPropertyInfo(node) { var name = astUtils.getStaticPropertyName(node); if (!this.properties.has(name)) { this.properties.set(name, { get: false, set: false }); } return this.properties.get(name); } /** * Checks whether the given property has been defined already or not. * @param {ASTNode} node - The Property node to check. * @returns {boolean} `true` if the property has been defined. */ }, { key: "isPropertyDefined", value: function isPropertyDefined(node) { var entry = this.getPropertyInfo(node); return GET_KIND.test(node.kind) && entry.get || SET_KIND.test(node.kind) && entry.set; } /** * Defines the given property. * @param {ASTNode} node - The Property node to define. * @returns {void} */ }, { key: "defineProperty", value: function defineProperty(node) { var entry = this.getPropertyInfo(node); if (GET_KIND.test(node.kind)) { entry.get = true; } if (SET_KIND.test(node.kind)) { entry.set = true; } } }]); return ObjectInfo; }(); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow duplicate keys in object literals", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-dupe-keys" }, schema: [], messages: { unexpected: "Duplicate key '{{name}}'." } }, create: function create(context) { var info = null; return { ObjectExpression: function ObjectExpression(node) { info = new ObjectInfo(info, node); }, "ObjectExpression:exit": function ObjectExpressionExit() { info = info.upper; }, Property: function Property(node) { var name = astUtils.getStaticPropertyName(node); // Skip destructuring. if (node.parent.type !== "ObjectExpression") { return; } // Skip if the name is not static. if (!name) { return; } // Reports if the name is defined already. if (info.isPropertyDefined(node)) { context.report({ node: info.node, loc: node.key.loc, messageId: "unexpected", data: { name: name } }); } // Update info. info.defineProperty(node); } }; } }; },{"../util/ast-utils":405}],220:[function(require,module,exports){ /** * @fileoverview Rule to disallow a duplicate case label. * @author Dieter Oberkofler * @author Burak Yigit Kaya */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow duplicate case labels", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-duplicate-case" }, schema: [], messages: { unexpected: "Duplicate case label." } }, create: function create(context) { var sourceCode = context.getSourceCode(); return { SwitchStatement: function SwitchStatement(node) { var mapping = {}; node.cases.forEach(function (switchCase) { var key = sourceCode.getText(switchCase.test); if (mapping[key]) { context.report({ node: switchCase, messageId: "unexpected" }); } else { mapping[key] = switchCase; } }); } }; } }; },{}],221:[function(require,module,exports){ /** * @fileoverview Restrict usage of duplicate imports. * @author Simen Bekkhus */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** * Returns the name of the module imported or re-exported. * * @param {ASTNode} node - A node to get. * @returns {string} the name of the module, or empty string if no name. */ function getValue(node) { if (node && node.source && node.source.value) { return node.source.value.trim(); } return ""; } /** * Checks if the name of the import or export exists in the given array, and reports if so. * * @param {RuleContext} context - The ESLint rule context object. * @param {ASTNode} node - A node to get. * @param {string} value - The name of the imported or exported module. * @param {string[]} array - The array containing other imports or exports in the file. * @param {string} message - A message to be reported after the name of the module * * @returns {void} No return value */ function checkAndReport(context, node, value, array, message) { if (array.indexOf(value) !== -1) { context.report({ node: node, message: "'{{module}}' {{message}}", data: { module: value, message: message } }); } } /** * @callback nodeCallback * @param {ASTNode} node - A node to handle. */ /** * Returns a function handling the imports of a given file * * @param {RuleContext} context - The ESLint rule context object. * @param {boolean} includeExports - Whether or not to check for exports in addition to imports. * @param {string[]} importsInFile - The array containing other imports in the file. * @param {string[]} exportsInFile - The array containing other exports in the file. * * @returns {nodeCallback} A function passed to ESLint to handle the statement. */ function handleImports(context, includeExports, importsInFile, exportsInFile) { return function (node) { var value = getValue(node); if (value) { checkAndReport(context, node, value, importsInFile, "import is duplicated."); if (includeExports) { checkAndReport(context, node, value, exportsInFile, "import is duplicated as export."); } importsInFile.push(value); } }; } /** * Returns a function handling the exports of a given file * * @param {RuleContext} context - The ESLint rule context object. * @param {string[]} importsInFile - The array containing other imports in the file. * @param {string[]} exportsInFile - The array containing other exports in the file. * * @returns {nodeCallback} A function passed to ESLint to handle the statement. */ function handleExports(context, importsInFile, exportsInFile) { return function (node) { var value = getValue(node); if (value) { checkAndReport(context, node, value, exportsInFile, "export is duplicated."); checkAndReport(context, node, value, importsInFile, "export is duplicated as import."); exportsInFile.push(value); } }; } module.exports = { meta: { type: "problem", docs: { description: "disallow duplicate module imports", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-duplicate-imports" }, schema: [{ type: "object", properties: { includeExports: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var includeExports = (context.options[0] || {}).includeExports, importsInFile = [], exportsInFile = []; var handlers = { ImportDeclaration: handleImports(context, includeExports, importsInFile, exportsInFile) }; if (includeExports) { handlers.ExportNamedDeclaration = handleExports(context, importsInFile, exportsInFile); handlers.ExportAllDeclaration = handleExports(context, importsInFile, exportsInFile); } return handlers; } }; },{}],222:[function(require,module,exports){ /** * @fileoverview Rule to flag `else` after a `return` in `if` * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); var FixTracker = require("../util/fix-tracker"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `else` blocks after `return` statements in `if` statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-else-return" }, schema: [{ type: "object", properties: { allowElseIf: { type: "boolean" } }, additionalProperties: false }], fixable: "code", messages: { unexpected: "Unnecessary 'else' after 'return'." } }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Display the context report if rule is violated * * @param {Node} node The 'else' node * @returns {void} */ function displayReport(node) { context.report({ node: node, messageId: "unexpected", fix: function fix(fixer) { var sourceCode = context.getSourceCode(); var startToken = sourceCode.getFirstToken(node); var elseToken = sourceCode.getTokenBefore(startToken); var source = sourceCode.getText(node); var lastIfToken = sourceCode.getTokenBefore(elseToken); var fixedSource = void 0, firstTokenOfElseBlock = void 0; if (startToken.type === "Punctuator" && startToken.value === "{") { firstTokenOfElseBlock = sourceCode.getTokenAfter(startToken); } else { firstTokenOfElseBlock = startToken; } /* * If the if block does not have curly braces and does not end in a semicolon * and the else block starts with (, [, /, +, ` or -, then it is not * safe to remove the else keyword, because ASI will not add a semicolon * after the if block */ var ifBlockMaybeUnsafe = node.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";"; var elseBlockUnsafe = /^[([/+`-]/.test(firstTokenOfElseBlock.value); if (ifBlockMaybeUnsafe && elseBlockUnsafe) { return null; } var endToken = sourceCode.getLastToken(node); var lastTokenOfElseBlock = sourceCode.getTokenBefore(endToken); if (lastTokenOfElseBlock.value !== ";") { var nextToken = sourceCode.getTokenAfter(endToken); var nextTokenUnsafe = nextToken && /^[([/+`-]/.test(nextToken.value); var nextTokenOnSameLine = nextToken && nextToken.loc.start.line === lastTokenOfElseBlock.loc.start.line; /* * If the else block contents does not end in a semicolon, * and the else block starts with (, [, /, +, ` or -, then it is not * safe to remove the else block, because ASI will not add a semicolon * after the remaining else block contents */ if (nextTokenUnsafe || nextTokenOnSameLine && nextToken.value !== "}") { return null; } } if (startToken.type === "Punctuator" && startToken.value === "{") { fixedSource = source.slice(1, -1); } else { fixedSource = source; } /* * Extend the replacement range to include the entire * function to avoid conflicting with no-useless-return. * https://github.com/eslint/eslint/issues/8026 */ return new FixTracker(fixer, sourceCode).retainEnclosingFunction(node).replaceTextRange([elseToken.range[0], node.range[1]], fixedSource); } }); } /** * Check to see if the node is a ReturnStatement * * @param {Node} node The node being evaluated * @returns {boolean} True if node is a return */ function checkForReturn(node) { return node.type === "ReturnStatement"; } /** * Naive return checking, does not iterate through the whole * BlockStatement because we make the assumption that the ReturnStatement * will be the last node in the body of the BlockStatement. * * @param {Node} node The consequent/alternate node * @returns {boolean} True if it has a return */ function naiveHasReturn(node) { if (node.type === "BlockStatement") { var body = node.body, lastChildNode = body[body.length - 1]; return lastChildNode && checkForReturn(lastChildNode); } return checkForReturn(node); } /** * Check to see if the node is valid for evaluation, * meaning it has an else. * * @param {Node} node The node being evaluated * @returns {boolean} True if the node is valid */ function hasElse(node) { return node.alternate && node.consequent; } /** * If the consequent is an IfStatement, check to see if it has an else * and both its consequent and alternate path return, meaning this is * a nested case of rule violation. If-Else not considered currently. * * @param {Node} node The consequent node * @returns {boolean} True if this is a nested rule violation */ function checkForIf(node) { return node.type === "IfStatement" && hasElse(node) && naiveHasReturn(node.alternate) && naiveHasReturn(node.consequent); } /** * Check the consequent/body node to make sure it is not * a ReturnStatement or an IfStatement that returns on both * code paths. * * @param {Node} node The consequent or body node * @returns {boolean} `true` if it is a Return/If node that always returns. */ function checkForReturnOrIf(node) { return checkForReturn(node) || checkForIf(node); } /** * Check whether a node returns in every codepath. * @param {Node} node The node to be checked * @returns {boolean} `true` if it returns on every codepath. */ function alwaysReturns(node) { if (node.type === "BlockStatement") { // If we have a BlockStatement, check each consequent body node. return node.body.some(checkForReturnOrIf); } /* * If not a block statement, make sure the consequent isn't a * ReturnStatement or an IfStatement with returns on both paths. */ return checkForReturnOrIf(node); } /** * Check the if statement, but don't catch else-if blocks. * @returns {void} * @param {Node} node The node for the if statement to check * @private */ function checkIfWithoutElse(node) { var parent = node.parent; /* * Fixing this would require splitting one statement into two, so no error should * be reported if this node is in a position where only one statement is allowed. */ if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) { return; } var consequents = []; var alternate = void 0; for (var currentNode = node; currentNode.type === "IfStatement"; currentNode = currentNode.alternate) { if (!currentNode.alternate) { return; } consequents.push(currentNode.consequent); alternate = currentNode.alternate; } if (consequents.every(alwaysReturns)) { displayReport(alternate); } } /** * Check the if statement * @returns {void} * @param {Node} node The node for the if statement to check * @private */ function checkIfWithElse(node) { var parent = node.parent; /* * Fixing this would require splitting one statement into two, so no error should * be reported if this node is in a position where only one statement is allowed. */ if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) { return; } var alternate = node.alternate; if (alternate && alwaysReturns(node.consequent)) { displayReport(alternate); } } var allowElseIf = !(context.options[0] && context.options[0].allowElseIf === false); //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { "IfStatement:exit": allowElseIf ? checkIfWithoutElse : checkIfWithElse }; } }; },{"../util/ast-utils":405,"../util/fix-tracker":407}],223:[function(require,module,exports){ /** * @fileoverview Rule to flag the use of empty character classes in regular expressions * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /* * plain-English description of the following regexp: * 0. `^` fix the match at the beginning of the string * 1. `\/`: the `/` that begins the regexp * 2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following * 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes) * 2.1. `\\.`: an escape sequence * 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty * 3. `\/` the `/` that ends the regexp * 4. `[gimuy]*`: optional regexp flags * 5. `$`: fix the match at the end of the string */ var regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+])*\/[gimuys]*$/; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow empty character classes in regular expressions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-empty-character-class" }, schema: [], messages: { unexpected: "Empty class." } }, create: function create(context) { var sourceCode = context.getSourceCode(); return { Literal: function Literal(node) { var token = sourceCode.getFirstToken(node); if (token.type === "RegularExpression" && !regex.test(token.value)) { context.report({ node: node, messageId: "unexpected" }); } } }; } }; },{}],224:[function(require,module,exports){ /** * @fileoverview Rule to disallow empty functions. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var ALLOW_OPTIONS = Object.freeze(["functions", "arrowFunctions", "generatorFunctions", "methods", "generatorMethods", "getters", "setters", "constructors"]); /** * Gets the kind of a given function node. * * @param {ASTNode} node - A function node to get. This is one of * an ArrowFunctionExpression, a FunctionDeclaration, or a * FunctionExpression. * @returns {string} The kind of the function. This is one of "functions", * "arrowFunctions", "generatorFunctions", "asyncFunctions", "methods", * "generatorMethods", "asyncMethods", "getters", "setters", and * "constructors". */ function getKind(node) { var parent = node.parent; var kind = ""; if (node.type === "ArrowFunctionExpression") { return "arrowFunctions"; } // Detects main kind. if (parent.type === "Property") { if (parent.kind === "get") { return "getters"; } if (parent.kind === "set") { return "setters"; } kind = parent.method ? "methods" : "functions"; } else if (parent.type === "MethodDefinition") { if (parent.kind === "get") { return "getters"; } if (parent.kind === "set") { return "setters"; } if (parent.kind === "constructor") { return "constructors"; } kind = "methods"; } else { kind = "functions"; } // Detects prefix. var prefix = ""; if (node.generator) { prefix = "generator"; } else if (node.async) { prefix = "async"; } else { return kind; } return prefix + kind[0].toUpperCase() + kind.slice(1); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow empty functions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-empty-function" }, schema: [{ type: "object", properties: { allow: { type: "array", items: { enum: ALLOW_OPTIONS }, uniqueItems: true } }, additionalProperties: false }], messages: { unexpected: "Unexpected empty {{name}}." } }, create: function create(context) { var options = context.options[0] || {}; var allowed = options.allow || []; var sourceCode = context.getSourceCode(); /** * Reports a given function node if the node matches the following patterns. * * - Not allowed by options. * - The body is empty. * - The body doesn't have any comments. * * @param {ASTNode} node - A function node to report. This is one of * an ArrowFunctionExpression, a FunctionDeclaration, or a * FunctionExpression. * @returns {void} */ function reportIfEmpty(node) { var kind = getKind(node); var name = astUtils.getFunctionNameWithKind(node); var innerComments = sourceCode.getTokens(node.body, { includeComments: true, filter: astUtils.isCommentToken }); if (allowed.indexOf(kind) === -1 && node.body.type === "BlockStatement" && node.body.body.length === 0 && innerComments.length === 0) { context.report({ node: node, loc: node.body.loc.start, messageId: "unexpected", data: { name: name } }); } } return { ArrowFunctionExpression: reportIfEmpty, FunctionDeclaration: reportIfEmpty, FunctionExpression: reportIfEmpty }; } }; },{"../util/ast-utils":405}],225:[function(require,module,exports){ /** * @fileoverview Rule to disallow an empty pattern * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow empty destructuring patterns", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-empty-pattern" }, schema: [], messages: { unexpected: "Unexpected empty {{type}} pattern." } }, create: function create(context) { return { ObjectPattern: function ObjectPattern(node) { if (node.properties.length === 0) { context.report({ node: node, messageId: "unexpected", data: { type: "object" } }); } }, ArrayPattern: function ArrayPattern(node) { if (node.elements.length === 0) { context.report({ node: node, messageId: "unexpected", data: { type: "array" } }); } } }; } }; },{}],226:[function(require,module,exports){ /** * @fileoverview Rule to flag use of an empty block statement * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow empty block statements", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-empty" }, schema: [{ type: "object", properties: { allowEmptyCatch: { type: "boolean" } }, additionalProperties: false }], messages: { unexpected: "Empty {{type}} statement." } }, create: function create(context) { var options = context.options[0] || {}, allowEmptyCatch = options.allowEmptyCatch || false; var sourceCode = context.getSourceCode(); return { BlockStatement: function BlockStatement(node) { // if the body is not empty, we can just return immediately if (node.body.length !== 0) { return; } // a function is generally allowed to be empty if (astUtils.isFunction(node.parent)) { return; } if (allowEmptyCatch && node.parent.type === "CatchClause") { return; } // any other block is only allowed to be empty, if it contains a comment if (sourceCode.getCommentsInside(node).length > 0) { return; } context.report({ node: node, messageId: "unexpected", data: { type: "block" } }); }, SwitchStatement: function SwitchStatement(node) { if (typeof node.cases === "undefined" || node.cases.length === 0) { context.report({ node: node, messageId: "unexpected", data: { type: "switch" } }); } } }; } }; },{"../util/ast-utils":405}],227:[function(require,module,exports){ /** * @fileoverview Rule to flag comparisons to null without a type-checking * operator. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `null` comparisons without type-checking operators", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-eq-null" }, schema: [], messages: { unexpected: "Use '===' to compare with null." } }, create: function create(context) { return { BinaryExpression: function BinaryExpression(node) { var badOperator = node.operator === "==" || node.operator === "!="; if (node.right.type === "Literal" && node.right.raw === "null" && badOperator || node.left.type === "Literal" && node.left.raw === "null" && badOperator) { context.report({ node: node, messageId: "unexpected" }); } } }; } }; },{}],228:[function(require,module,exports){ /** * @fileoverview Rule to flag use of eval() statement * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var candidatesOfGlobalObject = Object.freeze(["global", "window"]); /** * Checks a given node is a Identifier node of the specified name. * * @param {ASTNode} node - A node to check. * @param {string} name - A name to check. * @returns {boolean} `true` if the node is a Identifier node of the name. */ function isIdentifier(node, name) { return node.type === "Identifier" && node.name === name; } /** * Checks a given node is a Literal node of the specified string value. * * @param {ASTNode} node - A node to check. * @param {string} name - A name to check. * @returns {boolean} `true` if the node is a Literal node of the name. */ function isConstant(node, name) { switch (node.type) { case "Literal": return node.value === name; case "TemplateLiteral": return node.expressions.length === 0 && node.quasis[0].value.cooked === name; default: return false; } } /** * Checks a given node is a MemberExpression node which has the specified name's * property. * * @param {ASTNode} node - A node to check. * @param {string} name - A name to check. * @returns {boolean} `true` if the node is a MemberExpression node which has * the specified name's property */ function isMember(node, name) { return node.type === "MemberExpression" && (node.computed ? isConstant : isIdentifier)(node.property, name); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `eval()`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-eval" }, schema: [{ type: "object", properties: { allowIndirect: { type: "boolean" } }, additionalProperties: false }], messages: { unexpected: "eval can be harmful." } }, create: function create(context) { var allowIndirect = Boolean(context.options[0] && context.options[0].allowIndirect); var sourceCode = context.getSourceCode(); var funcInfo = null; /** * Pushs a variable scope (Program or Function) information to the stack. * * This is used in order to check whether or not `this` binding is a * reference to the global object. * * @param {ASTNode} node - A node of the scope. This is one of Program, * FunctionDeclaration, FunctionExpression, and ArrowFunctionExpression. * @returns {void} */ function enterVarScope(node) { var strict = context.getScope().isStrict; funcInfo = { upper: funcInfo, node: node, strict: strict, defaultThis: false, initialized: strict }; } /** * Pops a variable scope from the stack. * * @returns {void} */ function exitVarScope() { funcInfo = funcInfo.upper; } /** * Reports a given node. * * `node` is `Identifier` or `MemberExpression`. * The parent of `node` might be `CallExpression`. * * The location of the report is always `eval` `Identifier` (or possibly * `Literal`). The type of the report is `CallExpression` if the parent is * `CallExpression`. Otherwise, it's the given node type. * * @param {ASTNode} node - A node to report. * @returns {void} */ function report(node) { var parent = node.parent; var locationNode = node.type === "MemberExpression" ? node.property : node; var reportNode = parent.type === "CallExpression" && parent.callee === node ? parent : node; context.report({ node: reportNode, loc: locationNode.loc.start, messageId: "unexpected" }); } /** * Reports accesses of `eval` via the global object. * * @param {eslint-scope.Scope} globalScope - The global scope. * @returns {void} */ function reportAccessingEvalViaGlobalObject(globalScope) { for (var i = 0; i < candidatesOfGlobalObject.length; ++i) { var name = candidatesOfGlobalObject[i]; var variable = astUtils.getVariableByName(globalScope, name); if (!variable) { continue; } var references = variable.references; for (var j = 0; j < references.length; ++j) { var identifier = references[j].identifier; var node = identifier.parent; // To detect code like `window.window.eval`. while (isMember(node, name)) { node = node.parent; } // Reports. if (isMember(node, "eval")) { report(node); } } } } /** * Reports all accesses of `eval` (excludes direct calls to eval). * * @param {eslint-scope.Scope} globalScope - The global scope. * @returns {void} */ function reportAccessingEval(globalScope) { var variable = astUtils.getVariableByName(globalScope, "eval"); if (!variable) { return; } var references = variable.references; for (var i = 0; i < references.length; ++i) { var reference = references[i]; var id = reference.identifier; if (id.name === "eval" && !astUtils.isCallee(id)) { // Is accessing to eval (excludes direct calls to eval) report(id); } } } if (allowIndirect) { // Checks only direct calls to eval. It's simple! return { "CallExpression:exit": function CallExpressionExit(node) { var callee = node.callee; if (isIdentifier(callee, "eval")) { report(callee); } } }; } return { "CallExpression:exit": function CallExpressionExit(node) { var callee = node.callee; if (isIdentifier(callee, "eval")) { report(callee); } }, Program: function Program(node) { var scope = context.getScope(), features = context.parserOptions.ecmaFeatures || {}, strict = scope.isStrict || node.sourceType === "module" || features.globalReturn && scope.childScopes[0].isStrict; funcInfo = { upper: null, node: node, strict: strict, defaultThis: true, initialized: true }; }, "Program:exit": function ProgramExit() { var globalScope = context.getScope(); exitVarScope(); reportAccessingEval(globalScope); reportAccessingEvalViaGlobalObject(globalScope); }, FunctionDeclaration: enterVarScope, "FunctionDeclaration:exit": exitVarScope, FunctionExpression: enterVarScope, "FunctionExpression:exit": exitVarScope, ArrowFunctionExpression: enterVarScope, "ArrowFunctionExpression:exit": exitVarScope, ThisExpression: function ThisExpression(node) { if (!isMember(node.parent, "eval")) { return; } /* * `this.eval` is found. * Checks whether or not the value of `this` is the global object. */ if (!funcInfo.initialized) { funcInfo.initialized = true; funcInfo.defaultThis = astUtils.isDefaultThisBinding(funcInfo.node, sourceCode); } if (!funcInfo.strict && funcInfo.defaultThis) { // `this.eval` is possible built-in `eval`. report(node.parent); } } }; } }; },{"../util/ast-utils":405}],229:[function(require,module,exports){ /** * @fileoverview Rule to flag assignment of the exception parameter * @author Stephen Murray */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow reassigning exceptions in `catch` clauses", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-ex-assign" }, schema: [], messages: { unexpected: "Do not assign to the exception parameter." } }, create: function create(context) { /** * Finds and reports references that are non initializer and writable. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { astUtils.getModifyingReferences(variable.references).forEach(function (reference) { context.report({ node: reference.identifier, messageId: "unexpected" }); }); } return { CatchClause: function CatchClause(node) { context.getDeclaredVariables(node).forEach(checkVariable); } }; } }; },{"../util/ast-utils":405}],230:[function(require,module,exports){ /** * @fileoverview Rule to flag adding properties to native object's prototypes. * @author David Nelson */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); var globals = require("globals"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var propertyDefinitionMethods = new Set(["defineProperty", "defineProperties"]); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow extending native types", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-extend-native" }, schema: [{ type: "object", properties: { exceptions: { type: "array", items: { type: "string" }, uniqueItems: true } }, additionalProperties: false }], messages: { unexpected: "{{builtin}} prototype is read only, properties should not be added." } }, create: function create(context) { var config = context.options[0] || {}; var exceptions = new Set(config.exceptions || []); var modifiedBuiltins = new Set(Object.keys(globals.builtin).filter(function (builtin) { return builtin[0].toUpperCase() === builtin[0]; }).filter(function (builtin) { return !exceptions.has(builtin); })); /** * Reports a lint error for the given node. * @param {ASTNode} node The node to report. * @param {string} builtin The name of the native builtin being extended. * @returns {void} */ function reportNode(node, builtin) { context.report({ node: node, messageId: "unexpected", data: { builtin: builtin } }); } /** * Check to see if the `prototype` property of the given object * identifier node is being accessed. * @param {ASTNode} identifierNode The Identifier representing the object * to check. * @returns {boolean} True if the identifier is the object of a * MemberExpression and its `prototype` property is being accessed, * false otherwise. */ function isPrototypePropertyAccessed(identifierNode) { return Boolean(identifierNode && identifierNode.parent && identifierNode.parent.type === "MemberExpression" && identifierNode.parent.object === identifierNode && astUtils.getStaticPropertyName(identifierNode.parent) === "prototype"); } /** * Checks that an identifier is an object of a prototype whose member * is being assigned in an AssignmentExpression. * Example: Object.prototype.foo = "bar" * @param {ASTNode} identifierNode The identifier to check. * @returns {boolean} True if the identifier's prototype is modified. */ function isInPrototypePropertyAssignment(identifierNode) { return Boolean(isPrototypePropertyAccessed(identifierNode) && identifierNode.parent.parent.type === "MemberExpression" && identifierNode.parent.parent.parent.type === "AssignmentExpression" && identifierNode.parent.parent.parent.left === identifierNode.parent.parent); } /** * Checks that an identifier is an object of a prototype whose member * is being extended via the Object.defineProperty() or * Object.defineProperties() methods. * Example: Object.defineProperty(Array.prototype, "foo", ...) * Example: Object.defineProperties(Array.prototype, ...) * @param {ASTNode} identifierNode The identifier to check. * @returns {boolean} True if the identifier's prototype is modified. */ function isInDefinePropertyCall(identifierNode) { return Boolean(isPrototypePropertyAccessed(identifierNode) && identifierNode.parent.parent.type === "CallExpression" && identifierNode.parent.parent.arguments[0] === identifierNode.parent && identifierNode.parent.parent.callee.type === "MemberExpression" && identifierNode.parent.parent.callee.object.type === "Identifier" && identifierNode.parent.parent.callee.object.name === "Object" && identifierNode.parent.parent.callee.property.type === "Identifier" && propertyDefinitionMethods.has(identifierNode.parent.parent.callee.property.name)); } /** * Check to see if object prototype access is part of a prototype * extension. There are three ways a prototype can be extended: * 1. Assignment to prototype property (Object.prototype.foo = 1) * 2. Object.defineProperty()/Object.defineProperties() on a prototype * If prototype extension is detected, report the AssignmentExpression * or CallExpression node. * @param {ASTNode} identifierNode The Identifier representing the object * which prototype is being accessed and possibly extended. * @returns {void} */ function checkAndReportPrototypeExtension(identifierNode) { if (isInPrototypePropertyAssignment(identifierNode)) { // Identifier --> MemberExpression --> MemberExpression --> AssignmentExpression reportNode(identifierNode.parent.parent.parent, identifierNode.name); } else if (isInDefinePropertyCall(identifierNode)) { // Identifier --> MemberExpression --> CallExpression reportNode(identifierNode.parent.parent, identifierNode.name); } } return { "Program:exit": function ProgramExit() { var globalScope = context.getScope(); modifiedBuiltins.forEach(function (builtin) { var builtinVar = globalScope.set.get(builtin); if (builtinVar && builtinVar.references) { builtinVar.references.map(function (ref) { return ref.identifier; }).forEach(checkAndReportPrototypeExtension); } }); } }; } }; },{"../util/ast-utils":405,"globals":85}],231:[function(require,module,exports){ /** * @fileoverview Rule to flag unnecessary bind calls * @author Bence Dányi */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var SIDE_EFFECT_FREE_NODE_TYPES = new Set(["Literal", "Identifier", "ThisExpression", "FunctionExpression"]); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary calls to `.bind()`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-extra-bind" }, schema: [], fixable: "code", messages: { unexpected: "The function binding is unnecessary." } }, create: function create(context) { var scopeInfo = null; /** * Checks if a node is free of side effects. * * This check is stricter than it needs to be, in order to keep the implementation simple. * * @param {ASTNode} node A node to check. * @returns {boolean} True if the node is known to be side-effect free, false otherwise. */ function isSideEffectFree(node) { return SIDE_EFFECT_FREE_NODE_TYPES.has(node.type); } /** * Reports a given function node. * * @param {ASTNode} node - A node to report. This is a FunctionExpression or * an ArrowFunctionExpression. * @returns {void} */ function report(node) { context.report({ node: node.parent.parent, messageId: "unexpected", loc: node.parent.property.loc.start, fix: function fix(fixer) { if (node.parent.parent.arguments.length && !isSideEffectFree(node.parent.parent.arguments[0])) { return null; } var firstTokenToRemove = context.getSourceCode().getFirstTokenBetween(node.parent.object, node.parent.property, astUtils.isNotClosingParenToken); return fixer.removeRange([firstTokenToRemove.range[0], node.parent.parent.range[1]]); } }); } /** * Checks whether or not a given function node is the callee of `.bind()` * method. * * e.g. `(function() {}.bind(foo))` * * @param {ASTNode} node - A node to report. This is a FunctionExpression or * an ArrowFunctionExpression. * @returns {boolean} `true` if the node is the callee of `.bind()` method. */ function isCalleeOfBindMethod(node) { var parent = node.parent; var grandparent = parent.parent; return grandparent && grandparent.type === "CallExpression" && grandparent.callee === parent && grandparent.arguments.length === 1 && parent.type === "MemberExpression" && parent.object === node && astUtils.getStaticPropertyName(parent) === "bind"; } /** * Adds a scope information object to the stack. * * @param {ASTNode} node - A node to add. This node is a FunctionExpression * or a FunctionDeclaration node. * @returns {void} */ function enterFunction(node) { scopeInfo = { isBound: isCalleeOfBindMethod(node), thisFound: false, upper: scopeInfo }; } /** * Removes the scope information object from the top of the stack. * At the same time, this reports the function node if the function has * `.bind()` and the `this` keywords found. * * @param {ASTNode} node - A node to remove. This node is a * FunctionExpression or a FunctionDeclaration node. * @returns {void} */ function exitFunction(node) { if (scopeInfo.isBound && !scopeInfo.thisFound) { report(node); } scopeInfo = scopeInfo.upper; } /** * Reports a given arrow function if the function is callee of `.bind()` * method. * * @param {ASTNode} node - A node to report. This node is an * ArrowFunctionExpression. * @returns {void} */ function exitArrowFunction(node) { if (isCalleeOfBindMethod(node)) { report(node); } } /** * Set the mark as the `this` keyword was found in this scope. * * @returns {void} */ function markAsThisFound() { if (scopeInfo) { scopeInfo.thisFound = true; } } return { "ArrowFunctionExpression:exit": exitArrowFunction, FunctionDeclaration: enterFunction, "FunctionDeclaration:exit": exitFunction, FunctionExpression: enterFunction, "FunctionExpression:exit": exitFunction, ThisExpression: markAsThisFound }; } }; },{"../util/ast-utils":405}],232:[function(require,module,exports){ /** * @fileoverview Rule to flag unnecessary double negation in Boolean contexts * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary boolean casts", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-extra-boolean-cast" }, schema: [], fixable: "code", messages: { unexpectedCall: "Redundant Boolean call.", unexpectedNegation: "Redundant double negation." } }, create: function create(context) { var sourceCode = context.getSourceCode(); // Node types which have a test which will coerce values to booleans. var BOOLEAN_NODE_TYPES = ["IfStatement", "DoWhileStatement", "WhileStatement", "ConditionalExpression", "ForStatement"]; /** * Check if a node is in a context where its value would be coerced to a boolean at runtime. * * @param {Object} node The node * @param {Object} parent Its parent * @returns {boolean} If it is in a boolean context */ function isInBooleanContext(node, parent) { return BOOLEAN_NODE_TYPES.indexOf(parent.type) !== -1 && node === parent.test || // ! parent.type === "UnaryExpression" && parent.operator === "!"; } return { UnaryExpression: function UnaryExpression(node) { var ancestors = context.getAncestors(), parent = ancestors.pop(), grandparent = ancestors.pop(); // Exit early if it's guaranteed not to match if (node.operator !== "!" || parent.type !== "UnaryExpression" || parent.operator !== "!") { return; } if (isInBooleanContext(parent, grandparent) || // Boolean() and new Boolean() (grandparent.type === "CallExpression" || grandparent.type === "NewExpression") && grandparent.callee.type === "Identifier" && grandparent.callee.name === "Boolean") { context.report({ node: node, messageId: "unexpectedNegation", fix: function fix(fixer) { return fixer.replaceText(parent, sourceCode.getText(node.argument)); } }); } }, CallExpression: function CallExpression(node) { var parent = node.parent; if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") { return; } if (isInBooleanContext(node, parent)) { context.report({ node: node, messageId: "unexpectedCall", fix: function fix(fixer) { if (!node.arguments.length) { return fixer.replaceText(parent, "true"); } if (node.arguments.length > 1 || node.arguments[0].type === "SpreadElement") { return null; } var argument = node.arguments[0]; if (astUtils.getPrecedence(argument) < astUtils.getPrecedence(node.parent)) { return fixer.replaceText(node, "(" + sourceCode.getText(argument) + ")"); } return fixer.replaceText(node, sourceCode.getText(argument)); } }); } } }; } }; },{"../util/ast-utils":405}],233:[function(require,module,exports){ /** * @fileoverview Rule to disallow unnecessary labels * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary labels", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-extra-label" }, schema: [], fixable: "code", messages: { unexpected: "This label '{{name}}' is unnecessary." } }, create: function create(context) { var sourceCode = context.getSourceCode(); var scopeInfo = null; /** * Creates a new scope with a breakable statement. * * @param {ASTNode} node - A node to create. This is a BreakableStatement. * @returns {void} */ function enterBreakableStatement(node) { scopeInfo = { label: node.parent.type === "LabeledStatement" ? node.parent.label : null, breakable: true, upper: scopeInfo }; } /** * Removes the top scope of the stack. * * @returns {void} */ function exitBreakableStatement() { scopeInfo = scopeInfo.upper; } /** * Creates a new scope with a labeled statement. * * This ignores it if the body is a breakable statement. * In this case it's handled in the `enterBreakableStatement` function. * * @param {ASTNode} node - A node to create. This is a LabeledStatement. * @returns {void} */ function enterLabeledStatement(node) { if (!astUtils.isBreakableStatement(node.body)) { scopeInfo = { label: node.label, breakable: false, upper: scopeInfo }; } } /** * Removes the top scope of the stack. * * This ignores it if the body is a breakable statement. * In this case it's handled in the `exitBreakableStatement` function. * * @param {ASTNode} node - A node. This is a LabeledStatement. * @returns {void} */ function exitLabeledStatement(node) { if (!astUtils.isBreakableStatement(node.body)) { scopeInfo = scopeInfo.upper; } } /** * Reports a given control node if it's unnecessary. * * @param {ASTNode} node - A node. This is a BreakStatement or a * ContinueStatement. * @returns {void} */ function reportIfUnnecessary(node) { if (!node.label) { return; } var labelNode = node.label; for (var info = scopeInfo; info !== null; info = info.upper) { if (info.breakable || info.label && info.label.name === labelNode.name) { if (info.breakable && info.label && info.label.name === labelNode.name) { context.report({ node: labelNode, messageId: "unexpected", data: labelNode, fix: function fix(fixer) { return fixer.removeRange([sourceCode.getFirstToken(node).range[1], labelNode.range[1]]); } }); } return; } } } return { WhileStatement: enterBreakableStatement, "WhileStatement:exit": exitBreakableStatement, DoWhileStatement: enterBreakableStatement, "DoWhileStatement:exit": exitBreakableStatement, ForStatement: enterBreakableStatement, "ForStatement:exit": exitBreakableStatement, ForInStatement: enterBreakableStatement, "ForInStatement:exit": exitBreakableStatement, ForOfStatement: enterBreakableStatement, "ForOfStatement:exit": exitBreakableStatement, SwitchStatement: enterBreakableStatement, "SwitchStatement:exit": exitBreakableStatement, LabeledStatement: enterLabeledStatement, "LabeledStatement:exit": exitLabeledStatement, BreakStatement: reportIfUnnecessary, ContinueStatement: reportIfUnnecessary }; } }; },{"../util/ast-utils":405}],234:[function(require,module,exports){ /** * @fileoverview Disallow parenthesising higher precedence subexpressions. * @author Michael Ficarra */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils.js"); module.exports = { meta: { type: "layout", docs: { description: "disallow unnecessary parentheses", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-extra-parens" }, fixable: "code", schema: { anyOf: [{ type: "array", items: [{ enum: ["functions"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["all"] }, { type: "object", properties: { conditionalAssign: { type: "boolean" }, nestedBinaryExpressions: { type: "boolean" }, returnAssign: { type: "boolean" }, ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] }, enforceForArrowConditionals: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] }, messages: { unexpected: "Unnecessary parentheses around expression." } }, create: function create(context) { var sourceCode = context.getSourceCode(); var tokensToIgnore = new WeakSet(); var isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode); var precedence = astUtils.getPrecedence; var ALL_NODES = context.options[0] !== "functions"; var EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false; var NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false; var EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false; var IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX; var IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] && context.options[1].enforceForArrowConditionals === false; var PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" }); var PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" }); /** * Determines if this rule should be enforced for a node given the current configuration. * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the rule should be enforced for this node. * @private */ function ruleApplies(node) { if (node.type === "JSXElement" || node.type === "JSXFragment") { var isSingleLine = node.loc.start.line === node.loc.end.line; switch (IGNORE_JSX) { // Exclude this JSX element from linting case "all": return false; // Exclude this JSX element if it is multi-line element case "multi-line": return isSingleLine; // Exclude this JSX element if it is single-line element case "single-line": return !isSingleLine; // Nothing special to be done for JSX elements case "none": break; // no default } } return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; } /** * Determines if a node is surrounded by parentheses twice. * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the node is doubly parenthesised. * @private */ function isParenthesisedTwice(node) { var previousToken = sourceCode.getTokenBefore(node, 1), nextToken = sourceCode.getTokenAfter(node, 1); return isParenthesised(node) && previousToken && nextToken && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; } /** * Determines if a node is surrounded by (potentially) invalid parentheses. * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the node is incorrectly parenthesised. * @private */ function hasExcessParens(node) { return ruleApplies(node) && isParenthesised(node); } /** * Determines if a node that is expected to be parenthesised is surrounded by * (potentially) invalid extra parentheses. * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the node is has an unexpected extra pair of parentheses. * @private */ function hasDoubleExcessParens(node) { return ruleApplies(node) && isParenthesisedTwice(node); } /** * Determines if a node test expression is allowed to have a parenthesised assignment * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the assignment can be parenthesised. * @private */ function isCondAssignException(node) { return EXCEPT_COND_ASSIGN && node.test.type === "AssignmentExpression"; } /** * Determines if a node is in a return statement * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the node is in a return statement. * @private */ function isInReturnStatement(node) { for (var currentNode = node; currentNode; currentNode = currentNode.parent) { if (currentNode.type === "ReturnStatement" || currentNode.type === "ArrowFunctionExpression" && currentNode.body.type !== "BlockStatement") { return true; } } return false; } /** * Determines if a constructor function is newed-up with parens * @param {ASTNode} newExpression - The NewExpression node to be checked. * @returns {boolean} True if the constructor is called with parens. * @private */ function isNewExpressionWithParens(newExpression) { var lastToken = sourceCode.getLastToken(newExpression); var penultimateToken = sourceCode.getTokenBefore(lastToken); return newExpression.arguments.length > 0 || astUtils.isOpeningParenToken(penultimateToken) && astUtils.isClosingParenToken(lastToken); } /** * Determines if a node is or contains an assignment expression * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the node is or contains an assignment expression. * @private */ function containsAssignment(node) { if (node.type === "AssignmentExpression") { return true; } if (node.type === "ConditionalExpression" && (node.consequent.type === "AssignmentExpression" || node.alternate.type === "AssignmentExpression")) { return true; } if (node.left && node.left.type === "AssignmentExpression" || node.right && node.right.type === "AssignmentExpression") { return true; } return false; } /** * Determines if a node is contained by or is itself a return statement and is allowed to have a parenthesised assignment * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the assignment can be parenthesised. * @private */ function isReturnAssignException(node) { if (!EXCEPT_RETURN_ASSIGN || !isInReturnStatement(node)) { return false; } if (node.type === "ReturnStatement") { return node.argument && containsAssignment(node.argument); } if (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") { return containsAssignment(node.body); } return containsAssignment(node); } /** * Determines if a node following a [no LineTerminator here] restriction is * surrounded by (potentially) invalid extra parentheses. * @param {Token} token - The token preceding the [no LineTerminator here] restriction. * @param {ASTNode} node - The node to be checked. * @returns {boolean} True if the node is incorrectly parenthesised. * @private */ function hasExcessParensNoLineTerminator(token, node) { if (token.loc.end.line === node.loc.start.line) { return hasExcessParens(node); } return hasDoubleExcessParens(node); } /** * Determines whether a node should be preceded by an additional space when removing parens * @param {ASTNode} node node to evaluate; must be surrounded by parentheses * @returns {boolean} `true` if a space should be inserted before the node * @private */ function requiresLeadingSpace(node) { var leftParenToken = sourceCode.getTokenBefore(node); var tokenBeforeLeftParen = sourceCode.getTokenBefore(node, 1); var firstToken = sourceCode.getFirstToken(node); return tokenBeforeLeftParen && tokenBeforeLeftParen.range[1] === leftParenToken.range[0] && leftParenToken.range[1] === firstToken.range[0] && !astUtils.canTokensBeAdjacent(tokenBeforeLeftParen, firstToken); } /** * Determines whether a node should be followed by an additional space when removing parens * @param {ASTNode} node node to evaluate; must be surrounded by parentheses * @returns {boolean} `true` if a space should be inserted after the node * @private */ function requiresTrailingSpace(node) { var nextTwoTokens = sourceCode.getTokensAfter(node, { count: 2 }); var rightParenToken = nextTwoTokens[0]; var tokenAfterRightParen = nextTwoTokens[1]; var tokenBeforeRightParen = sourceCode.getLastToken(node); return rightParenToken && tokenAfterRightParen && !sourceCode.isSpaceBetweenTokens(rightParenToken, tokenAfterRightParen) && !astUtils.canTokensBeAdjacent(tokenBeforeRightParen, tokenAfterRightParen); } /** * Determines if a given expression node is an IIFE * @param {ASTNode} node The node to check * @returns {boolean} `true` if the given node is an IIFE */ function isIIFE(node) { return node.type === "CallExpression" && node.callee.type === "FunctionExpression"; } /** * Report the node * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function report(node) { var leftParenToken = sourceCode.getTokenBefore(node); var rightParenToken = sourceCode.getTokenAfter(node); if (!isParenthesisedTwice(node)) { if (tokensToIgnore.has(sourceCode.getFirstToken(node))) { return; } if (isIIFE(node) && !isParenthesised(node.callee)) { return; } } context.report({ node: node, loc: leftParenToken.loc.start, messageId: "unexpected", fix: function fix(fixer) { var parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]); return fixer.replaceTextRange([leftParenToken.range[0], rightParenToken.range[1]], (requiresLeadingSpace(node) ? " " : "") + parenthesizedSource + (requiresTrailingSpace(node) ? " " : "")); } }); } /** * Evaluate Unary update * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkUnaryUpdate(node) { if (node.type === "UnaryExpression" && node.argument.type === "BinaryExpression" && node.argument.operator === "**") { return; } if (hasExcessParens(node.argument) && precedence(node.argument) >= precedence(node)) { report(node.argument); } } /** * Check if a member expression contains a call expression * @param {ASTNode} node MemberExpression node to evaluate * @returns {boolean} true if found, false if not */ function doesMemberExpressionContainCallExpression(node) { var currentNode = node.object; var currentNodeType = node.object.type; while (currentNodeType === "MemberExpression") { currentNode = currentNode.object; currentNodeType = currentNode.type; } return currentNodeType === "CallExpression"; } /** * Evaluate a new call * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkCallNew(node) { var callee = node.callee; if (hasExcessParens(callee) && precedence(callee) >= precedence(node)) { var hasNewParensException = callee.type === "NewExpression" && !isNewExpressionWithParens(callee); if (hasDoubleExcessParens(callee) || !isIIFE(node) && !hasNewParensException && !( /* * Allow extra parens around a new expression if * there are intervening parentheses. */ callee.type === "MemberExpression" && doesMemberExpressionContainCallExpression(callee))) { report(node.callee); } } if (node.arguments.length === 1) { if (hasDoubleExcessParens(node.arguments[0]) && precedence(node.arguments[0]) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) { report(node.arguments[0]); } } else { node.arguments.filter(function (arg) { return hasExcessParens(arg) && precedence(arg) >= PRECEDENCE_OF_ASSIGNMENT_EXPR; }).forEach(report); } } /** * Evaluate binary logicals * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkBinaryLogical(node) { var prec = precedence(node); var leftPrecedence = precedence(node.left); var rightPrecedence = precedence(node.right); var isExponentiation = node.operator === "**"; var shouldSkipLeft = NESTED_BINARY && (node.left.type === "BinaryExpression" || node.left.type === "LogicalExpression") || node.left.type === "UnaryExpression" && isExponentiation; var shouldSkipRight = NESTED_BINARY && (node.right.type === "BinaryExpression" || node.right.type === "LogicalExpression"); if (!shouldSkipLeft && hasExcessParens(node.left) && (leftPrecedence > prec || leftPrecedence === prec && !isExponentiation)) { report(node.left); } if (!shouldSkipRight && hasExcessParens(node.right) && (rightPrecedence > prec || rightPrecedence === prec && isExponentiation)) { report(node.right); } } /** * Check the parentheses around the super class of the given class definition. * @param {ASTNode} node The node of class declarations to check. * @returns {void} */ function checkClass(node) { if (!node.superClass) { return; } /* * If `node.superClass` is a LeftHandSideExpression, parentheses are extra. * Otherwise, parentheses are needed. */ var hasExtraParens = precedence(node.superClass) > PRECEDENCE_OF_UPDATE_EXPR ? hasExcessParens(node.superClass) : hasDoubleExcessParens(node.superClass); if (hasExtraParens) { report(node.superClass); } } /** * Check the parentheses around the argument of the given spread operator. * @param {ASTNode} node The node of spread elements/properties to check. * @returns {void} */ function checkSpreadOperator(node) { var hasExtraParens = precedence(node.argument) >= PRECEDENCE_OF_ASSIGNMENT_EXPR ? hasExcessParens(node.argument) : hasDoubleExcessParens(node.argument); if (hasExtraParens) { report(node.argument); } } /** * Checks the parentheses for an ExpressionStatement or ExportDefaultDeclaration * @param {ASTNode} node The ExpressionStatement.expression or ExportDefaultDeclaration.declaration node * @returns {void} */ function checkExpressionOrExportStatement(node) { var firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node); var secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken); var thirdToken = secondToken ? sourceCode.getTokenAfter(secondToken) : null; if (astUtils.isOpeningParenToken(firstToken) && (astUtils.isOpeningBraceToken(secondToken) || secondToken.type === "Keyword" && (secondToken.value === "function" || secondToken.value === "class" || secondToken.value === "let" && astUtils.isOpeningBracketToken(sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken))) || secondToken && secondToken.type === "Identifier" && secondToken.value === "async" && thirdToken && thirdToken.type === "Keyword" && thirdToken.value === "function")) { tokensToIgnore.add(secondToken); } if (hasExcessParens(node)) { report(node); } } return { ArrayExpression: function ArrayExpression(node) { node.elements.filter(function (e) { return e && hasExcessParens(e) && precedence(e) >= PRECEDENCE_OF_ASSIGNMENT_EXPR; }).forEach(report); }, ArrowFunctionExpression: function ArrowFunctionExpression(node) { if (isReturnAssignException(node)) { return; } if (node.body.type === "ConditionalExpression" && IGNORE_ARROW_CONDITIONALS && !isParenthesisedTwice(node.body)) { return; } if (node.body.type !== "BlockStatement") { var firstBodyToken = sourceCode.getFirstToken(node.body, astUtils.isNotOpeningParenToken); var tokenBeforeFirst = sourceCode.getTokenBefore(firstBodyToken); if (astUtils.isOpeningParenToken(tokenBeforeFirst) && astUtils.isOpeningBraceToken(firstBodyToken)) { tokensToIgnore.add(firstBodyToken); } if (hasExcessParens(node.body) && precedence(node.body) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) { report(node.body); } } }, AssignmentExpression: function AssignmentExpression(node) { if (isReturnAssignException(node)) { return; } if (hasExcessParens(node.right) && precedence(node.right) >= precedence(node)) { report(node.right); } }, BinaryExpression: checkBinaryLogical, CallExpression: checkCallNew, ConditionalExpression: function ConditionalExpression(node) { if (isReturnAssignException(node)) { return; } if (hasExcessParens(node.test) && precedence(node.test) >= precedence({ type: "LogicalExpression", operator: "||" })) { report(node.test); } if (hasExcessParens(node.consequent) && precedence(node.consequent) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) { report(node.consequent); } if (hasExcessParens(node.alternate) && precedence(node.alternate) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) { report(node.alternate); } }, DoWhileStatement: function DoWhileStatement(node) { if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { report(node.test); } }, ExportDefaultDeclaration: function ExportDefaultDeclaration(node) { return checkExpressionOrExportStatement(node.declaration); }, ExpressionStatement: function ExpressionStatement(node) { return checkExpressionOrExportStatement(node.expression); }, "ForInStatement, ForOfStatement": function ForInStatementForOfStatement(node) { if (node.left.type !== "VariableDeclarator") { var firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); if (firstLeftToken.value === "let" && ( /* * If `let` is the only thing on the left side of the loop, it's the loop variable: `for ((let) of foo);` * Removing it will cause a syntax error, because it will be parsed as the start of a VariableDeclarator. */ firstLeftToken.range[1] === node.left.range[1] || /* * If `let` is followed by a `[` token, it's a property access on the `let` value: `for ((let[foo]) of bar);` * Removing it will cause the property access to be parsed as a destructuring declaration of `foo` instead. */ astUtils.isOpeningBracketToken(sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken)))) { tokensToIgnore.add(firstLeftToken); } } if (!(node.type === "ForOfStatement" && node.right.type === "SequenceExpression") && hasExcessParens(node.right)) { report(node.right); } if (hasExcessParens(node.left)) { report(node.left); } }, ForStatement: function ForStatement(node) { if (node.init && hasExcessParens(node.init)) { report(node.init); } if (node.test && hasExcessParens(node.test) && !isCondAssignException(node)) { report(node.test); } if (node.update && hasExcessParens(node.update)) { report(node.update); } }, IfStatement: function IfStatement(node) { if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { report(node.test); } }, LogicalExpression: checkBinaryLogical, MemberExpression: function MemberExpression(node) { var nodeObjHasExcessParens = hasExcessParens(node.object); if (nodeObjHasExcessParens && precedence(node.object) >= precedence(node) && (node.computed || !(astUtils.isDecimalInteger(node.object) || // RegExp literal is allowed to have parens (#1589) node.object.type === "Literal" && node.object.regex))) { report(node.object); } if (nodeObjHasExcessParens && node.object.type === "CallExpression" && node.parent.type !== "NewExpression") { report(node.object); } if (node.computed && hasExcessParens(node.property)) { report(node.property); } }, NewExpression: checkCallNew, ObjectExpression: function ObjectExpression(node) { node.properties.filter(function (property) { var value = property.value; return value && hasExcessParens(value) && precedence(value) >= PRECEDENCE_OF_ASSIGNMENT_EXPR; }).forEach(function (property) { return report(property.value); }); }, ReturnStatement: function ReturnStatement(node) { var returnToken = sourceCode.getFirstToken(node); if (isReturnAssignException(node)) { return; } if (node.argument && hasExcessParensNoLineTerminator(returnToken, node.argument) && // RegExp literal is allowed to have parens (#1589) !(node.argument.type === "Literal" && node.argument.regex)) { report(node.argument); } }, SequenceExpression: function SequenceExpression(node) { node.expressions.filter(function (e) { return hasExcessParens(e) && precedence(e) >= precedence(node); }).forEach(report); }, SwitchCase: function SwitchCase(node) { if (node.test && hasExcessParens(node.test)) { report(node.test); } }, SwitchStatement: function SwitchStatement(node) { if (hasDoubleExcessParens(node.discriminant)) { report(node.discriminant); } }, ThrowStatement: function ThrowStatement(node) { var throwToken = sourceCode.getFirstToken(node); if (hasExcessParensNoLineTerminator(throwToken, node.argument)) { report(node.argument); } }, UnaryExpression: checkUnaryUpdate, UpdateExpression: checkUnaryUpdate, AwaitExpression: checkUnaryUpdate, VariableDeclarator: function VariableDeclarator(node) { if (node.init && hasExcessParens(node.init) && precedence(node.init) >= PRECEDENCE_OF_ASSIGNMENT_EXPR && // RegExp literal is allowed to have parens (#1589) !(node.init.type === "Literal" && node.init.regex)) { report(node.init); } }, WhileStatement: function WhileStatement(node) { if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { report(node.test); } }, WithStatement: function WithStatement(node) { if (hasDoubleExcessParens(node.object)) { report(node.object); } }, YieldExpression: function YieldExpression(node) { if (node.argument) { var yieldToken = sourceCode.getFirstToken(node); if (precedence(node.argument) >= precedence(node) && hasExcessParensNoLineTerminator(yieldToken, node.argument) || hasDoubleExcessParens(node.argument)) { report(node.argument); } } }, ClassDeclaration: checkClass, ClassExpression: checkClass, SpreadElement: checkSpreadOperator, SpreadProperty: checkSpreadOperator, ExperimentalSpreadProperty: checkSpreadOperator }; } }; },{"../util/ast-utils.js":405}],235:[function(require,module,exports){ /** * @fileoverview Rule to flag use of unnecessary semicolons * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var FixTracker = require("../util/fix-tracker"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary semicolons", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-extra-semi" }, fixable: "code", schema: [], messages: { unexpected: "Unnecessary semicolon." } }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Reports an unnecessary semicolon error. * @param {Node|Token} nodeOrToken - A node or a token to be reported. * @returns {void} */ function report(nodeOrToken) { context.report({ node: nodeOrToken, messageId: "unexpected", fix: function fix(fixer) { /* * Expand the replacement range to include the surrounding * tokens to avoid conflicting with semi. * https://github.com/eslint/eslint/issues/7928 */ return new FixTracker(fixer, context.getSourceCode()).retainSurroundingTokens(nodeOrToken).remove(nodeOrToken); } }); } /** * Checks for a part of a class body. * This checks tokens from a specified token to a next MethodDefinition or the end of class body. * * @param {Token} firstToken - The first token to check. * @returns {void} */ function checkForPartOfClassBody(firstToken) { for (var token = firstToken; token.type === "Punctuator" && !astUtils.isClosingBraceToken(token); token = sourceCode.getTokenAfter(token)) { if (astUtils.isSemicolonToken(token)) { report(token); } } } return { /** * Reports this empty statement, except if the parent node is a loop. * @param {Node} node - A EmptyStatement node to be reported. * @returns {void} */ EmptyStatement: function EmptyStatement(node) { var parent = node.parent, allowedParentTypes = ["ForStatement", "ForInStatement", "ForOfStatement", "WhileStatement", "DoWhileStatement", "IfStatement", "LabeledStatement", "WithStatement"]; if (allowedParentTypes.indexOf(parent.type) === -1) { report(node); } }, /** * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body. * @param {Node} node - A ClassBody node to check. * @returns {void} */ ClassBody: function ClassBody(node) { checkForPartOfClassBody(sourceCode.getFirstToken(node, 1)); // 0 is `{`. }, /** * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body. * @param {Node} node - A MethodDefinition node of the start point. * @returns {void} */ MethodDefinition: function MethodDefinition(node) { checkForPartOfClassBody(sourceCode.getTokenAfter(node)); } }; } }; },{"../util/ast-utils":405,"../util/fix-tracker":407}],236:[function(require,module,exports){ /** * @fileoverview Rule to flag fall-through cases in switch statements. * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/i; /** * Checks whether or not a given node has a fallthrough comment. * @param {ASTNode} node - A SwitchCase node to get comments. * @param {RuleContext} context - A rule context which stores comments. * @param {RegExp} fallthroughCommentPattern - A pattern to match comment to. * @returns {boolean} `true` if the node has a valid fallthrough comment. */ function hasFallthroughComment(node, context, fallthroughCommentPattern) { var sourceCode = context.getSourceCode(); var comment = lodash.last(sourceCode.getCommentsBefore(node)); return Boolean(comment && fallthroughCommentPattern.test(comment.value)); } /** * Checks whether or not a given code path segment is reachable. * @param {CodePathSegment} segment - A CodePathSegment to check. * @returns {boolean} `true` if the segment is reachable. */ function isReachable(segment) { return segment.reachable; } /** * Checks whether a node and a token are separated by blank lines * @param {ASTNode} node - The node to check * @param {Token} token - The token to compare against * @returns {boolean} `true` if there are blank lines between node and token */ function hasBlankLinesBetween(node, token) { return token.loc.start.line > node.loc.end.line + 1; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow fallthrough of `case` statements", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-fallthrough" }, schema: [{ type: "object", properties: { commentPattern: { type: "string" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] || {}; var currentCodePath = null; var sourceCode = context.getSourceCode(); /* * We need to use leading comments of the next SwitchCase node because * trailing comments is wrong if semicolons are omitted. */ var fallthroughCase = null; var fallthroughCommentPattern = null; if (options.commentPattern) { fallthroughCommentPattern = new RegExp(options.commentPattern); } else { fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT; } return { onCodePathStart: function onCodePathStart(codePath) { currentCodePath = codePath; }, onCodePathEnd: function onCodePathEnd() { currentCodePath = currentCodePath.upper; }, SwitchCase: function SwitchCase(node) { /* * Checks whether or not there is a fallthrough comment. * And reports the previous fallthrough node if that does not exist. */ if (fallthroughCase && !hasFallthroughComment(node, context, fallthroughCommentPattern)) { context.report({ message: "Expected a 'break' statement before '{{type}}'.", data: { type: node.test ? "case" : "default" }, node: node }); } fallthroughCase = null; }, "SwitchCase:exit": function SwitchCaseExit(node) { var nextToken = sourceCode.getTokenAfter(node); /* * `reachable` meant fall through because statements preceded by * `break`, `return`, or `throw` are unreachable. * And allows empty cases and the last case. */ if (currentCodePath.currentSegments.some(isReachable) && (node.consequent.length > 0 || hasBlankLinesBetween(node, nextToken)) && lodash.last(node.parent.cases) !== node) { fallthroughCase = node; } } }; } }; },{"lodash":92}],237:[function(require,module,exports){ /** * @fileoverview Rule to flag use of a leading/trailing decimal point in a numeric literal * @author James Allardice */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow leading or trailing decimal points in numeric literals", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-floating-decimal" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { Literal: function Literal(node) { if (typeof node.value === "number") { if (node.raw.startsWith(".")) { context.report({ node: node, message: "A leading decimal point can be confused with a dot.", fix: function fix(fixer) { var tokenBefore = sourceCode.getTokenBefore(node); var needsSpaceBefore = tokenBefore && tokenBefore.range[1] === node.range[0] && !astUtils.canTokensBeAdjacent(tokenBefore, "0" + node.raw); return fixer.insertTextBefore(node, needsSpaceBefore ? " 0" : "0"); } }); } if (node.raw.indexOf(".") === node.raw.length - 1) { context.report({ node: node, message: "A trailing decimal point can be confused with a dot.", fix: function fix(fixer) { return fixer.insertTextAfter(node, "0"); } }); } } } }; } }; },{"../util/ast-utils":405}],238:[function(require,module,exports){ /** * @fileoverview Rule to flag use of function declaration identifiers as variables. * @author Ian Christian Myers */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow reassigning `function` declarations", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-func-assign" }, schema: [] }, create: function create(context) { /** * Reports a reference if is non initializer and writable. * @param {References} references - Collection of reference to check. * @returns {void} */ function checkReference(references) { astUtils.getModifyingReferences(references).forEach(function (reference) { context.report({ node: reference.identifier, message: "'{{name}}' is a function.", data: { name: reference.identifier.name } }); }); } /** * Finds and reports references that are non initializer and writable. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { if (variable.defs[0].type === "FunctionName") { checkReference(variable.references); } } /** * Checks parameters of a given function node. * @param {ASTNode} node - A function node to check. * @returns {void} */ function checkForFunction(node) { context.getDeclaredVariables(node).forEach(checkVariable); } return { FunctionDeclaration: checkForFunction, FunctionExpression: checkForFunction }; } }; },{"../util/ast-utils":405}],239:[function(require,module,exports){ /** * @fileoverview Rule to disallow assignments to native objects or read-only global variables * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow assignments to native objects or read-only global variables", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-global-assign" }, schema: [{ type: "object", properties: { exceptions: { type: "array", items: { type: "string" }, uniqueItems: true } }, additionalProperties: false }] }, create: function create(context) { var config = context.options[0]; var exceptions = config && config.exceptions || []; /** * Reports write references. * @param {Reference} reference - A reference to check. * @param {int} index - The index of the reference in the references. * @param {Reference[]} references - The array that the reference belongs to. * @returns {void} */ function checkReference(reference, index, references) { var identifier = reference.identifier; if (reference.init === false && reference.isWrite() && ( /* * Destructuring assignments can have multiple default value, * so possibly there are multiple writeable references for the same identifier. */ index === 0 || references[index - 1].identifier !== identifier)) { context.report({ node: identifier, message: "Read-only global '{{name}}' should not be modified.", data: identifier }); } } /** * Reports write references if a given variable is read-only builtin. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { variable.references.forEach(checkReference); } } return { Program: function Program() { var globalScope = context.getScope(); globalScope.variables.forEach(checkVariable); } }; } }; },{}],240:[function(require,module,exports){ /** * @fileoverview A rule to disallow the type conversions with shorter notations. * @author Toru Nagashima */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/; var ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; /** * Parses and normalizes an option object. * @param {Object} options - An option object to parse. * @returns {Object} The parsed and normalized option object. */ function parseOptions(options) { return { boolean: "boolean" in options ? Boolean(options.boolean) : true, number: "number" in options ? Boolean(options.number) : true, string: "string" in options ? Boolean(options.string) : true, allow: options.allow || [] }; } /** * Checks whether or not a node is a double logical nigating. * @param {ASTNode} node - An UnaryExpression node to check. * @returns {boolean} Whether or not the node is a double logical nigating. */ function isDoubleLogicalNegating(node) { return node.operator === "!" && node.argument.type === "UnaryExpression" && node.argument.operator === "!"; } /** * Checks whether or not a node is a binary negating of `.indexOf()` method calling. * @param {ASTNode} node - An UnaryExpression node to check. * @returns {boolean} Whether or not the node is a binary negating of `.indexOf()` method calling. */ function isBinaryNegatingOfIndexOf(node) { return node.operator === "~" && node.argument.type === "CallExpression" && node.argument.callee.type === "MemberExpression" && node.argument.callee.property.type === "Identifier" && INDEX_OF_PATTERN.test(node.argument.callee.property.name); } /** * Checks whether or not a node is a multiplying by one. * @param {BinaryExpression} node - A BinaryExpression node to check. * @returns {boolean} Whether or not the node is a multiplying by one. */ function isMultiplyByOne(node) { return node.operator === "*" && (node.left.type === "Literal" && node.left.value === 1 || node.right.type === "Literal" && node.right.value === 1); } /** * Checks whether the result of a node is numeric or not * @param {ASTNode} node The node to test * @returns {boolean} true if the node is a number literal or a `Number()`, `parseInt` or `parseFloat` call */ function isNumeric(node) { return node.type === "Literal" && typeof node.value === "number" || node.type === "CallExpression" && (node.callee.name === "Number" || node.callee.name === "parseInt" || node.callee.name === "parseFloat"); } /** * Returns the first non-numeric operand in a BinaryExpression. Designed to be * used from bottom to up since it walks up the BinaryExpression trees using * node.parent to find the result. * @param {BinaryExpression} node The BinaryExpression node to be walked up on * @returns {ASTNode|null} The first non-numeric item in the BinaryExpression tree or null */ function getNonNumericOperand(node) { var left = node.left, right = node.right; if (right.type !== "BinaryExpression" && !isNumeric(right)) { return right; } if (left.type !== "BinaryExpression" && !isNumeric(left)) { return left; } return null; } /** * Checks whether a node is an empty string literal or not. * @param {ASTNode} node The node to check. * @returns {boolean} Whether or not the passed in node is an * empty string literal or not. */ function isEmptyString(node) { return astUtils.isStringLiteral(node) && (node.value === "" || node.type === "TemplateLiteral" && node.quasis.length === 1 && node.quasis[0].value.cooked === ""); } /** * Checks whether or not a node is a concatenating with an empty string. * @param {ASTNode} node - A BinaryExpression node to check. * @returns {boolean} Whether or not the node is a concatenating with an empty string. */ function isConcatWithEmptyString(node) { return node.operator === "+" && (isEmptyString(node.left) && !astUtils.isStringLiteral(node.right) || isEmptyString(node.right) && !astUtils.isStringLiteral(node.left)); } /** * Checks whether or not a node is appended with an empty string. * @param {ASTNode} node - An AssignmentExpression node to check. * @returns {boolean} Whether or not the node is appended with an empty string. */ function isAppendEmptyString(node) { return node.operator === "+=" && isEmptyString(node.right); } /** * Returns the operand that is not an empty string from a flagged BinaryExpression. * @param {ASTNode} node - The flagged BinaryExpression node to check. * @returns {ASTNode} The operand that is not an empty string from a flagged BinaryExpression. */ function getNonEmptyOperand(node) { return isEmptyString(node.left) ? node.right : node.left; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow shorthand type conversions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-implicit-coercion" }, fixable: "code", schema: [{ type: "object", properties: { boolean: { type: "boolean" }, number: { type: "boolean" }, string: { type: "boolean" }, allow: { type: "array", items: { enum: ALLOWABLE_OPERATORS }, uniqueItems: true } }, additionalProperties: false }] }, create: function create(context) { var options = parseOptions(context.options[0] || {}); var sourceCode = context.getSourceCode(); /** * Reports an error and autofixes the node * @param {ASTNode} node - An ast node to report the error on. * @param {string} recommendation - The recommended code for the issue * @param {bool} shouldFix - Whether this report should fix the node * @returns {void} */ function report(node, recommendation, shouldFix) { context.report({ node: node, message: "use `{{recommendation}}` instead.", data: { recommendation: recommendation }, fix: function fix(fixer) { if (!shouldFix) { return null; } var tokenBefore = sourceCode.getTokenBefore(node); if (tokenBefore && tokenBefore.range[1] === node.range[0] && !astUtils.canTokensBeAdjacent(tokenBefore, recommendation)) { return fixer.replaceText(node, " " + recommendation); } return fixer.replaceText(node, recommendation); } }); } return { UnaryExpression: function UnaryExpression(node) { var operatorAllowed = void 0; // !!foo operatorAllowed = options.allow.indexOf("!!") >= 0; if (!operatorAllowed && options.boolean && isDoubleLogicalNegating(node)) { var recommendation = "Boolean(" + sourceCode.getText(node.argument.argument) + ")"; report(node, recommendation, true); } // ~foo.indexOf(bar) operatorAllowed = options.allow.indexOf("~") >= 0; if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) { var _recommendation = sourceCode.getText(node.argument) + " !== -1"; report(node, _recommendation, false); } // +foo operatorAllowed = options.allow.indexOf("+") >= 0; if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) { var _recommendation2 = "Number(" + sourceCode.getText(node.argument) + ")"; report(node, _recommendation2, true); } }, // Use `:exit` to prevent double reporting "BinaryExpression:exit": function BinaryExpressionExit(node) { var operatorAllowed = void 0; // 1 * foo operatorAllowed = options.allow.indexOf("*") >= 0; var nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); if (nonNumericOperand) { var recommendation = "Number(" + sourceCode.getText(nonNumericOperand) + ")"; report(node, recommendation, true); } // "" + foo operatorAllowed = options.allow.indexOf("+") >= 0; if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) { var _recommendation3 = "String(" + sourceCode.getText(getNonEmptyOperand(node)) + ")"; report(node, _recommendation3, true); } }, AssignmentExpression: function AssignmentExpression(node) { // foo += "" var operatorAllowed = options.allow.indexOf("+") >= 0; if (!operatorAllowed && options.string && isAppendEmptyString(node)) { var code = sourceCode.getText(getNonEmptyOperand(node)); var recommendation = code + " = String(" + code + ")"; report(node, recommendation, true); } } }; } }; },{"../util/ast-utils":405}],241:[function(require,module,exports){ /** * @fileoverview Rule to check for implicit global variables and functions. * @author Joshua Peek */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow variable and `function` declarations in the global scope", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-implicit-globals" }, schema: [] }, create: function create(context) { return { Program: function Program() { var scope = context.getScope(); scope.variables.forEach(function (variable) { if (variable.writeable) { return; } variable.defs.forEach(function (def) { if (def.type === "FunctionName" || def.type === "Variable" && def.parent.kind === "var") { context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." }); } }); }); scope.implicit.variables.forEach(function (variable) { var scopeVariable = scope.set.get(variable.name); if (scopeVariable && scopeVariable.writeable) { return; } variable.defs.forEach(function (def) { context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." }); }); }); } }; } }; },{}],242:[function(require,module,exports){ /** * @fileoverview Rule to flag use of implied eval via setTimeout and setInterval * @author James Allardice */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `eval()`-like methods", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-implied-eval" }, schema: [] }, create: function create(context) { var CALLEE_RE = /^(setTimeout|setInterval|execScript)$/; /* * Figures out if we should inspect a given binary expression. Is a stack * of stacks, where the first element in each substack is a CallExpression. */ var impliedEvalAncestorsStack = []; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Get the last element of an array, without modifying arr, like pop(), but non-destructive. * @param {Array} arr What to inspect * @returns {*} The last element of arr * @private */ function last(arr) { return arr ? arr[arr.length - 1] : null; } /** * Checks if the given MemberExpression node is a potentially implied eval identifier on window. * @param {ASTNode} node The MemberExpression node to check. * @returns {boolean} Whether or not the given node is potentially an implied eval. * @private */ function isImpliedEvalMemberExpression(node) { var object = node.object, property = node.property, hasImpliedEvalName = CALLEE_RE.test(property.name) || CALLEE_RE.test(property.value); return object.name === "window" && hasImpliedEvalName; } /** * Determines if a node represents a call to a potentially implied eval. * * This checks the callee name and that there's an argument, but not the type of the argument. * * @param {ASTNode} node The CallExpression to check. * @returns {boolean} True if the node matches, false if not. * @private */ function isImpliedEvalCallExpression(node) { var isMemberExpression = node.callee.type === "MemberExpression", isIdentifier = node.callee.type === "Identifier", isImpliedEvalCallee = isIdentifier && CALLEE_RE.test(node.callee.name) || isMemberExpression && isImpliedEvalMemberExpression(node.callee); return isImpliedEvalCallee && node.arguments.length; } /** * Checks that the parent is a direct descendent of an potential implied eval CallExpression, and if the parent is a CallExpression, that we're the first argument. * @param {ASTNode} node The node to inspect the parent of. * @returns {boolean} Was the parent a direct descendent, and is the child therefore potentially part of a dangerous argument? * @private */ function hasImpliedEvalParent(node) { // make sure our parent is marked return node.parent === last(last(impliedEvalAncestorsStack)) && ( // if our parent is a CallExpression, make sure we're the first argument node.parent.type !== "CallExpression" || node === node.parent.arguments[0]); } /** * Checks if our parent is marked as part of an implied eval argument. If * so, collapses the top of impliedEvalAncestorsStack and reports on the * original CallExpression. * @param {ASTNode} node The CallExpression to check. * @returns {boolean} True if the node matches, false if not. * @private */ function checkString(node) { if (hasImpliedEvalParent(node)) { // remove the entire substack, to avoid duplicate reports var substack = impliedEvalAncestorsStack.pop(); context.report({ node: substack[0], message: "Implied eval. Consider passing a function instead of a string." }); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { CallExpression: function CallExpression(node) { if (isImpliedEvalCallExpression(node)) { // call expressions create a new substack impliedEvalAncestorsStack.push([node]); } }, "CallExpression:exit": function CallExpressionExit(node) { if (node === last(last(impliedEvalAncestorsStack))) { /* * Destroys the entire sub-stack, rather than just using * last(impliedEvalAncestorsStack).pop(), as a CallExpression is * always the bottom of a impliedEvalAncestorsStack substack. */ impliedEvalAncestorsStack.pop(); } }, BinaryExpression: function BinaryExpression(node) { if (node.operator === "+" && hasImpliedEvalParent(node)) { last(impliedEvalAncestorsStack).push(node); } }, "BinaryExpression:exit": function BinaryExpressionExit(node) { if (node === last(last(impliedEvalAncestorsStack))) { last(impliedEvalAncestorsStack).pop(); } }, Literal: function Literal(node) { if (typeof node.value === "string") { checkString(node); } }, TemplateLiteral: function TemplateLiteral(node) { checkString(node); } }; } }; },{}],243:[function(require,module,exports){ /** * @fileoverview Enforces or disallows inline comments. * @author Greg Cochard */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow inline comments after code", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-inline-comments" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Will check that comments are not on lines starting with or ending with code * @param {ASTNode} node The comment node to check * @private * @returns {void} */ function testCodeAroundComment(node) { // Get the whole line and cut it off at the start of the comment var startLine = String(sourceCode.lines[node.loc.start.line - 1]); var endLine = String(sourceCode.lines[node.loc.end.line - 1]); var preamble = startLine.slice(0, node.loc.start.column).trim(); // Also check after the comment var postamble = endLine.slice(node.loc.end.column).trim(); // Check that this comment isn't an ESLint directive var isDirective = astUtils.isDirectiveComment(node); // Should be empty if there was only whitespace around the comment if (!isDirective && (preamble || postamble)) { context.report({ node: node, message: "Unexpected comment inline with code." }); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function Program() { var comments = sourceCode.getAllComments(); comments.filter(function (token) { return token.type !== "Shebang"; }).forEach(testCodeAroundComment); } }; } }; },{"../util/ast-utils":405}],244:[function(require,module,exports){ /** * @fileoverview Rule to enforce declarations in program or function body root. * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow variable or `function` declarations in nested blocks", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-inner-declarations" }, schema: [{ enum: ["functions", "both"] }] }, create: function create(context) { /** * Find the nearest Program or Function ancestor node. * @returns {Object} Ancestor's type and distance from node. */ function nearestBody() { var ancestors = context.getAncestors(); var ancestor = ancestors.pop(), generation = 1; while (ancestor && ["Program", "FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].indexOf(ancestor.type) < 0) { generation += 1; ancestor = ancestors.pop(); } return { // Type of containing ancestor type: ancestor.type, // Separation between ancestor and node distance: generation }; } /** * Ensure that a given node is at a program or function body's root. * @param {ASTNode} node Declaration node to check. * @returns {void} */ function check(node) { var body = nearestBody(), valid = body.type === "Program" && body.distance === 1 || body.distance === 2; if (!valid) { context.report({ node: node, message: "Move {{type}} declaration to {{body}} root.", data: { type: node.type === "FunctionDeclaration" ? "function" : "variable", body: body.type === "Program" ? "program" : "function body" } }); } } return { FunctionDeclaration: check, VariableDeclaration: function VariableDeclaration(node) { if (context.options[0] === "both" && node.kind === "var") { check(node); } } }; } }; },{}],245:[function(require,module,exports){ /** * @fileoverview Validate strings passed to the RegExp constructor * @author Michael Ficarra */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var RegExpValidator = require("regexpp").RegExpValidator; var validator = new RegExpValidator({ ecmaVersion: 2018 }); var validFlags = /[gimuys]/g; var undefined1 = void 0; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow invalid regular expression strings in `RegExp` constructors", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-invalid-regexp" }, schema: [{ type: "object", properties: { allowConstructorFlags: { type: "array", items: { type: "string" } } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0]; var allowedFlags = null; if (options && options.allowConstructorFlags) { var temp = options.allowConstructorFlags.join("").replace(validFlags, ""); if (temp) { allowedFlags = new RegExp("[" + temp + "]", "gi"); } } /** * Check if node is a string * @param {ASTNode} node node to evaluate * @returns {boolean} True if its a string * @private */ function isString(node) { return node && node.type === "Literal" && typeof node.value === "string"; } /** * Check syntax error in a given pattern. * @param {string} pattern The RegExp pattern to validate. * @param {boolean} uFlag The Unicode flag. * @returns {string|null} The syntax error. */ function validateRegExpPattern(pattern, uFlag) { try { validator.validatePattern(pattern, undefined1, undefined1, uFlag); return null; } catch (err) { return err.message; } } /** * Check syntax error in a given flags. * @param {string} flags The RegExp flags to validate. * @returns {string|null} The syntax error. */ function validateRegExpFlags(flags) { try { validator.validateFlags(flags); return null; } catch (err) { return "Invalid flags supplied to RegExp constructor '" + flags + "'"; } } return { "CallExpression, NewExpression": function CallExpressionNewExpression(node) { if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp" || !isString(node.arguments[0])) { return; } var pattern = node.arguments[0].value; var flags = isString(node.arguments[1]) ? node.arguments[1].value : ""; if (allowedFlags) { flags = flags.replace(allowedFlags, ""); } // If flags are unknown, check both are errored or not. var message = validateRegExpFlags(flags) || (flags ? validateRegExpPattern(pattern, flags.indexOf("u") !== -1) : validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)); if (message) { context.report({ node: node, message: "{{message}}.", data: { message: message } }); } } }; } }; },{"regexpp":104}],246:[function(require,module,exports){ /** * @fileoverview A rule to disallow `this` keywords outside of classes or class-like objects. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `this` keywords outside of classes or class-like objects", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-invalid-this" }, schema: [] }, create: function create(context) { var stack = [], sourceCode = context.getSourceCode(); /** * Gets the current checking context. * * The return value has a flag that whether or not `this` keyword is valid. * The flag is initialized when got at the first time. * * @returns {{valid: boolean}} * an object which has a flag that whether or not `this` keyword is valid. */ stack.getCurrent = function () { var current = this[this.length - 1]; if (!current.init) { current.init = true; current.valid = !astUtils.isDefaultThisBinding(current.node, sourceCode); } return current; }; /** * Pushs new checking context into the stack. * * The checking context is not initialized yet. * Because most functions don't have `this` keyword. * When `this` keyword was found, the checking context is initialized. * * @param {ASTNode} node - A function node that was entered. * @returns {void} */ function enterFunction(node) { // `this` can be invalid only under strict mode. stack.push({ init: !context.getScope().isStrict, node: node, valid: true }); } /** * Pops the current checking context from the stack. * @returns {void} */ function exitFunction() { stack.pop(); } return { /* * `this` is invalid only under strict mode. * Modules is always strict mode. */ Program: function Program(node) { var scope = context.getScope(), features = context.parserOptions.ecmaFeatures || {}; stack.push({ init: true, node: node, valid: !(scope.isStrict || node.sourceType === "module" || features.globalReturn && scope.childScopes[0].isStrict) }); }, "Program:exit": function ProgramExit() { stack.pop(); }, FunctionDeclaration: enterFunction, "FunctionDeclaration:exit": exitFunction, FunctionExpression: enterFunction, "FunctionExpression:exit": exitFunction, // Reports if `this` of the current context is invalid. ThisExpression: function ThisExpression(node) { var current = stack.getCurrent(); if (current && !current.valid) { context.report({ node: node, message: "Unexpected 'this'." }); } } }; } }; },{"../util/ast-utils":405}],247:[function(require,module,exports){ /** * @fileoverview Rule to disalow whitespace that is not a tab or space, whitespace inside strings and comments are allowed * @author Jonathan Kingston * @author Christophe Porteneuve */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ var ALL_IRREGULARS = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/; var IRREGULAR_WHITESPACE = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mg; var IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mg; var LINE_BREAK = astUtils.createGlobalLinebreakMatcher(); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow irregular whitespace", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-irregular-whitespace" }, schema: [{ type: "object", properties: { skipComments: { type: "boolean" }, skipStrings: { type: "boolean" }, skipTemplates: { type: "boolean" }, skipRegExps: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { // Module store of errors that we have found var errors = []; // Lookup the `skipComments` option, which defaults to `false`. var options = context.options[0] || {}; var skipComments = !!options.skipComments; var skipStrings = options.skipStrings !== false; var skipRegExps = !!options.skipRegExps; var skipTemplates = !!options.skipTemplates; var sourceCode = context.getSourceCode(); var commentNodes = sourceCode.getAllComments(); /** * Removes errors that occur inside a string node * @param {ASTNode} node to check for matching errors. * @returns {void} * @private */ function removeWhitespaceError(node) { var locStart = node.loc.start; var locEnd = node.loc.end; errors = errors.filter(function (_ref) { var errorLoc = _ref.loc; if (errorLoc.line >= locStart.line && errorLoc.line <= locEnd.line) { if (errorLoc.column >= locStart.column && (errorLoc.column <= locEnd.column || errorLoc.line < locEnd.line)) { return false; } } return true; }); } /** * Checks identifier or literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors * @param {ASTNode} node to check for matching errors. * @returns {void} * @private */ function removeInvalidNodeErrorsInIdentifierOrLiteral(node) { var shouldCheckStrings = skipStrings && typeof node.value === "string"; var shouldCheckRegExps = skipRegExps && Boolean(node.regex); if (shouldCheckStrings || shouldCheckRegExps) { // If we have irregular characters remove them from the errors list if (ALL_IRREGULARS.test(node.raw)) { removeWhitespaceError(node); } } } /** * Checks template string literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors * @param {ASTNode} node to check for matching errors. * @returns {void} * @private */ function removeInvalidNodeErrorsInTemplateLiteral(node) { if (typeof node.value.raw === "string") { if (ALL_IRREGULARS.test(node.value.raw)) { removeWhitespaceError(node); } } } /** * Checks comment nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors * @param {ASTNode} node to check for matching errors. * @returns {void} * @private */ function removeInvalidNodeErrorsInComment(node) { if (ALL_IRREGULARS.test(node.value)) { removeWhitespaceError(node); } } /** * Checks the program source for irregular whitespace * @param {ASTNode} node The program node * @returns {void} * @private */ function checkForIrregularWhitespace(node) { var sourceLines = sourceCode.lines; sourceLines.forEach(function (sourceLine, lineIndex) { var lineNumber = lineIndex + 1; var match = void 0; while ((match = IRREGULAR_WHITESPACE.exec(sourceLine)) !== null) { var location = { line: lineNumber, column: match.index }; errors.push({ node: node, message: "Irregular whitespace not allowed.", loc: location }); } }); } /** * Checks the program source for irregular line terminators * @param {ASTNode} node The program node * @returns {void} * @private */ function checkForIrregularLineTerminators(node) { var source = sourceCode.getText(), sourceLines = sourceCode.lines, linebreaks = source.match(LINE_BREAK); var lastLineIndex = -1, match = void 0; while ((match = IRREGULAR_LINE_TERMINATORS.exec(source)) !== null) { var lineIndex = linebreaks.indexOf(match[0], lastLineIndex + 1) || 0; var location = { line: lineIndex + 1, column: sourceLines[lineIndex].length }; errors.push({ node: node, message: "Irregular whitespace not allowed.", loc: location }); lastLineIndex = lineIndex; } } /** * A no-op function to act as placeholder for comment accumulation when the `skipComments` option is `false`. * @returns {void} * @private */ function noop() {} var nodes = {}; if (ALL_IRREGULARS.test(sourceCode.getText())) { nodes.Program = function (node) { /* * As we can easily fire warnings for all white space issues with * all the source its simpler to fire them here. * This means we can check all the application code without having * to worry about issues caused in the parser tokens. * When writing this code also evaluating per node was missing out * connecting tokens in some cases. * We can later filter the errors when they are found to be not an * issue in nodes we don't care about. */ checkForIrregularWhitespace(node); checkForIrregularLineTerminators(node); }; nodes.Identifier = removeInvalidNodeErrorsInIdentifierOrLiteral; nodes.Literal = removeInvalidNodeErrorsInIdentifierOrLiteral; nodes.TemplateElement = skipTemplates ? removeInvalidNodeErrorsInTemplateLiteral : noop; nodes["Program:exit"] = function () { if (skipComments) { // First strip errors occurring in comment nodes. commentNodes.forEach(removeInvalidNodeErrorsInComment); } // If we have any errors remaining report on them errors.forEach(function (error) { return context.report(error); }); }; } else { nodes.Program = noop; } return nodes; } }; },{"../util/ast-utils":405}],248:[function(require,module,exports){ /** * @fileoverview Rule to flag usage of __iterator__ property * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of the `__iterator__` property", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-iterator" }, schema: [] }, create: function create(context) { return { MemberExpression: function MemberExpression(node) { if (node.property && node.property.type === "Identifier" && node.property.name === "__iterator__" && !node.computed || node.property.type === "Literal" && node.property.value === "__iterator__") { context.report({ node: node, message: "Reserved name '__iterator__'." }); } } }; } }; },{}],249:[function(require,module,exports){ /** * @fileoverview Rule to flag labels that are the same as an identifier * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow labels that share a name with a variable", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-label-var" }, schema: [] }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Check if the identifier is present inside current scope * @param {Object} scope current scope * @param {string} name To evaluate * @returns {boolean} True if its present * @private */ function findIdentifier(scope, name) { return astUtils.getVariableByName(scope, name) !== null; } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { LabeledStatement: function LabeledStatement(node) { // Fetch the innermost scope. var scope = context.getScope(); /* * Recursively find the identifier walking up the scope, starting * with the innermost scope. */ if (findIdentifier(scope, node.label.name)) { context.report({ node: node, message: "Found identifier with same name as label." }); } } }; } }; },{"../util/ast-utils":405}],250:[function(require,module,exports){ /** * @fileoverview Disallow Labeled Statements * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow labeled statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-labels" }, schema: [{ type: "object", properties: { allowLoop: { type: "boolean" }, allowSwitch: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0]; var allowLoop = Boolean(options && options.allowLoop); var allowSwitch = Boolean(options && options.allowSwitch); var scopeInfo = null; /** * Gets the kind of a given node. * * @param {ASTNode} node - A node to get. * @returns {string} The kind of the node. */ function getBodyKind(node) { if (astUtils.isLoop(node)) { return "loop"; } if (node.type === "SwitchStatement") { return "switch"; } return "other"; } /** * Checks whether the label of a given kind is allowed or not. * * @param {string} kind - A kind to check. * @returns {boolean} `true` if the kind is allowed. */ function isAllowed(kind) { switch (kind) { case "loop": return allowLoop; case "switch": return allowSwitch; default: return false; } } /** * Checks whether a given name is a label of a loop or not. * * @param {string} label - A name of a label to check. * @returns {boolean} `true` if the name is a label of a loop. */ function getKind(label) { var info = scopeInfo; while (info) { if (info.label === label) { return info.kind; } info = info.upper; } /* istanbul ignore next: syntax error */ return "other"; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { LabeledStatement: function LabeledStatement(node) { scopeInfo = { label: node.label.name, kind: getBodyKind(node.body), upper: scopeInfo }; }, "LabeledStatement:exit": function LabeledStatementExit(node) { if (!isAllowed(scopeInfo.kind)) { context.report({ node: node, message: "Unexpected labeled statement." }); } scopeInfo = scopeInfo.upper; }, BreakStatement: function BreakStatement(node) { if (node.label && !isAllowed(getKind(node.label.name))) { context.report({ node: node, message: "Unexpected label in break statement." }); } }, ContinueStatement: function ContinueStatement(node) { if (node.label && !isAllowed(getKind(node.label.name))) { context.report({ node: node, message: "Unexpected label in continue statement." }); } } }; } }; },{"../util/ast-utils":405}],251:[function(require,module,exports){ /** * @fileoverview Rule to flag blocks with no reason to exist * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary nested blocks", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-lone-blocks" }, schema: [] }, create: function create(context) { // A stack of lone blocks to be checked for block-level bindings var loneBlocks = []; var ruleDef = void 0; /** * Reports a node as invalid. * @param {ASTNode} node - The node to be reported. * @returns {void} */ function report(node) { var message = node.parent.type === "BlockStatement" ? "Nested block is redundant." : "Block is redundant."; context.report({ node: node, message: message }); } /** * Checks for any ocurrence of a BlockStatement in a place where lists of statements can appear * @param {ASTNode} node The node to check * @returns {boolean} True if the node is a lone block. */ function isLoneBlock(node) { return node.parent.type === "BlockStatement" || node.parent.type === "Program" || // Don't report blocks in switch cases if the block is the only statement of the case. node.parent.type === "SwitchCase" && !(node.parent.consequent[0] === node && node.parent.consequent.length === 1); } /** * Checks the enclosing block of the current node for block-level bindings, * and "marks it" as valid if any. * @returns {void} */ function markLoneBlock() { if (loneBlocks.length === 0) { return; } var block = context.getAncestors().pop(); if (loneBlocks[loneBlocks.length - 1] === block) { loneBlocks.pop(); } } // Default rule definition: report all lone blocks ruleDef = { BlockStatement: function BlockStatement(node) { if (isLoneBlock(node)) { report(node); } } }; // ES6: report blocks without block-level bindings if (context.parserOptions.ecmaVersion >= 6) { ruleDef = { BlockStatement: function BlockStatement(node) { if (isLoneBlock(node)) { loneBlocks.push(node); } }, "BlockStatement:exit": function BlockStatementExit(node) { if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) { loneBlocks.pop(); report(node); } } }; ruleDef.VariableDeclaration = function (node) { if (node.kind === "let" || node.kind === "const") { markLoneBlock(); } }; ruleDef.FunctionDeclaration = function () { if (context.getScope().isStrict) { markLoneBlock(); } }; ruleDef.ClassDeclaration = markLoneBlock; } return ruleDef; } }; },{}],252:[function(require,module,exports){ /** * @fileoverview Rule to disallow if as the only statmenet in an else block * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `if` statements as the only statement in `else` blocks", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-lonely-if" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { IfStatement: function IfStatement(node) { var ancestors = context.getAncestors(), parent = ancestors.pop(), grandparent = ancestors.pop(); if (parent && parent.type === "BlockStatement" && parent.body.length === 1 && grandparent && grandparent.type === "IfStatement" && parent === grandparent.alternate) { context.report({ node: node, message: "Unexpected if as the only statement in an else block.", fix: function fix(fixer) { var openingElseCurly = sourceCode.getFirstToken(parent); var closingElseCurly = sourceCode.getLastToken(parent); var elseKeyword = sourceCode.getTokenBefore(openingElseCurly); var tokenAfterElseBlock = sourceCode.getTokenAfter(closingElseCurly); var lastIfToken = sourceCode.getLastToken(node.consequent); var sourceText = sourceCode.getText(); if (sourceText.slice(openingElseCurly.range[1], node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) { // Don't fix if there are any non-whitespace characters interfering (e.g. comments) return null; } if (node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock && (node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line || /^[([/+`-]/.test(tokenAfterElseBlock.value) || lastIfToken.value === "++" || lastIfToken.value === "--")) { /* * If the `if` statement has no block, and is not followed by a semicolon, make sure that fixing * the issue would not change semantics due to ASI. If this would happen, don't do a fix. */ return null; } return fixer.replaceTextRange([openingElseCurly.range[0], closingElseCurly.range[1]], (elseKeyword.range[1] === openingElseCurly.range[0] ? " " : "") + sourceCode.getText(node)); } }); } } }; } }; },{}],253:[function(require,module,exports){ /** * @fileoverview Rule to flag creation of function inside a loop * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets the containing loop node of a specified node. * * We don't need to check nested functions, so this ignores those. * `Scope.through` contains references of nested functions. * * @param {ASTNode} node - An AST node to get. * @returns {ASTNode|null} The containing loop node of the specified node, or * `null`. */ function getContainingLoopNode(node) { for (var currentNode = node; currentNode.parent; currentNode = currentNode.parent) { var parent = currentNode.parent; switch (parent.type) { case "WhileStatement": case "DoWhileStatement": return parent; case "ForStatement": // `init` is outside of the loop. if (parent.init !== currentNode) { return parent; } break; case "ForInStatement": case "ForOfStatement": // `right` is outside of the loop. if (parent.right !== currentNode) { return parent; } break; case "ArrowFunctionExpression": case "FunctionExpression": case "FunctionDeclaration": // We don't need to check nested functions. return null; default: break; } } return null; } /** * Gets the containing loop node of a given node. * If the loop was nested, this returns the most outer loop. * * @param {ASTNode} node - A node to get. This is a loop node. * @param {ASTNode|null} excludedNode - A node that the result node should not * include. * @returns {ASTNode} The most outer loop node. */ function getTopLoopNode(node, excludedNode) { var border = excludedNode ? excludedNode.range[1] : 0; var retv = node; var containingLoopNode = node; while (containingLoopNode && containingLoopNode.range[0] >= border) { retv = containingLoopNode; containingLoopNode = getContainingLoopNode(containingLoopNode); } return retv; } /** * Checks whether a given reference which refers to an upper scope's variable is * safe or not. * * @param {ASTNode} loopNode - A containing loop node. * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is safe or not. */ function isSafe(loopNode, reference) { var variable = reference.resolved; var definition = variable && variable.defs[0]; var declaration = definition && definition.parent; var kind = declaration && declaration.type === "VariableDeclaration" ? declaration.kind : ""; // Variables which are declared by `const` is safe. if (kind === "const") { return true; } /* * Variables which are declared by `let` in the loop is safe. * It's a different instance from the next loop step's. */ if (kind === "let" && declaration.range[0] > loopNode.range[0] && declaration.range[1] < loopNode.range[1]) { return true; } /* * WriteReferences which exist after this border are unsafe because those * can modify the variable. */ var border = getTopLoopNode(loopNode, kind === "let" ? declaration : null).range[0]; /** * Checks whether a given reference is safe or not. * The reference is every reference of the upper scope's variable we are * looking now. * * It's safeafe if the reference matches one of the following condition. * - is readonly. * - doesn't exist inside a local function and after the border. * * @param {eslint-scope.Reference} upperRef - A reference to check. * @returns {boolean} `true` if the reference is safe. */ function isSafeReference(upperRef) { var id = upperRef.identifier; return !upperRef.isWrite() || variable.scope.variableScope === upperRef.from.variableScope && id.range[0] < border; } return Boolean(variable) && variable.references.every(isSafeReference); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `function` declarations and expressions inside loop statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-loop-func" }, schema: [] }, create: function create(context) { /** * Reports functions which match the following condition: * * - has a loop node in ancestors. * - has any references which refers to an unsafe variable. * * @param {ASTNode} node The AST node to check. * @returns {boolean} Whether or not the node is within a loop. */ function checkForLoops(node) { var loopNode = getContainingLoopNode(node); if (!loopNode) { return; } var references = context.getScope().through; if (references.length > 0 && !references.every(isSafe.bind(null, loopNode))) { context.report({ node: node, message: "Don't make functions within a loop." }); } } return { ArrowFunctionExpression: checkForLoops, FunctionExpression: checkForLoops, FunctionDeclaration: checkForLoops }; } }; },{}],254:[function(require,module,exports){ /** * @fileoverview Rule to flag statements that use magic numbers (adapted from https://github.com/danielstjules/buddy.js) * @author Vincent Lemeunier */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow magic numbers", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-magic-numbers" }, schema: [{ type: "object", properties: { detectObjects: { type: "boolean" }, enforceConst: { type: "boolean" }, ignore: { type: "array", items: { type: "number" }, uniqueItems: true }, ignoreArrayIndexes: { type: "boolean" } }, additionalProperties: false }], messages: { useConst: "Number constants declarations must use 'const'.", noMagic: "No magic number: {{raw}}." } }, create: function create(context) { var config = context.options[0] || {}, detectObjects = !!config.detectObjects, enforceConst = !!config.enforceConst, ignore = config.ignore || [], ignoreArrayIndexes = !!config.ignoreArrayIndexes; /** * Returns whether the node is number literal * @param {Node} node - the node literal being evaluated * @returns {boolean} true if the node is a number literal */ function isNumber(node) { return typeof node.value === "number"; } /** * Returns whether the number should be ignored * @param {number} num - the number * @returns {boolean} true if the number should be ignored */ function shouldIgnoreNumber(num) { return ignore.indexOf(num) !== -1; } /** * Returns whether the number should be ignored when used as a radix within parseInt() or Number.parseInt() * @param {ASTNode} parent - the non-"UnaryExpression" parent * @param {ASTNode} node - the node literal being evaluated * @returns {boolean} true if the number should be ignored */ function shouldIgnoreParseInt(parent, node) { return parent.type === "CallExpression" && node === parent.arguments[1] && (parent.callee.name === "parseInt" || parent.callee.type === "MemberExpression" && parent.callee.object.name === "Number" && parent.callee.property.name === "parseInt"); } /** * Returns whether the number should be ignored when used to define a JSX prop * @param {ASTNode} parent - the non-"UnaryExpression" parent * @returns {boolean} true if the number should be ignored */ function shouldIgnoreJSXNumbers(parent) { return parent.type.indexOf("JSX") === 0; } /** * Returns whether the number should be ignored when used as an array index with enabled 'ignoreArrayIndexes' option. * @param {ASTNode} parent - the non-"UnaryExpression" parent. * @returns {boolean} true if the number should be ignored */ function shouldIgnoreArrayIndexes(parent) { return parent.type === "MemberExpression" && ignoreArrayIndexes; } return { Literal: function Literal(node) { var okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"]; if (!isNumber(node)) { return; } var fullNumberNode = void 0; var parent = void 0; var value = void 0; var raw = void 0; // For negative magic numbers: update the value and parent node if (node.parent.type === "UnaryExpression" && node.parent.operator === "-") { fullNumberNode = node.parent; parent = fullNumberNode.parent; value = -node.value; raw = "-" + node.raw; } else { fullNumberNode = node; parent = node.parent; value = node.value; raw = node.raw; } if (shouldIgnoreNumber(value) || shouldIgnoreParseInt(parent, fullNumberNode) || shouldIgnoreArrayIndexes(parent) || shouldIgnoreJSXNumbers(parent)) { return; } if (parent.type === "VariableDeclarator") { if (enforceConst && parent.parent.kind !== "const") { context.report({ node: fullNumberNode, messageId: "useConst" }); } } else if (okTypes.indexOf(parent.type) === -1 || parent.type === "AssignmentExpression" && parent.left.type === "Identifier") { context.report({ node: fullNumberNode, messageId: "noMagic", data: { raw: raw } }); } } }; } }; },{}],255:[function(require,module,exports){ /** * @author Toru Nagashima */ "use strict"; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var _marked = /*#__PURE__*/regeneratorRuntime.mark(iterateCharacterSequence); var _require = require("eslint-utils"), CALL = _require.CALL, CONSTRUCT = _require.CONSTRUCT, ReferenceTracker = _require.ReferenceTracker, getStringIfConstant = _require.getStringIfConstant; var _require2 = require("regexpp"), RegExpParser = _require2.RegExpParser, visitRegExpAST = _require2.visitRegExpAST; var _require3 = require("../util/unicode"), isCombiningCharacter = _require3.isCombiningCharacter, isEmojiModifier = _require3.isEmojiModifier, isRegionalIndicatorSymbol = _require3.isRegionalIndicatorSymbol, isSurrogatePair = _require3.isSurrogatePair; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Iterate character sequences of a given nodes. * * CharacterClassRange syntax can steal a part of character sequence, * so this function reverts CharacterClassRange syntax and restore the sequence. * * @param {regexpp.AST.CharacterClassElement[]} nodes The node list to iterate character sequences. * @returns {IterableIterator} The list of character sequences. */ function iterateCharacterSequence(nodes) { var seq, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, node; return regeneratorRuntime.wrap(function iterateCharacterSequence$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: seq = []; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context.prev = 4; _iterator = nodes[Symbol.iterator](); case 6: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context.next = 26; break; } node = _step.value; _context.t0 = node.type; _context.next = _context.t0 === "Character" ? 11 : _context.t0 === "CharacterClassRange" ? 13 : _context.t0 === "CharacterSet" ? 18 : 23; break; case 11: seq.push(node.value); return _context.abrupt("break", 23); case 13: seq.push(node.min.value); _context.next = 16; return seq; case 16: seq = [node.max.value]; return _context.abrupt("break", 23); case 18: if (!(seq.length > 0)) { _context.next = 22; break; } _context.next = 21; return seq; case 21: seq = []; case 22: return _context.abrupt("break", 23); case 23: _iteratorNormalCompletion = true; _context.next = 6; break; case 26: _context.next = 32; break; case 28: _context.prev = 28; _context.t1 = _context["catch"](4); _didIteratorError = true; _iteratorError = _context.t1; case 32: _context.prev = 32; _context.prev = 33; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 35: _context.prev = 35; if (!_didIteratorError) { _context.next = 38; break; } throw _iteratorError; case 38: return _context.finish(35); case 39: return _context.finish(32); case 40: if (!(seq.length > 0)) { _context.next = 43; break; } _context.next = 43; return seq; case 43: case "end": return _context.stop(); } } }, _marked, this, [[4, 28, 32, 40], [33,, 35, 39]]); } var hasCharacterSequence = { surrogatePairWithoutUFlag: function surrogatePairWithoutUFlag(chars) { return chars.some(function (c, i) { return i !== 0 && isSurrogatePair(chars[i - 1], c); }); }, combiningClass: function combiningClass(chars) { return chars.some(function (c, i) { return i !== 0 && isCombiningCharacter(c) && !isCombiningCharacter(chars[i - 1]); }); }, emojiModifier: function emojiModifier(chars) { return chars.some(function (c, i) { return i !== 0 && isEmojiModifier(c) && !isEmojiModifier(chars[i - 1]); }); }, regionalIndicatorSymbol: function regionalIndicatorSymbol(chars) { return chars.some(function (c, i) { return i !== 0 && isRegionalIndicatorSymbol(c) && isRegionalIndicatorSymbol(chars[i - 1]); }); }, zwj: function zwj(chars) { var lastIndex = chars.length - 1; return chars.some(function (c, i) { return i !== 0 && i !== lastIndex && c === 0x200d && chars[i - 1] !== 0x200d && chars[i + 1] !== 0x200d; }); } }; var kinds = Object.keys(hasCharacterSequence); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow characters which are made with multiple code points in character class syntax", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-misleading-character-class" }, schema: [], messages: { surrogatePairWithoutUFlag: "Unexpected surrogate pair in character class. Use 'u' flag.", combiningClass: "Unexpected combined character in character class.", emojiModifier: "Unexpected modified Emoji in character class.", regionalIndicatorSymbol: "Unexpected national flag in character class.", zwj: "Unexpected joined character sequence in character class." } }, create: function create(context) { var parser = new RegExpParser(); /** * Verify a given regular expression. * @param {Node} node The node to report. * @param {string} pattern The regular expression pattern to verify. * @param {string} flags The flags of the regular expression. * @returns {void} */ function verify(node, pattern, flags) { var patternNode = parser.parsePattern(pattern, 0, pattern.length, flags.includes("u")); var has = { surrogatePairWithoutUFlag: false, combiningClass: false, variationSelector: false, emojiModifier: false, regionalIndicatorSymbol: false, zwj: false }; visitRegExpAST(patternNode, { onCharacterClassEnter: function onCharacterClassEnter(ccNode) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = iterateCharacterSequence(ccNode.elements)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var chars = _step2.value; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = kinds[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var kind = _step3.value; has[kind] = has[kind] || hasCharacterSequence[kind](chars); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } }); var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = kinds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var kind = _step4.value; if (has[kind]) { context.report({ node: node, messageId: kind }); } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } return { "Literal[regex]": function LiteralRegex(node) { verify(node, node.regex.pattern, node.regex.flags); }, "Program": function Program() { var scope = context.getScope(); var tracker = new ReferenceTracker(scope); /* * Iterate calls of RegExp. * E.g., `new RegExp()`, `RegExp()`, `new window.RegExp()`, * `const {RegExp: a} = window; new a()`, etc... */ var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = tracker.iterateGlobalReferences({ RegExp: (_RegExp = {}, _defineProperty(_RegExp, CALL, true), _defineProperty(_RegExp, CONSTRUCT, true), _RegExp) })[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var _RegExp; var node = _step5.value.node; var _node$arguments = _slicedToArray(node.arguments, 2), patternNode = _node$arguments[0], flagsNode = _node$arguments[1]; var pattern = getStringIfConstant(patternNode, scope); var flags = getStringIfConstant(flagsNode, scope); if (typeof pattern === "string") { verify(node, pattern, flags || ""); } } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } } }; } }; },{"../util/unicode":419,"eslint-utils":68,"regexpp":104}],256:[function(require,module,exports){ /** * @fileoverview Rule to disallow mixed binary operators. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils.js"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"]; var BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"]; var COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="]; var LOGICAL_OPERATORS = ["&&", "||"]; var RELATIONAL_OPERATORS = ["in", "instanceof"]; var ALL_OPERATORS = [].concat(ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS); var DEFAULT_GROUPS = [ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS]; var TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/; /** * Normalizes options. * * @param {Object|undefined} options - A options object to normalize. * @returns {Object} Normalized option object. */ function normalizeOptions(options) { var hasGroups = options && options.groups && options.groups.length > 0; var groups = hasGroups ? options.groups : DEFAULT_GROUPS; var allowSamePrecedence = (options && options.allowSamePrecedence) !== false; return { groups: groups, allowSamePrecedence: allowSamePrecedence }; } /** * Checks whether any group which includes both given operator exists or not. * * @param {Array.} groups - A list of groups to check. * @param {string} left - An operator. * @param {string} right - Another operator. * @returns {boolean} `true` if such group existed. */ function includesBothInAGroup(groups, left, right) { return groups.some(function (group) { return group.indexOf(left) !== -1 && group.indexOf(right) !== -1; }); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow mixed binary operators", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-mixed-operators" }, schema: [{ type: "object", properties: { groups: { type: "array", items: { type: "array", items: { enum: ALL_OPERATORS }, minItems: 2, uniqueItems: true }, uniqueItems: true }, allowSamePrecedence: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var options = normalizeOptions(context.options[0]); /** * Checks whether a given node should be ignored by options or not. * * @param {ASTNode} node - A node to check. This is a BinaryExpression * node or a LogicalExpression node. This parent node is one of * them, too. * @returns {boolean} `true` if the node should be ignored. */ function shouldIgnore(node) { var a = node; var b = node.parent; return !includesBothInAGroup(options.groups, a.operator, b.operator) || options.allowSamePrecedence && astUtils.getPrecedence(a) === astUtils.getPrecedence(b); } /** * Checks whether the operator of a given node is mixed with parent * node's operator or not. * * @param {ASTNode} node - A node to check. This is a BinaryExpression * node or a LogicalExpression node. This parent node is one of * them, too. * @returns {boolean} `true` if the node was mixed. */ function isMixedWithParent(node) { return node.operator !== node.parent.operator && !astUtils.isParenthesised(sourceCode, node); } /** * Gets the operator token of a given node. * * @param {ASTNode} node - A node to check. This is a BinaryExpression * node or a LogicalExpression node. * @returns {Token} The operator token of the node. */ function getOperatorToken(node) { return sourceCode.getTokenAfter(node.left, astUtils.isNotClosingParenToken); } /** * Reports both the operator of a given node and the operator of the * parent node. * * @param {ASTNode} node - A node to check. This is a BinaryExpression * node or a LogicalExpression node. This parent node is one of * them, too. * @returns {void} */ function reportBothOperators(node) { var parent = node.parent; var left = parent.left === node ? node : parent; var right = parent.left !== node ? node : parent; var message = "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'."; var data = { leftOperator: left.operator, rightOperator: right.operator }; context.report({ node: left, loc: getOperatorToken(left).loc.start, message: message, data: data }); context.report({ node: right, loc: getOperatorToken(right).loc.start, message: message, data: data }); } /** * Checks between the operator of this node and the operator of the * parent node. * * @param {ASTNode} node - A node to check. * @returns {void} */ function check(node) { if (TARGET_NODE_TYPE.test(node.parent.type) && isMixedWithParent(node) && !shouldIgnore(node)) { reportBothOperators(node); } } return { BinaryExpression: check, LogicalExpression: check }; } }; },{"../util/ast-utils.js":405}],257:[function(require,module,exports){ /** * @fileoverview Rule to enforce grouped require statements for Node.JS * @author Raphael Pigulla */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; module.exports = { meta: { type: "suggestion", docs: { description: "disallow `require` calls to be mixed with regular variable declarations", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-mixed-requires" }, schema: [{ oneOf: [{ type: "boolean" }, { type: "object", properties: { grouping: { type: "boolean" }, allowCall: { type: "boolean" } }, additionalProperties: false }] }] }, create: function create(context) { var options = context.options[0]; var grouping = false, allowCall = false; if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object") { grouping = options.grouping; allowCall = options.allowCall; } else { grouping = !!options; } /** * Returns the list of built-in modules. * * @returns {string[]} An array of built-in Node.js modules. */ function getBuiltinModules() { /* * This list is generated using: * `require("repl")._builtinLibs.concat('repl').sort()` * This particular list is as per nodejs v0.12.2 and iojs v0.7.1 */ return ["assert", "buffer", "child_process", "cluster", "crypto", "dgram", "dns", "domain", "events", "fs", "http", "https", "net", "os", "path", "punycode", "querystring", "readline", "repl", "smalloc", "stream", "string_decoder", "tls", "tty", "url", "util", "v8", "vm", "zlib"]; } var BUILTIN_MODULES = getBuiltinModules(); var DECL_REQUIRE = "require", DECL_UNINITIALIZED = "uninitialized", DECL_OTHER = "other"; var REQ_CORE = "core", REQ_FILE = "file", REQ_MODULE = "module", REQ_COMPUTED = "computed"; /** * Determines the type of a declaration statement. * @param {ASTNode} initExpression The init node of the VariableDeclarator. * @returns {string} The type of declaration represented by the expression. */ function getDeclarationType(initExpression) { if (!initExpression) { // "var x;" return DECL_UNINITIALIZED; } if (initExpression.type === "CallExpression" && initExpression.callee.type === "Identifier" && initExpression.callee.name === "require") { // "var x = require('util');" return DECL_REQUIRE; } if (allowCall && initExpression.type === "CallExpression" && initExpression.callee.type === "CallExpression") { // "var x = require('diagnose')('sub-module');" return getDeclarationType(initExpression.callee); } if (initExpression.type === "MemberExpression") { // "var x = require('glob').Glob;" return getDeclarationType(initExpression.object); } // "var x = 42;" return DECL_OTHER; } /** * Determines the type of module that is loaded via require. * @param {ASTNode} initExpression The init node of the VariableDeclarator. * @returns {string} The module type. */ function inferModuleType(initExpression) { if (initExpression.type === "MemberExpression") { // "var x = require('glob').Glob;" return inferModuleType(initExpression.object); } if (initExpression.arguments.length === 0) { // "var x = require();" return REQ_COMPUTED; } var arg = initExpression.arguments[0]; if (arg.type !== "Literal" || typeof arg.value !== "string") { // "var x = require(42);" return REQ_COMPUTED; } if (BUILTIN_MODULES.indexOf(arg.value) !== -1) { // "var fs = require('fs');" return REQ_CORE; } if (/^\.{0,2}\//.test(arg.value)) { // "var utils = require('./utils');" return REQ_FILE; } // "var async = require('async');" return REQ_MODULE; } /** * Check if the list of variable declarations is mixed, i.e. whether it * contains both require and other declarations. * @param {ASTNode} declarations The list of VariableDeclarators. * @returns {boolean} True if the declarations are mixed, false if not. */ function isMixed(declarations) { var contains = {}; declarations.forEach(function (declaration) { var type = getDeclarationType(declaration.init); contains[type] = true; }); return !!(contains[DECL_REQUIRE] && (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER])); } /** * Check if all require declarations in the given list are of the same * type. * @param {ASTNode} declarations The list of VariableDeclarators. * @returns {boolean} True if the declarations are grouped, false if not. */ function isGrouped(declarations) { var found = {}; declarations.forEach(function (declaration) { if (getDeclarationType(declaration.init) === DECL_REQUIRE) { found[inferModuleType(declaration.init)] = true; } }); return Object.keys(found).length <= 1; } return { VariableDeclaration: function VariableDeclaration(node) { if (isMixed(node.declarations)) { context.report({ node: node, message: "Do not mix 'require' and other declarations." }); } else if (grouping && !isGrouped(node.declarations)) { context.report({ node: node, message: "Do not mix core, module, file and computed requires." }); } } }; } }; },{}],258:[function(require,module,exports){ /** * @fileoverview Disallow mixed spaces and tabs for indentation * @author Jary Niebur */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow mixed spaces and tabs for indentation", category: "Stylistic Issues", recommended: true, url: "https://eslint.org/docs/rules/no-mixed-spaces-and-tabs" }, schema: [{ enum: ["smart-tabs", true, false] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var smartTabs = void 0; var ignoredLocs = []; switch (context.options[0]) { case true: // Support old syntax, maybe add deprecation warning here case "smart-tabs": smartTabs = true; break; default: smartTabs = false; } /** * Determines if a given line and column are before a location. * @param {Location} loc The location object from an AST node. * @param {int} line The line to check. * @param {int} column The column to check. * @returns {boolean} True if the line and column are before the location, false if not. * @private */ function beforeLoc(loc, line, column) { if (line < loc.start.line) { return true; } return line === loc.start.line && column < loc.start.column; } /** * Determines if a given line and column are after a location. * @param {Location} loc The location object from an AST node. * @param {int} line The line to check. * @param {int} column The column to check. * @returns {boolean} True if the line and column are after the location, false if not. * @private */ function afterLoc(loc, line, column) { if (line > loc.end.line) { return true; } return line === loc.end.line && column > loc.end.column; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { TemplateElement: function TemplateElement(node) { ignoredLocs.push(node.loc); }, "Program:exit": function ProgramExit(node) { /* * At least one space followed by a tab * or the reverse before non-tab/-space * characters begin. */ var regex = /^(?=[\t ]*(\t | \t))/; var lines = sourceCode.lines, comments = sourceCode.getAllComments(); comments.forEach(function (comment) { ignoredLocs.push(comment.loc); }); ignoredLocs.sort(function (first, second) { if (beforeLoc(first, second.start.line, second.start.column)) { return 1; } if (beforeLoc(second, first.start.line, second.start.column)) { return -1; } return 0; }); if (smartTabs) { /* * At least one space followed by a tab * before non-tab/-space characters begin. */ regex = /^(?=[\t ]* \t)/; } lines.forEach(function (line, i) { var match = regex.exec(line); if (match) { var lineNumber = i + 1, column = match.index + 1; for (var j = 0; j < ignoredLocs.length; j++) { if (beforeLoc(ignoredLocs[j], lineNumber, column)) { continue; } if (afterLoc(ignoredLocs[j], lineNumber, column)) { continue; } return; } context.report({ node: node, loc: { line: lineNumber, column: column }, message: "Mixed spaces and tabs." }); } }); } }; } }; },{}],259:[function(require,module,exports){ /** * @fileoverview Rule to check use of chained assignment expressions * @author Stewart Rand */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow use of chained assignment expressions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-multi-assign" }, schema: [] }, create: function create(context) { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { AssignmentExpression: function AssignmentExpression(node) { if (["AssignmentExpression", "VariableDeclarator"].indexOf(node.parent.type) !== -1) { context.report({ node: node, message: "Unexpected chained assignment." }); } } }; } }; },{}],260:[function(require,module,exports){ /** * @fileoverview Disallow use of multiple spaces. * @author Nicholas C. Zakas */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow multiple spaces", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-multi-spaces" }, fixable: "whitespace", schema: [{ type: "object", properties: { exceptions: { type: "object", patternProperties: { "^([A-Z][a-z]*)+$": { type: "boolean" } }, additionalProperties: false }, ignoreEOLComments: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var options = context.options[0] || {}; var ignoreEOLComments = options.ignoreEOLComments; var exceptions = Object.assign({ Property: true }, options.exceptions); var hasExceptions = Object.keys(exceptions).filter(function (key) { return exceptions[key]; }).length > 0; /** * Formats value of given comment token for error message by truncating its length. * @param {Token} token comment token * @returns {string} formatted value * @private */ function formatReportedCommentValue(token) { var valueLines = token.value.split("\n"); var value = valueLines[0]; var formattedValue = value.slice(0, 12) + "..."; return valueLines.length === 1 && value.length <= 12 ? value : formattedValue; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function Program() { sourceCode.tokensAndComments.forEach(function (leftToken, leftIndex, tokensAndComments) { if (leftIndex === tokensAndComments.length - 1) { return; } var rightToken = tokensAndComments[leftIndex + 1]; // Ignore tokens that don't have 2 spaces between them or are on different lines if (!sourceCode.text.slice(leftToken.range[1], rightToken.range[0]).includes(" ") || leftToken.loc.end.line < rightToken.loc.start.line) { return; } // Ignore comments that are the last token on their line if `ignoreEOLComments` is active. if (ignoreEOLComments && astUtils.isCommentToken(rightToken) && (leftIndex === tokensAndComments.length - 2 || rightToken.loc.end.line < tokensAndComments[leftIndex + 2].loc.start.line)) { return; } // Ignore tokens that are in a node in the "exceptions" object if (hasExceptions) { var parentNode = sourceCode.getNodeByRangeIndex(rightToken.range[0] - 1); if (parentNode && exceptions[parentNode.type]) { return; } } var displayValue = void 0; if (rightToken.type === "Block") { displayValue = "/*" + formatReportedCommentValue(rightToken) + "*/"; } else if (rightToken.type === "Line") { displayValue = "//" + formatReportedCommentValue(rightToken); } else { displayValue = rightToken.value; } context.report({ node: rightToken, loc: rightToken.loc.start, message: "Multiple spaces found before '{{displayValue}}'.", data: { displayValue: displayValue }, fix: function fix(fixer) { return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " "); } }); }); } }; } }; },{"../util/ast-utils":405}],261:[function(require,module,exports){ /** * @fileoverview Rule to flag when using multiline strings * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow multiline strings", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-multi-str" }, schema: [] }, create: function create(context) { /** * Determines if a given node is part of JSX syntax. * @param {ASTNode} node The node to check. * @returns {boolean} True if the node is a JSX node, false if not. * @private */ function isJSXElement(node) { return node.type.indexOf("JSX") === 0; } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { Literal: function Literal(node) { if (astUtils.LINEBREAK_MATCHER.test(node.raw) && !isJSXElement(node.parent)) { context.report({ node: node, message: "Multiline support is limited to browsers supporting ES5 only." }); } } }; } }; },{"../util/ast-utils":405}],262:[function(require,module,exports){ /** * @fileoverview Disallows multiple blank lines. * implementation adapted from the no-trailing-spaces rule. * @author Greg Cochard */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow multiple empty lines", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-multiple-empty-lines" }, fixable: "whitespace", schema: [{ type: "object", properties: { max: { type: "integer", minimum: 0 }, maxEOF: { type: "integer", minimum: 0 }, maxBOF: { type: "integer", minimum: 0 } }, required: ["max"], additionalProperties: false }] }, create: function create(context) { // Use options.max or 2 as default var max = 2, maxEOF = max, maxBOF = max; if (context.options.length) { max = context.options[0].max; maxEOF = typeof context.options[0].maxEOF !== "undefined" ? context.options[0].maxEOF : max; maxBOF = typeof context.options[0].maxBOF !== "undefined" ? context.options[0].maxBOF : max; } var sourceCode = context.getSourceCode(); // Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue var allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines; var templateLiteralLines = new Set(); //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { TemplateLiteral: function TemplateLiteral(node) { node.quasis.forEach(function (literalPart) { // Empty lines have a semantic meaning if they're inside template literals. Don't count these as empty lines. for (var ignoredLine = literalPart.loc.start.line; ignoredLine < literalPart.loc.end.line; ignoredLine++) { templateLiteralLines.add(ignoredLine); } }); }, "Program:exit": function ProgramExit(node) { return allLines // Given a list of lines, first get a list of line numbers that are non-empty. .reduce(function (nonEmptyLineNumbers, line, index) { if (line.trim() || templateLiteralLines.has(index + 1)) { nonEmptyLineNumbers.push(index + 1); } return nonEmptyLineNumbers; }, []) // Add a value at the end to allow trailing empty lines to be checked. .concat(allLines.length + 1) // Given two line numbers of non-empty lines, report the lines between if the difference is too large. .reduce(function (lastLineNumber, lineNumber) { var message = void 0, maxAllowed = void 0; if (lastLineNumber === 0) { message = "Too many blank lines at the beginning of file. Max of {{max}} allowed."; maxAllowed = maxBOF; } else if (lineNumber === allLines.length + 1) { message = "Too many blank lines at the end of file. Max of {{max}} allowed."; maxAllowed = maxEOF; } else { message = "More than {{max}} blank {{pluralizedLines}} not allowed."; maxAllowed = max; } if (lineNumber - lastLineNumber - 1 > maxAllowed) { context.report({ node: node, loc: { start: { line: lastLineNumber + 1, column: 0 }, end: { line: lineNumber, column: 0 } }, message: message, data: { max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines" }, fix: function fix(fixer) { var rangeStart = sourceCode.getIndexFromLoc({ line: lastLineNumber + 1, column: 0 }); /* * The end of the removal range is usually the start index of the next line. * However, at the end of the file there is no next line, so the end of the * range is just the length of the text. */ var lineNumberAfterRemovedLines = lineNumber - maxAllowed; var rangeEnd = lineNumberAfterRemovedLines <= allLines.length ? sourceCode.getIndexFromLoc({ line: lineNumberAfterRemovedLines, column: 0 }) : sourceCode.text.length; return fixer.removeRange([rangeStart, rangeEnd]); } }); } return lineNumber; }, 0); } }; } }; },{}],263:[function(require,module,exports){ /** * @fileoverview Rule to disallow assignments to native objects or read-only global variables * @author Ilya Volodin * @deprecated in ESLint v3.3.0 */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow assignments to native objects or read-only global variables", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-native-reassign" }, deprecated: true, replacedBy: ["no-global-assign"], schema: [{ type: "object", properties: { exceptions: { type: "array", items: { type: "string" }, uniqueItems: true } }, additionalProperties: false }] }, create: function create(context) { var config = context.options[0]; var exceptions = config && config.exceptions || []; /** * Reports write references. * @param {Reference} reference - A reference to check. * @param {int} index - The index of the reference in the references. * @param {Reference[]} references - The array that the reference belongs to. * @returns {void} */ function checkReference(reference, index, references) { var identifier = reference.identifier; if (reference.init === false && reference.isWrite() && ( /* * Destructuring assignments can have multiple default value, * so possibly there are multiple writeable references for the same identifier. */ index === 0 || references[index - 1].identifier !== identifier)) { context.report({ node: identifier, message: "Read-only global '{{name}}' should not be modified.", data: identifier }); } } /** * Reports write references if a given variable is read-only builtin. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { variable.references.forEach(checkReference); } } return { Program: function Program() { var globalScope = context.getScope(); globalScope.variables.forEach(checkVariable); } }; } }; },{}],264:[function(require,module,exports){ /** * @fileoverview Rule to disallow a negated condition * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow negated conditions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-negated-condition" }, schema: [] }, create: function create(context) { /** * Determines if a given node is an if-else without a condition on the else * @param {ASTNode} node The node to check. * @returns {boolean} True if the node has an else without an if. * @private */ function hasElseWithoutCondition(node) { return node.alternate && node.alternate.type !== "IfStatement"; } /** * Determines if a given node is a negated unary expression * @param {Object} test The test object to check. * @returns {boolean} True if the node is a negated unary expression. * @private */ function isNegatedUnaryExpression(test) { return test.type === "UnaryExpression" && test.operator === "!"; } /** * Determines if a given node is a negated binary expression * @param {Test} test The test to check. * @returns {boolean} True if the node is a negated binary expression. * @private */ function isNegatedBinaryExpression(test) { return test.type === "BinaryExpression" && (test.operator === "!=" || test.operator === "!=="); } /** * Determines if a given node has a negated if expression * @param {ASTNode} node The node to check. * @returns {boolean} True if the node has a negated if expression. * @private */ function isNegatedIf(node) { return isNegatedUnaryExpression(node.test) || isNegatedBinaryExpression(node.test); } return { IfStatement: function IfStatement(node) { if (!hasElseWithoutCondition(node)) { return; } if (isNegatedIf(node)) { context.report({ node: node, message: "Unexpected negated condition." }); } }, ConditionalExpression: function ConditionalExpression(node) { if (isNegatedIf(node)) { context.report({ node: node, message: "Unexpected negated condition." }); } } }; } }; },{}],265:[function(require,module,exports){ /** * @fileoverview A rule to disallow negated left operands of the `in` operator * @author Michael Ficarra * @deprecated in ESLint v3.3.0 */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow negating the left operand in `in` expressions", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-negated-in-lhs" }, replacedBy: ["no-unsafe-negation"], deprecated: true, schema: [] }, create: function create(context) { return { BinaryExpression: function BinaryExpression(node) { if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") { context.report({ node: node, message: "The 'in' expression's left operand is negated." }); } } }; } }; },{}],266:[function(require,module,exports){ /** * @fileoverview Rule to flag nested ternary expressions * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow nested ternary expressions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-nested-ternary" }, schema: [] }, create: function create(context) { return { ConditionalExpression: function ConditionalExpression(node) { if (node.alternate.type === "ConditionalExpression" || node.consequent.type === "ConditionalExpression") { context.report({ node: node, message: "Do not nest ternary expressions." }); } } }; } }; },{}],267:[function(require,module,exports){ /** * @fileoverview Rule to flag when using new Function * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `new` operators with the `Function` object", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-new-func" }, schema: [] }, create: function create(context) { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports a node. * @param {ASTNode} node The node to report * @returns {void} * @private */ function report(node) { context.report({ node: node, message: "The Function constructor is eval." }); } return { "NewExpression[callee.name = 'Function']": report, "CallExpression[callee.name = 'Function']": report }; } }; },{}],268:[function(require,module,exports){ /** * @fileoverview A rule to disallow calls to the Object constructor * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `Object` constructors", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-new-object" }, schema: [] }, create: function create(context) { return { NewExpression: function NewExpression(node) { if (node.callee.name === "Object") { context.report({ node: node, message: "The object literal notation {} is preferrable." }); } } }; } }; },{}],269:[function(require,module,exports){ /** * @fileoverview Rule to disallow use of new operator with the `require` function * @author Wil Moore III */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `new` operators with calls to `require`", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-new-require" }, schema: [] }, create: function create(context) { return { NewExpression: function NewExpression(node) { if (node.callee.type === "Identifier" && node.callee.name === "require") { context.report({ node: node, message: "Unexpected use of new with require." }); } } }; } }; },{}],270:[function(require,module,exports){ /** * @fileoverview Rule to disallow use of the new operator with the `Symbol` object * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow `new` operators with the `Symbol` object", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/no-new-symbol" }, schema: [] }, create: function create(context) { return { "Program:exit": function ProgramExit() { var globalScope = context.getScope(); var variable = globalScope.set.get("Symbol"); if (variable && variable.defs.length === 0) { variable.references.forEach(function (ref) { var node = ref.identifier; if (node.parent && node.parent.type === "NewExpression") { context.report({ node: node, message: "`Symbol` cannot be called as a constructor." }); } }); } } }; } }; },{}],271:[function(require,module,exports){ /** * @fileoverview Rule to flag when using constructor for wrapper objects * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `new` operators with the `String`, `Number`, and `Boolean` objects", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-new-wrappers" }, schema: [] }, create: function create(context) { return { NewExpression: function NewExpression(node) { var wrapperObjects = ["String", "Number", "Boolean", "Math", "JSON"]; if (wrapperObjects.indexOf(node.callee.name) > -1) { context.report({ node: node, message: "Do not use {{fn}} as a constructor.", data: { fn: node.callee.name } }); } } }; } }; },{}],272:[function(require,module,exports){ /** * @fileoverview Rule to flag statements with function invocation preceded by * "new" and not part of assignment * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `new` operators outside of assignments or comparisons", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-new" }, schema: [] }, create: function create(context) { return { "ExpressionStatement > NewExpression": function ExpressionStatementNewExpression(node) { context.report({ node: node.parent, message: "Do not use 'new' for side effects." }); } }; } }; },{}],273:[function(require,module,exports){ /** * @fileoverview Rule to flag use of an object property of the global object (Math and JSON) as a function * @author James Allardice */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow calling global object properties as functions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-obj-calls" }, schema: [] }, create: function create(context) { return { CallExpression: function CallExpression(node) { if (node.callee.type === "Identifier") { var name = node.callee.name; if (name === "Math" || name === "JSON" || name === "Reflect") { context.report({ node: node, message: "'{{name}}' is not a function.", data: { name: name } }); } } } }; } }; },{}],274:[function(require,module,exports){ /** * @fileoverview Rule to flag octal escape sequences in string literals. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow octal escape sequences in string literals", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-octal-escape" }, schema: [] }, create: function create(context) { return { Literal: function Literal(node) { if (typeof node.value !== "string") { return; } var match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/); if (match) { var octalDigit = match[2]; // \0 is actually not considered an octal if (match[2] !== "0" || typeof match[3] !== "undefined") { context.report({ node: node, message: "Don't use octal: '\\{{octalDigit}}'. Use '\\u....' instead.", data: { octalDigit: octalDigit } }); } } } }; } }; },{}],275:[function(require,module,exports){ /** * @fileoverview Rule to flag when initializing octal literal * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow octal literals", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-octal" }, schema: [] }, create: function create(context) { return { Literal: function Literal(node) { if (typeof node.value === "number" && /^0[0-7]/.test(node.raw)) { context.report({ node: node, message: "Octal literals should not be used." }); } } }; } }; },{}],276:[function(require,module,exports){ /** * @fileoverview Disallow reassignment of function parameters. * @author Nat Burns */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/; module.exports = { meta: { type: "suggestion", docs: { description: "disallow reassigning `function` parameters", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-param-reassign" }, schema: [{ oneOf: [{ type: "object", properties: { props: { enum: [false] } }, additionalProperties: false }, { type: "object", properties: { props: { enum: [true] }, ignorePropertyModificationsFor: { type: "array", items: { type: "string" }, uniqueItems: true } }, additionalProperties: false }] }] }, create: function create(context) { var props = context.options[0] && Boolean(context.options[0].props); var ignoredPropertyAssignmentsFor = context.options[0] && context.options[0].ignorePropertyModificationsFor || []; /** * Checks whether or not the reference modifies properties of its variable. * @param {Reference} reference - A reference to check. * @returns {boolean} Whether or not the reference modifies properties of its variable. */ function isModifyingProp(reference) { var node = reference.identifier; var parent = node.parent; while (parent && !stopNodePattern.test(parent.type)) { switch (parent.type) { // e.g. foo.a = 0; case "AssignmentExpression": return parent.left === node; // e.g. ++foo.a; case "UpdateExpression": return true; // e.g. delete foo.a; case "UnaryExpression": if (parent.operator === "delete") { return true; } break; // EXCLUDES: e.g. cache.get(foo.a).b = 0; case "CallExpression": if (parent.callee !== node) { return false; } break; // EXCLUDES: e.g. cache[foo.a] = 0; case "MemberExpression": if (parent.property === node) { return false; } break; // EXCLUDES: e.g. ({ [foo]: a }) = bar; case "Property": if (parent.key === node) { return false; } break; // no default } node = parent; parent = node.parent; } return false; } /** * Reports a reference if is non initializer and writable. * @param {Reference} reference - A reference to check. * @param {int} index - The index of the reference in the references. * @param {Reference[]} references - The array that the reference belongs to. * @returns {void} */ function checkReference(reference, index, references) { var identifier = reference.identifier; if (identifier && !reference.init && ( /* * Destructuring assignments can have multiple default value, * so possibly there are multiple writeable references for the same identifier. */ index === 0 || references[index - 1].identifier !== identifier)) { if (reference.isWrite()) { context.report({ node: identifier, message: "Assignment to function parameter '{{name}}'.", data: { name: identifier.name } }); } else if (props && isModifyingProp(reference) && ignoredPropertyAssignmentsFor.indexOf(identifier.name) === -1) { context.report({ node: identifier, message: "Assignment to property of function parameter '{{name}}'.", data: { name: identifier.name } }); } } } /** * Finds and reports references that are non initializer and writable. * @param {Variable} variable - A variable to check. * @returns {void} */ function checkVariable(variable) { if (variable.defs[0].type === "Parameter") { variable.references.forEach(checkReference); } } /** * Checks parameters of a given function node. * @param {ASTNode} node - A function node to check. * @returns {void} */ function checkForFunction(node) { context.getDeclaredVariables(node).forEach(checkVariable); } return { // `:exit` is needed for the `node.parent` property of identifier nodes. "FunctionDeclaration:exit": checkForFunction, "FunctionExpression:exit": checkForFunction, "ArrowFunctionExpression:exit": checkForFunction }; } }; },{}],277:[function(require,module,exports){ /** * @fileoverview Disallow string concatenation when using __dirname and __filename * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow string concatenation with `__dirname` and `__filename`", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-path-concat" }, schema: [] }, create: function create(context) { var MATCHER = /^__(?:dir|file)name$/; //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { BinaryExpression: function BinaryExpression(node) { var left = node.left, right = node.right; if (node.operator === "+" && (left.type === "Identifier" && MATCHER.test(left.name) || right.type === "Identifier" && MATCHER.test(right.name))) { context.report({ node: node, message: "Use path.join() or path.resolve() instead of + to create paths." }); } } }; } }; },{}],278:[function(require,module,exports){ /** * @fileoverview Rule to flag use of unary increment and decrement operators. * @author Ian Christian Myers * @author Brody McKee (github.com/mrmckeb) */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; module.exports = { meta: { type: "suggestion", docs: { description: "disallow the unary operators `++` and `--`", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-plusplus" }, schema: [{ type: "object", properties: { allowForLoopAfterthoughts: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var config = context.options[0]; var allowInForAfterthought = false; if ((typeof config === "undefined" ? "undefined" : _typeof(config)) === "object") { allowInForAfterthought = config.allowForLoopAfterthoughts === true; } return { UpdateExpression: function UpdateExpression(node) { if (allowInForAfterthought && node.parent.type === "ForStatement") { return; } context.report({ node: node, message: "Unary operator '{{operator}}' used.", data: { operator: node.operator } }); } }; } }; },{}],279:[function(require,module,exports){ /** * @fileoverview Disallow the use of process.env() * @author Vignesh Anand */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `process.env`", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-process-env" }, schema: [] }, create: function create(context) { return { MemberExpression: function MemberExpression(node) { var objectName = node.object.name, propertyName = node.property.name; if (objectName === "process" && !node.computed && propertyName && propertyName === "env") { context.report({ node: node, message: "Unexpected use of process.env." }); } } }; } }; },{}],280:[function(require,module,exports){ /** * @fileoverview Disallow the use of process.exit() * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `process.exit()`", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-process-exit" }, schema: [] }, create: function create(context) { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { "CallExpression > MemberExpression.callee[object.name = 'process'][property.name = 'exit']": function CallExpressionMemberExpressionCalleeObjectNameProcessPropertyNameExit(node) { context.report({ node: node.parent, message: "Don't use process.exit(); throw an error instead." }); } }; } }; },{}],281:[function(require,module,exports){ /** * @fileoverview Rule to flag usage of __proto__ property * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of the `__proto__` property", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-proto" }, schema: [] }, create: function create(context) { return { MemberExpression: function MemberExpression(node) { if (node.property && node.property.type === "Identifier" && node.property.name === "__proto__" && !node.computed || node.property.type === "Literal" && node.property.value === "__proto__") { context.report({ node: node, message: "The '__proto__' property is deprecated." }); } } }; } }; },{}],282:[function(require,module,exports){ /** * @fileoverview Rule to disallow use of Object.prototype builtins on objects * @author Andrew Levine */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow calling some `Object.prototype` methods directly on objects", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-prototype-builtins" }, schema: [] }, create: function create(context) { var DISALLOWED_PROPS = ["hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable"]; /** * Reports if a disallowed property is used in a CallExpression * @param {ASTNode} node The CallExpression node. * @returns {void} */ function disallowBuiltIns(node) { if (node.callee.type !== "MemberExpression" || node.callee.computed) { return; } var propName = node.callee.property.name; if (DISALLOWED_PROPS.indexOf(propName) > -1) { context.report({ message: "Do not access Object.prototype method '{{prop}}' from target object.", loc: node.callee.property.loc.start, data: { prop: propName }, node: node }); } } return { CallExpression: disallowBuiltIns }; } }; },{}],283:[function(require,module,exports){ /** * @fileoverview Rule to flag when the same variable is declared more then once. * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow variable redeclaration", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-redeclare" }, schema: [{ type: "object", properties: { builtinGlobals: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = { builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals) }; /** * Find variables in a given scope and flag redeclared ones. * @param {Scope} scope - An eslint-scope scope object. * @returns {void} * @private */ function findVariablesInScope(scope) { scope.variables.forEach(function (variable) { var hasBuiltin = options.builtinGlobals && "writeable" in variable; var count = (hasBuiltin ? 1 : 0) + variable.identifiers.length; if (count >= 2) { variable.identifiers.sort(function (a, b) { return a.range[1] - b.range[1]; }); for (var i = hasBuiltin ? 0 : 1, l = variable.identifiers.length; i < l; i++) { context.report({ node: variable.identifiers[i], message: "'{{a}}' is already defined.", data: { a: variable.name } }); } } }); } /** * Find variables in the current scope. * @param {ASTNode} node - The Program node. * @returns {void} * @private */ function checkForGlobal(node) { var scope = context.getScope(), parserOptions = context.parserOptions, ecmaFeatures = parserOptions.ecmaFeatures || {}; // Nodejs env or modules has a special scope. if (ecmaFeatures.globalReturn || node.sourceType === "module") { findVariablesInScope(scope.childScopes[0]); } else { findVariablesInScope(scope); } } /** * Find variables in the current scope. * @returns {void} * @private */ function checkForBlock() { findVariablesInScope(context.getScope()); } if (context.parserOptions.ecmaVersion >= 6) { return { Program: checkForGlobal, BlockStatement: checkForBlock, SwitchStatement: checkForBlock }; } return { Program: checkForGlobal, FunctionDeclaration: checkForBlock, FunctionExpression: checkForBlock, ArrowFunctionExpression: checkForBlock }; } }; },{}],284:[function(require,module,exports){ /** * @fileoverview Rule to count multiple spaces in regular expressions * @author Matt DuVall */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow multiple spaces in regular expressions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-regex-spaces" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Validate regular expressions * @param {ASTNode} node node to validate * @param {string} value regular expression to validate * @param {number} valueStart The start location of the regex/string literal. It will always be the case that * `sourceCode.getText().slice(valueStart, valueStart + value.length) === value` * @returns {void} * @private */ function checkRegex(node, value, valueStart) { var multipleSpacesRegex = /( {2,})( [+*{?]|[^+*{?]|$)/, regexResults = multipleSpacesRegex.exec(value); if (regexResults !== null) { var count = regexResults[1].length; context.report({ node: node, message: "Spaces are hard to count. Use {{{count}}}.", data: { count: count }, fix: function fix(fixer) { return fixer.replaceTextRange([valueStart + regexResults.index, valueStart + regexResults.index + count], " {" + count + "}"); } }); /* * TODO: (platinumazure) Fix message to use rule message * substitution when api.report is fixed in lib/eslint.js. */ } } /** * Validate regular expression literals * @param {ASTNode} node node to validate * @returns {void} * @private */ function checkLiteral(node) { var token = sourceCode.getFirstToken(node), nodeType = token.type, nodeValue = token.value; if (nodeType === "RegularExpression") { checkRegex(node, nodeValue, token.range[0]); } } /** * Check if node is a string * @param {ASTNode} node node to evaluate * @returns {boolean} True if its a string * @private */ function isString(node) { return node && node.type === "Literal" && typeof node.value === "string"; } /** * Validate strings passed to the RegExp constructor * @param {ASTNode} node node to validate * @returns {void} * @private */ function checkFunction(node) { var scope = context.getScope(); var regExpVar = astUtils.getVariableByName(scope, "RegExp"); var shadowed = regExpVar && regExpVar.defs.length > 0; if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0]) && !shadowed) { checkRegex(node, node.arguments[0].value, node.arguments[0].range[0] + 1); } } return { Literal: checkLiteral, CallExpression: checkFunction, NewExpression: checkFunction }; } }; },{"../util/ast-utils":405}],285:[function(require,module,exports){ /** * @fileoverview Restrict usage of specified globals. * @author Benoît Zugmeyer */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var DEFAULT_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'.", CUSTOM_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'. {{customMessage}}"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow specified global variables", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-restricted-globals" }, schema: { type: "array", items: { oneOf: [{ type: "string" }, { type: "object", properties: { name: { type: "string" }, message: { type: "string" } }, required: ["name"], additionalProperties: false }] }, uniqueItems: true, minItems: 0 } }, create: function create(context) { // If no globals are restricted, we don't need to do anything if (context.options.length === 0) { return {}; } var restrictedGlobalMessages = context.options.reduce(function (memo, option) { if (typeof option === "string") { memo[option] = null; } else { memo[option.name] = option.message; } return memo; }, {}); /** * Report a variable to be used as a restricted global. * @param {Reference} reference the variable reference * @returns {void} * @private */ function reportReference(reference) { var name = reference.identifier.name, customMessage = restrictedGlobalMessages[name], message = customMessage ? CUSTOM_MESSAGE_TEMPLATE : DEFAULT_MESSAGE_TEMPLATE; context.report({ node: reference.identifier, message: message, data: { name: name, customMessage: customMessage } }); } /** * Check if the given name is a restricted global name. * @param {string} name name of a variable * @returns {boolean} whether the variable is a restricted global or not * @private */ function isRestricted(name) { return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name); } return { Program: function Program() { var scope = context.getScope(); // Report variables declared elsewhere (ex: variables defined as "global" by eslint) scope.variables.forEach(function (variable) { if (!variable.defs.length && isRestricted(variable.name)) { variable.references.forEach(reportReference); } }); // Report variables not declared at all scope.through.forEach(function (reference) { if (isRestricted(reference.identifier.name)) { reportReference(reference); } }); } }; } }; },{}],286:[function(require,module,exports){ /** * @fileoverview Restrict usage of specified node imports. * @author Guy Ellis */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var DEFAULT_MESSAGE_TEMPLATE = "'{{importSource}}' import is restricted from being used."; var CUSTOM_MESSAGE_TEMPLATE = "'{{importSource}}' import is restricted from being used. {{customMessage}}"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var ignore = require("ignore"); var arrayOfStrings = { type: "array", items: { type: "string" }, uniqueItems: true }; var arrayOfStringsOrObjects = { type: "array", items: { anyOf: [{ type: "string" }, { type: "object", properties: { name: { type: "string" }, message: { type: "string", minLength: 1 }, importNames: { type: "array", items: { type: "string" } } }, additionalProperties: false, required: ["name"] }] }, uniqueItems: true }; module.exports = { meta: { type: "suggestion", docs: { description: "disallow specified modules when loaded by `import`", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-restricted-imports" }, schema: { anyOf: [arrayOfStringsOrObjects, { type: "array", items: { type: "object", properties: { paths: arrayOfStringsOrObjects, patterns: arrayOfStrings }, additionalProperties: false }, additionalItems: false }] } }, create: function create(context) { var options = Array.isArray(context.options) ? context.options : []; var isPathAndPatternsObject = _typeof(options[0]) === "object" && (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns")); var restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || []; var restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; var restrictedPathMessages = restrictedPaths.reduce(function (memo, importSource) { if (typeof importSource === "string") { memo[importSource] = { message: null }; } else { memo[importSource.name] = { message: importSource.message, importNames: importSource.importNames }; } return memo; }, {}); // if no imports are restricted we don"t need to check if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) { return {}; } var restrictedPatternsMatcher = ignore().add(restrictedPatterns); /** * Checks to see if "*" is being used to import everything. * @param {Set.} importNames - Set of import names that are being imported * @returns {boolean} whether everything is imported or not */ function isEverythingImported(importNames) { return importNames.has("*"); } /** * Report a restricted path. * @param {node} node representing the restricted path reference * @returns {void} * @private */ function reportPath(node) { var importSource = node.source.value.trim(); var customMessage = restrictedPathMessages[importSource] && restrictedPathMessages[importSource].message; var message = customMessage ? CUSTOM_MESSAGE_TEMPLATE : DEFAULT_MESSAGE_TEMPLATE; context.report({ node: node, message: message, data: { importSource: importSource, customMessage: customMessage } }); } /** * Report a restricted path specifically for patterns. * @param {node} node - representing the restricted path reference * @returns {void} * @private */ function reportPathForPatterns(node) { var importSource = node.source.value.trim(); context.report({ node: node, message: "'{{importSource}}' import is restricted from being used by a pattern.", data: { importSource: importSource } }); } /** * Report a restricted path specifically when using the '*' import. * @param {string} importSource - path of the import * @param {node} node - representing the restricted path reference * @returns {void} * @private */ function reportPathForEverythingImported(importSource, node) { var importNames = restrictedPathMessages[importSource].importNames; context.report({ node: node, message: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.", data: { importSource: importSource, importNames: importNames } }); } /** * Check if the given importSource is restricted because '*' is being imported. * @param {string} importSource - path of the import * @param {Set.} importNames - Set of import names that are being imported * @returns {boolean} whether the path is restricted * @private */ function isRestrictedForEverythingImported(importSource, importNames) { return Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource) && restrictedPathMessages[importSource].importNames && isEverythingImported(importNames); } /** * Check if the given importNames are restricted given a list of restrictedImportNames. * @param {Set.} importNames - Set of import names that are being imported * @param {string[]} restrictedImportNames - array of import names that are restricted for this import * @returns {boolean} whether the objectName is restricted * @private */ function isRestrictedObject(importNames, restrictedImportNames) { return restrictedImportNames.some(function (restrictedObjectName) { return importNames.has(restrictedObjectName); }); } /** * Check if the given importSource is a restricted path. * @param {string} importSource - path of the import * @param {Set.} importNames - Set of import names that are being imported * @returns {boolean} whether the variable is a restricted path or not * @private */ function isRestrictedPath(importSource, importNames) { var isRestricted = false; if (Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) { if (restrictedPathMessages[importSource].importNames) { isRestricted = isRestrictedObject(importNames, restrictedPathMessages[importSource].importNames); } else { isRestricted = true; } } return isRestricted; } /** * Check if the given importSource is restricted by a pattern. * @param {string} importSource - path of the import * @returns {boolean} whether the variable is a restricted pattern or not * @private */ function isRestrictedPattern(importSource) { return restrictedPatterns.length > 0 && restrictedPatternsMatcher.ignores(importSource); } /** * Checks a node to see if any problems should be reported. * @param {ASTNode} node The node to check. * @returns {void} * @private */ function checkNode(node) { var importSource = node.source.value.trim(); var importNames = node.specifiers ? node.specifiers.reduce(function (set, specifier) { if (specifier.type === "ImportDefaultSpecifier") { set.add("default"); } else if (specifier.type === "ImportNamespaceSpecifier") { set.add("*"); } else if (specifier.imported) { set.add(specifier.imported.name); } else if (specifier.local) { set.add(specifier.local.name); } return set; }, new Set()) : new Set(); if (isRestrictedForEverythingImported(importSource, importNames)) { reportPathForEverythingImported(importSource, node); } if (isRestrictedPath(importSource, importNames)) { reportPath(node); } if (isRestrictedPattern(importSource)) { reportPathForPatterns(node); } } return { ImportDeclaration: checkNode, ExportNamedDeclaration: function ExportNamedDeclaration(node) { if (node.source) { checkNode(node); } }, ExportAllDeclaration: checkNode }; } }; },{"ignore":86}],287:[function(require,module,exports){ /** * @fileoverview Restrict usage of specified node modules. * @author Christian Schulz */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var DEFAULT_MESSAGE_TEMPLATE = "'{{moduleName}}' module is restricted from being used."; var CUSTOM_MESSAGE_TEMPLATE = "'{{moduleName}}' module is restricted from being used. {{customMessage}}"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var ignore = require("ignore"); var arrayOfStrings = { type: "array", items: { type: "string" }, uniqueItems: true }; var arrayOfStringsOrObjects = { type: "array", items: { anyOf: [{ type: "string" }, { type: "object", properties: { name: { type: "string" }, message: { type: "string", minLength: 1 } }, additionalProperties: false, required: ["name"] }] }, uniqueItems: true }; module.exports = { meta: { type: "suggestion", docs: { description: "disallow specified modules when loaded by `require`", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-restricted-modules" }, schema: { anyOf: [arrayOfStringsOrObjects, { type: "array", items: { type: "object", properties: { paths: arrayOfStringsOrObjects, patterns: arrayOfStrings }, additionalProperties: false }, additionalItems: false }] } }, create: function create(context) { var options = Array.isArray(context.options) ? context.options : []; var isPathAndPatternsObject = _typeof(options[0]) === "object" && (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns")); var restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || []; var restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; var restrictedPathMessages = restrictedPaths.reduce(function (memo, importName) { if (typeof importName === "string") { memo[importName] = null; } else { memo[importName.name] = importName.message; } return memo; }, {}); // if no imports are restricted we don"t need to check if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) { return {}; } var ig = ignore().add(restrictedPatterns); /** * Function to check if a node is a string literal. * @param {ASTNode} node The node to check. * @returns {boolean} If the node is a string literal. */ function isString(node) { return node && node.type === "Literal" && typeof node.value === "string"; } /** * Function to check if a node is a require call. * @param {ASTNode} node The node to check. * @returns {boolean} If the node is a require call. */ function isRequireCall(node) { return node.callee.type === "Identifier" && node.callee.name === "require"; } /** * Report a restricted path. * @param {node} node representing the restricted path reference * @returns {void} * @private */ function reportPath(node) { var moduleName = node.arguments[0].value.trim(); var customMessage = restrictedPathMessages[moduleName]; var message = customMessage ? CUSTOM_MESSAGE_TEMPLATE : DEFAULT_MESSAGE_TEMPLATE; context.report({ node: node, message: message, data: { moduleName: moduleName, customMessage: customMessage } }); } /** * Check if the given name is a restricted path name * @param {string} name name of a variable * @returns {boolean} whether the variable is a restricted path or not * @private */ function isRestrictedPath(name) { return Object.prototype.hasOwnProperty.call(restrictedPathMessages, name); } return { CallExpression: function CallExpression(node) { if (isRequireCall(node)) { // node has arguments and first argument is string if (node.arguments.length && isString(node.arguments[0])) { var moduleName = node.arguments[0].value.trim(); // check if argument value is in restricted modules array if (isRestrictedPath(moduleName)) { reportPath(node); } if (restrictedPatterns.length > 0 && ig.ignores(moduleName)) { context.report({ node: node, message: "'{{moduleName}}' module is restricted from being used by a pattern.", data: { moduleName: moduleName } }); } } } } }; } }; },{"ignore":86}],288:[function(require,module,exports){ /** * @fileoverview Rule to disallow certain object properties * @author Will Klein & Eli White */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow certain properties on certain objects", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-restricted-properties" }, schema: { type: "array", items: { anyOf: [// `object` and `property` are both optional, but at least one of them must be provided. { type: "object", properties: { object: { type: "string" }, property: { type: "string" }, message: { type: "string" } }, additionalProperties: false, required: ["object"] }, { type: "object", properties: { object: { type: "string" }, property: { type: "string" }, message: { type: "string" } }, additionalProperties: false, required: ["property"] }] }, uniqueItems: true } }, create: function create(context) { var restrictedCalls = context.options; if (restrictedCalls.length === 0) { return {}; } var restrictedProperties = new Map(); var globallyRestrictedObjects = new Map(); var globallyRestrictedProperties = new Map(); restrictedCalls.forEach(function (option) { var objectName = option.object; var propertyName = option.property; if (typeof objectName === "undefined") { globallyRestrictedProperties.set(propertyName, { message: option.message }); } else if (typeof propertyName === "undefined") { globallyRestrictedObjects.set(objectName, { message: option.message }); } else { if (!restrictedProperties.has(objectName)) { restrictedProperties.set(objectName, new Map()); } restrictedProperties.get(objectName).set(propertyName, { message: option.message }); } }); /** * Checks to see whether a property access is restricted, and reports it if so. * @param {ASTNode} node The node to report * @param {string} objectName The name of the object * @param {string} propertyName The name of the property * @returns {undefined} */ function checkPropertyAccess(node, objectName, propertyName) { if (propertyName === null) { return; } var matchedObject = restrictedProperties.get(objectName); var matchedObjectProperty = matchedObject ? matchedObject.get(propertyName) : globallyRestrictedObjects.get(objectName); var globalMatchedProperty = globallyRestrictedProperties.get(propertyName); if (matchedObjectProperty) { var message = matchedObjectProperty.message ? " " + matchedObjectProperty.message : ""; context.report({ node: node, // eslint-disable-next-line eslint-plugin/report-message-format message: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", data: { objectName: objectName, propertyName: propertyName, message: message } }); } else if (globalMatchedProperty) { var _message = globalMatchedProperty.message ? " " + globalMatchedProperty.message : ""; context.report({ node: node, // eslint-disable-next-line eslint-plugin/report-message-format message: "'{{propertyName}}' is restricted from being used.{{message}}", data: { propertyName: propertyName, message: _message } }); } } /** * Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);` * @param {ASTNode} node An AssignmentExpression or AssignmentPattern node * @returns {undefined} */ function checkDestructuringAssignment(node) { if (node.right.type === "Identifier") { var objectName = node.right.name; if (node.left.type === "ObjectPattern") { node.left.properties.forEach(function (property) { checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property)); }); } } } return { MemberExpression: function MemberExpression(node) { checkPropertyAccess(node, node.object && node.object.name, astUtils.getStaticPropertyName(node)); }, VariableDeclarator: function VariableDeclarator(node) { if (node.init && node.init.type === "Identifier") { var objectName = node.init.name; if (node.id.type === "ObjectPattern") { node.id.properties.forEach(function (property) { checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property)); }); } } }, AssignmentExpression: checkDestructuringAssignment, AssignmentPattern: checkDestructuringAssignment }; } }; },{"../util/ast-utils":405}],289:[function(require,module,exports){ /** * @fileoverview Rule to flag use of certain node types * @author Burak Yigit Kaya */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } module.exports = { meta: { type: "suggestion", docs: { description: "disallow specified syntax", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-restricted-syntax" }, schema: { type: "array", items: [{ oneOf: [{ type: "string" }, { type: "object", properties: { selector: { type: "string" }, message: { type: "string" } }, required: ["selector"], additionalProperties: false }] }], uniqueItems: true, minItems: 0 } }, create: function create(context) { return context.options.reduce(function (result, selectorOrObject) { var isStringFormat = typeof selectorOrObject === "string"; var hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message); var selector = isStringFormat ? selectorOrObject : selectorOrObject.selector; var message = hasCustomMessage ? selectorOrObject.message : "Using '{{selector}}' is not allowed."; return Object.assign(result, _defineProperty({}, selector, function (node) { context.report({ node: node, message: message, data: hasCustomMessage ? {} : { selector: selector } }); })); }, {}); } }; },{}],290:[function(require,module,exports){ /** * @fileoverview Rule to flag when return statement contains assignment * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow assignment operators in `return` statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-return-assign" }, schema: [{ enum: ["except-parens", "always"] }] }, create: function create(context) { var always = (context.options[0] || "except-parens") !== "except-parens"; var sourceCode = context.getSourceCode(); return { AssignmentExpression: function AssignmentExpression(node) { if (!always && astUtils.isParenthesised(sourceCode, node)) { return; } var currentChild = node; var parent = currentChild.parent; // Find ReturnStatement or ArrowFunctionExpression in ancestors. while (parent && !SENTINEL_TYPE.test(parent.type)) { currentChild = parent; parent = parent.parent; } // Reports. if (parent && parent.type === "ReturnStatement") { context.report({ node: parent, message: "Return statement should not contain assignment." }); } else if (parent && parent.type === "ArrowFunctionExpression" && parent.body === currentChild) { context.report({ node: parent, message: "Arrow function should not return assignment." }); } } }; } }; },{"../util/ast-utils":405}],291:[function(require,module,exports){ /** * @fileoverview Disallows unnecessary `return await` * @author Jordan Harband */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var message = "Redundant use of `await` on a return value."; module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary `return await`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-return-await" }, fixable: null, schema: [] }, create: function create(context) { /** * Reports a found unnecessary `await` expression. * @param {ASTNode} node The node representing the `await` expression to report * @returns {void} */ function reportUnnecessaryAwait(node) { context.report({ node: context.getSourceCode().getFirstToken(node), loc: node.loc, message: message }); } /** * Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting * this function. For example, a statement in a `try` block will always have an error handler. A statement in * a `catch` block will only have an error handler if there is also a `finally` block. * @param {ASTNode} node A node representing a location where an could be thrown * @returns {boolean} `true` if a thrown error will be caught/handled in this function */ function hasErrorHandler(node) { var ancestor = node; while (!astUtils.isFunction(ancestor) && ancestor.type !== "Program") { if (ancestor.parent.type === "TryStatement" && (ancestor === ancestor.parent.block || ancestor === ancestor.parent.handler && ancestor.parent.finalizer)) { return true; } ancestor = ancestor.parent; } return false; } /** * Checks if a node is placed in tail call position. Once `return` arguments (or arrow function expressions) can be a complex expression, * an `await` expression could or could not be unnecessary by the definition of this rule. So we're looking for `await` expressions that are in tail position. * @param {ASTNode} node A node representing the `await` expression to check * @returns {boolean} The checking result */ function isInTailCallPosition(node) { if (node.parent.type === "ArrowFunctionExpression") { return true; } if (node.parent.type === "ReturnStatement") { return !hasErrorHandler(node.parent); } if (node.parent.type === "ConditionalExpression" && (node === node.parent.consequent || node === node.parent.alternate)) { return isInTailCallPosition(node.parent); } if (node.parent.type === "LogicalExpression" && node === node.parent.right) { return isInTailCallPosition(node.parent); } if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) { return isInTailCallPosition(node.parent); } return false; } return { AwaitExpression: function AwaitExpression(node) { if (isInTailCallPosition(node) && !hasErrorHandler(node)) { reportUnnecessaryAwait(node); } } }; } }; },{"../util/ast-utils":405}],292:[function(require,module,exports){ /** * @fileoverview Rule to flag when using javascript: urls * @author Ilya Volodin */ /* jshint scripturl: true */ /* eslint no-script-url: 0 */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `javascript:` urls", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-script-url" }, schema: [] }, create: function create(context) { return { Literal: function Literal(node) { if (node.value && typeof node.value === "string") { var value = node.value.toLowerCase(); if (value.indexOf("javascript:") === 0) { context.report({ node: node, message: "Script URL is a form of eval." }); } } } }; } }; },{}],293:[function(require,module,exports){ /** * @fileoverview Rule to disallow assignments where both sides are exactly the same * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var SPACES = /\s+/g; /** * Checks whether the property of 2 given member expression nodes are the same * property or not. * * @param {ASTNode} left - A member expression node to check. * @param {ASTNode} right - Another member expression node to check. * @returns {boolean} `true` if the member expressions have the same property. */ function isSameProperty(left, right) { if (left.property.type === "Identifier" && left.property.type === right.property.type && left.property.name === right.property.name && left.computed === right.computed) { return true; } var lname = astUtils.getStaticPropertyName(left); var rname = astUtils.getStaticPropertyName(right); return lname !== null && lname === rname; } /** * Checks whether 2 given member expression nodes are the reference to the same * property or not. * * @param {ASTNode} left - A member expression node to check. * @param {ASTNode} right - Another member expression node to check. * @returns {boolean} `true` if the member expressions are the reference to the * same property or not. */ function isSameMember(left, right) { if (!isSameProperty(left, right)) { return false; } var lobj = left.object; var robj = right.object; if (lobj.type !== robj.type) { return false; } if (lobj.type === "MemberExpression") { return isSameMember(lobj, robj); } return lobj.type === "Identifier" && lobj.name === robj.name; } /** * Traverses 2 Pattern nodes in parallel, then reports self-assignments. * * @param {ASTNode|null} left - A left node to traverse. This is a Pattern or * a Property. * @param {ASTNode|null} right - A right node to traverse. This is a Pattern or * a Property. * @param {boolean} props - The flag to check member expressions as well. * @param {Function} report - A callback function to report. * @returns {void} */ function eachSelfAssignment(left, right, props, report) { if (!left || !right) { // do nothing } else if (left.type === "Identifier" && right.type === "Identifier" && left.name === right.name) { report(right); } else if (left.type === "ArrayPattern" && right.type === "ArrayExpression") { var end = Math.min(left.elements.length, right.elements.length); for (var i = 0; i < end; ++i) { var rightElement = right.elements[i]; eachSelfAssignment(left.elements[i], rightElement, props, report); // After a spread element, those indices are unknown. if (rightElement && rightElement.type === "SpreadElement") { break; } } } else if (left.type === "RestElement" && right.type === "SpreadElement") { eachSelfAssignment(left.argument, right.argument, props, report); } else if (left.type === "ObjectPattern" && right.type === "ObjectExpression" && right.properties.length >= 1) { /* * Gets the index of the last spread property. * It's possible to overwrite properties followed by it. */ var startJ = 0; for (var _i = right.properties.length - 1; _i >= 0; --_i) { var propType = right.properties[_i].type; if (propType === "SpreadElement" || propType === "ExperimentalSpreadProperty") { startJ = _i + 1; break; } } for (var _i2 = 0; _i2 < left.properties.length; ++_i2) { for (var j = startJ; j < right.properties.length; ++j) { eachSelfAssignment(left.properties[_i2], right.properties[j], props, report); } } } else if (left.type === "Property" && right.type === "Property" && !left.computed && !right.computed && right.kind === "init" && !right.method && left.key.name === right.key.name) { eachSelfAssignment(left.value, right.value, props, report); } else if (props && left.type === "MemberExpression" && right.type === "MemberExpression" && isSameMember(left, right)) { report(right); } } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow assignments where both sides are exactly the same", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-self-assign" }, schema: [{ type: "object", properties: { props: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var _context$options = _slicedToArray(context.options, 1), _context$options$ = _context$options[0]; _context$options$ = _context$options$ === undefined ? {} : _context$options$; var _context$options$$pro = _context$options$.props, props = _context$options$$pro === undefined ? true : _context$options$$pro; /** * Reports a given node as self assignments. * * @param {ASTNode} node - A node to report. This is an Identifier node. * @returns {void} */ function report(node) { context.report({ node: node, message: "'{{name}}' is assigned to itself.", data: { name: sourceCode.getText(node).replace(SPACES, "") } }); } return { AssignmentExpression: function AssignmentExpression(node) { if (node.operator === "=") { eachSelfAssignment(node.left, node.right, props, report); } } }; } }; },{"../util/ast-utils":405}],294:[function(require,module,exports){ /** * @fileoverview Rule to flag comparison where left part is the same as the right * part. * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow comparisons where both sides are exactly the same", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-self-compare" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Determines whether two nodes are composed of the same tokens. * @param {ASTNode} nodeA The first node * @param {ASTNode} nodeB The second node * @returns {boolean} true if the nodes have identical token representations */ function hasSameTokens(nodeA, nodeB) { var tokensA = sourceCode.getTokens(nodeA); var tokensB = sourceCode.getTokens(nodeB); return tokensA.length === tokensB.length && tokensA.every(function (token, index) { return token.type === tokensB[index].type && token.value === tokensB[index].value; }); } return { BinaryExpression: function BinaryExpression(node) { var operators = new Set(["===", "==", "!==", "!=", ">", "<", ">=", "<="]); if (operators.has(node.operator) && hasSameTokens(node.left, node.right)) { context.report({ node: node, message: "Comparing to itself is potentially pointless." }); } } }; } }; },{}],295:[function(require,module,exports){ /** * @fileoverview Rule to flag use of comma operator * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow comma operators", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-sequences" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Parts of the grammar that are required to have parens. */ var parenthesized = { DoWhileStatement: "test", IfStatement: "test", SwitchStatement: "discriminant", WhileStatement: "test", WithStatement: "object", ArrowFunctionExpression: "body" /* * Omitting CallExpression - commas are parsed as argument separators * Omitting NewExpression - commas are parsed as argument separators * Omitting ForInStatement - parts aren't individually parenthesised * Omitting ForStatement - parts aren't individually parenthesised */ }; /** * Determines whether a node is required by the grammar to be wrapped in * parens, e.g. the test of an if statement. * @param {ASTNode} node - The AST node * @returns {boolean} True if parens around node belong to parent node. */ function requiresExtraParens(node) { return node.parent && parenthesized[node.parent.type] && node === node.parent[parenthesized[node.parent.type]]; } /** * Check if a node is wrapped in parens. * @param {ASTNode} node - The AST node * @returns {boolean} True if the node has a paren on each side. */ function isParenthesised(node) { return astUtils.isParenthesised(sourceCode, node); } /** * Check if a node is wrapped in two levels of parens. * @param {ASTNode} node - The AST node * @returns {boolean} True if two parens surround the node on each side. */ function isParenthesisedTwice(node) { var previousToken = sourceCode.getTokenBefore(node, 1), nextToken = sourceCode.getTokenAfter(node, 1); return isParenthesised(node) && previousToken && nextToken && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; } return { SequenceExpression: function SequenceExpression(node) { // Always allow sequences in for statement update if (node.parent.type === "ForStatement" && (node === node.parent.init || node === node.parent.update)) { return; } // Wrapping a sequence in extra parens indicates intent if (requiresExtraParens(node)) { if (isParenthesisedTwice(node)) { return; } } else { if (isParenthesised(node)) { return; } } var child = sourceCode.getTokenAfter(node.expressions[0]); context.report({ node: node, loc: child.loc.start, message: "Unexpected use of comma operator." }); } }; } }; },{"../util/ast-utils":405}],296:[function(require,module,exports){ /** * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1) * @author Michael Ficarra */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow identifiers from shadowing restricted names", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-shadow-restricted-names" }, schema: [] }, create: function create(context) { var RESTRICTED = ["undefined", "NaN", "Infinity", "arguments", "eval"]; return { "VariableDeclaration, :function, CatchClause": function VariableDeclarationFunctionCatchClause(node) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = context.getDeclaredVariables(node)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var variable = _step.value; if (variable.defs.length > 0 && RESTRICTED.includes(variable.name)) { context.report({ node: variable.defs[0].name, message: "Shadowing of global property '{{idName}}'.", data: { idName: variable.name } }); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }; } }; },{}],297:[function(require,module,exports){ /** * @fileoverview Rule to flag on declaring variables already declared in the outer scope * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow variable declarations from shadowing variables declared in the outer scope", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-shadow" }, schema: [{ type: "object", properties: { builtinGlobals: { type: "boolean" }, hoist: { enum: ["all", "functions", "never"] }, allow: { type: "array", items: { type: "string" } } }, additionalProperties: false }] }, create: function create(context) { var options = { builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals), hoist: context.options[0] && context.options[0].hoist || "functions", allow: context.options[0] && context.options[0].allow || [] }; /** * Check if variable name is allowed. * * @param {ASTNode} variable The variable to check. * @returns {boolean} Whether or not the variable name is allowed. */ function isAllowed(variable) { return options.allow.indexOf(variable.name) !== -1; } /** * Checks if a variable of the class name in the class scope of ClassDeclaration. * * ClassDeclaration creates two variables of its name into its outer scope and its class scope. * So we should ignore the variable in the class scope. * * @param {Object} variable The variable to check. * @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration. */ function isDuplicatedClassNameVariable(variable) { var block = variable.scope.block; return block.type === "ClassDeclaration" && block.id === variable.identifiers[0]; } /** * Checks if a variable is inside the initializer of scopeVar. * * To avoid reporting at declarations such as `var a = function a() {};`. * But it should report `var a = function(a) {};` or `var a = function() { function a() {} };`. * * @param {Object} variable The variable to check. * @param {Object} scopeVar The scope variable to look for. * @returns {boolean} Whether or not the variable is inside initializer of scopeVar. */ function isOnInitializer(variable, scopeVar) { var outerScope = scopeVar.scope; var outerDef = scopeVar.defs[0]; var outer = outerDef && outerDef.parent && outerDef.parent.range; var innerScope = variable.scope; var innerDef = variable.defs[0]; var inner = innerDef && innerDef.name.range; return outer && inner && outer[0] < inner[0] && inner[1] < outer[1] && (innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression" || innerDef.node.type === "ClassExpression") && outerScope === innerScope.upper; } /** * Get a range of a variable's identifier node. * @param {Object} variable The variable to get. * @returns {Array|undefined} The range of the variable's identifier node. */ function getNameRange(variable) { var def = variable.defs[0]; return def && def.name.range; } /** * Checks if a variable is in TDZ of scopeVar. * @param {Object} variable The variable to check. * @param {Object} scopeVar The variable of TDZ. * @returns {boolean} Whether or not the variable is in TDZ of scopeVar. */ function isInTdz(variable, scopeVar) { var outerDef = scopeVar.defs[0]; var inner = getNameRange(variable); var outer = getNameRange(scopeVar); return inner && outer && inner[1] < outer[0] && ( // Excepts FunctionDeclaration if is {"hoist":"function"}. options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration"); } /** * Checks the current context for shadowed variables. * @param {Scope} scope - Fixme * @returns {void} */ function checkForShadows(scope) { var variables = scope.variables; for (var i = 0; i < variables.length; ++i) { var variable = variables[i]; // Skips "arguments" or variables of a class name in the class scope of ClassDeclaration. if (variable.identifiers.length === 0 || isDuplicatedClassNameVariable(variable) || isAllowed(variable)) { continue; } // Gets shadowed variable. var shadowed = astUtils.getVariableByName(scope.upper, variable.name); if (shadowed && (shadowed.identifiers.length > 0 || options.builtinGlobals && "writeable" in shadowed) && !isOnInitializer(variable, shadowed) && !(options.hoist !== "all" && isInTdz(variable, shadowed))) { context.report({ node: variable.identifiers[0], message: "'{{name}}' is already declared in the upper scope.", data: variable }); } } } return { "Program:exit": function ProgramExit() { var globalScope = context.getScope(); var stack = globalScope.childScopes.slice(); while (stack.length) { var scope = stack.pop(); stack.push.apply(stack, _toConsumableArray(scope.childScopes)); checkForShadows(scope); } } }; } }; },{"../util/ast-utils":405}],298:[function(require,module,exports){ /** * @fileoverview Rule to check that spaced function application * @author Matt DuVall * @deprecated in ESLint v3.3.0 */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow spacing between function identifiers and their applications (deprecated)", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-spaced-func" }, deprecated: true, replacedBy: ["func-call-spacing"], fixable: "whitespace", schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Check if open space is present in a function name * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function detectOpenSpaces(node) { var lastCalleeToken = sourceCode.getLastToken(node.callee); var prevToken = lastCalleeToken, parenToken = sourceCode.getTokenAfter(lastCalleeToken); // advances to an open parenthesis. while (parenToken && parenToken.range[1] < node.range[1] && parenToken.value !== "(") { prevToken = parenToken; parenToken = sourceCode.getTokenAfter(parenToken); } // look for a space between the callee and the open paren if (parenToken && parenToken.range[1] < node.range[1] && sourceCode.isSpaceBetweenTokens(prevToken, parenToken)) { context.report({ node: node, loc: lastCalleeToken.loc.start, message: "Unexpected space between function name and paren.", fix: function fix(fixer) { return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); } }); } } return { CallExpression: detectOpenSpaces, NewExpression: detectOpenSpaces }; } }; },{}],299:[function(require,module,exports){ /** * @fileoverview Disallow sparse arrays * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow sparse arrays", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-sparse-arrays" }, schema: [] }, create: function create(context) { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ArrayExpression: function ArrayExpression(node) { var emptySpot = node.elements.indexOf(null) > -1; if (emptySpot) { context.report({ node: node, message: "Unexpected comma in middle of array." }); } } }; } }; },{}],300:[function(require,module,exports){ /** * @fileoverview Rule to check for properties whose identifier ends with the string Sync * @author Matt DuVall */ /* jshint node:true */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } module.exports = { meta: { type: "suggestion", docs: { description: "disallow synchronous methods", category: "Node.js and CommonJS", recommended: false, url: "https://eslint.org/docs/rules/no-sync" }, schema: [{ type: "object", properties: { allowAtRootLevel: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var selector = context.options[0] && context.options[0].allowAtRootLevel ? ":function MemberExpression[property.name=/.*Sync$/]" : "MemberExpression[property.name=/.*Sync$/]"; return _defineProperty({}, selector, function (node) { context.report({ node: node, message: "Unexpected sync method: '{{propertyName}}'.", data: { propertyName: node.property.name } }); }); } }; },{}],301:[function(require,module,exports){ /** * @fileoverview Rule to check for tabs inside a file * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var tabRegex = /\t+/g; var anyNonWhitespaceRegex = /\S/; //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow all tabs", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-tabs" }, schema: [{ type: "object", properties: { allowIndentationTabs: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var allowIndentationTabs = context.options && context.options[0] && context.options[0].allowIndentationTabs; return { Program: function Program(node) { sourceCode.getLines().forEach(function (line, index) { var match = void 0; while ((match = tabRegex.exec(line)) !== null) { if (allowIndentationTabs && !anyNonWhitespaceRegex.test(line.slice(0, match.index))) { continue; } context.report({ node: node, loc: { line: index + 1, column: match.index }, message: "Unexpected tab character." }); } }); } }; } }; },{}],302:[function(require,module,exports){ /** * @fileoverview Warn when using template string syntax in regular strings * @author Jeroen Engels */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow template literal placeholder syntax in regular strings", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/no-template-curly-in-string" }, schema: [] }, create: function create(context) { var regex = /\$\{[^}]+\}/; return { Literal: function Literal(node) { if (typeof node.value === "string" && regex.test(node.value)) { context.report({ node: node, message: "Unexpected template string expression." }); } } }; } }; },{}],303:[function(require,module,exports){ /** * @fileoverview Rule to flag use of ternary operators. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow ternary operators", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-ternary" }, schema: [] }, create: function create(context) { return { ConditionalExpression: function ConditionalExpression(node) { context.report({ node: node, message: "Ternary operator used." }); } }; } }; },{}],304:[function(require,module,exports){ /** * @fileoverview A rule to disallow using `this`/`super` before `super()`. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is a constructor. * @param {ASTNode} node - A node to check. This node type is one of * `Program`, `FunctionDeclaration`, `FunctionExpression`, and * `ArrowFunctionExpression`. * @returns {boolean} `true` if the node is a constructor. */ function isConstructorFunction(node) { return node.type === "FunctionExpression" && node.parent.type === "MethodDefinition" && node.parent.kind === "constructor"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow `this`/`super` before calling `super()` in constructors", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/no-this-before-super" }, schema: [] }, create: function create(context) { /* * Information for each constructor. * - upper: Information of the upper constructor. * - hasExtends: A flag which shows whether the owner class has a valid * `extends` part. * - scope: The scope of the owner class. * - codePath: The code path of this constructor. */ var funcInfo = null; /* * Information for each code path segment. * Each key is the id of a code path segment. * Each value is an object: * - superCalled: The flag which shows `super()` called in all code paths. * - invalidNodes: The array of invalid ThisExpression and Super nodes. */ var segInfoMap = Object.create(null); /** * Gets whether or not `super()` is called in a given code path segment. * @param {CodePathSegment} segment - A code path segment to get. * @returns {boolean} `true` if `super()` is called. */ function isCalled(segment) { return !segment.reachable || segInfoMap[segment.id].superCalled; } /** * Checks whether or not this is in a constructor. * @returns {boolean} `true` if this is in a constructor. */ function isInConstructorOfDerivedClass() { return Boolean(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends); } /** * Checks whether or not this is before `super()` is called. * @returns {boolean} `true` if this is before `super()` is called. */ function isBeforeCallOfSuper() { return isInConstructorOfDerivedClass() && !funcInfo.codePath.currentSegments.every(isCalled); } /** * Sets a given node as invalid. * @param {ASTNode} node - A node to set as invalid. This is one of * a ThisExpression and a Super. * @returns {void} */ function setInvalid(node) { var segments = funcInfo.codePath.currentSegments; for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; if (segment.reachable) { segInfoMap[segment.id].invalidNodes.push(node); } } } /** * Sets the current segment as `super` was called. * @returns {void} */ function setSuperCalled() { var segments = funcInfo.codePath.currentSegments; for (var i = 0; i < segments.length; ++i) { var segment = segments[i]; if (segment.reachable) { segInfoMap[segment.id].superCalled = true; } } } return { /** * Adds information of a constructor into the stack. * @param {CodePath} codePath - A code path which was started. * @param {ASTNode} node - The current node. * @returns {void} */ onCodePathStart: function onCodePathStart(codePath, node) { if (isConstructorFunction(node)) { // Class > ClassBody > MethodDefinition > FunctionExpression var classNode = node.parent.parent.parent; funcInfo = { upper: funcInfo, isConstructor: true, hasExtends: Boolean(classNode.superClass && !astUtils.isNullOrUndefined(classNode.superClass)), codePath: codePath }; } else { funcInfo = { upper: funcInfo, isConstructor: false, hasExtends: false, codePath: codePath }; } }, /** * Removes the top of stack item. * * And this treverses all segments of this code path then reports every * invalid node. * * @param {CodePath} codePath - A code path which was ended. * @returns {void} */ onCodePathEnd: function onCodePathEnd(codePath) { var isDerivedClass = funcInfo.hasExtends; funcInfo = funcInfo.upper; if (!isDerivedClass) { return; } codePath.traverseSegments(function (segment, controller) { var info = segInfoMap[segment.id]; for (var i = 0; i < info.invalidNodes.length; ++i) { var invalidNode = info.invalidNodes[i]; context.report({ message: "'{{kind}}' is not allowed before 'super()'.", node: invalidNode, data: { kind: invalidNode.type === "Super" ? "super" : "this" } }); } if (info.superCalled) { controller.skip(); } }); }, /** * Initialize information of a given code path segment. * @param {CodePathSegment} segment - A code path segment to initialize. * @returns {void} */ onCodePathSegmentStart: function onCodePathSegmentStart(segment) { if (!isInConstructorOfDerivedClass()) { return; } // Initialize info. segInfoMap[segment.id] = { superCalled: segment.prevSegments.length > 0 && segment.prevSegments.every(isCalled), invalidNodes: [] }; }, /** * Update information of the code path segment when a code path was * looped. * @param {CodePathSegment} fromSegment - The code path segment of the * end of a loop. * @param {CodePathSegment} toSegment - A code path segment of the head * of a loop. * @returns {void} */ onCodePathSegmentLoop: function onCodePathSegmentLoop(fromSegment, toSegment) { if (!isInConstructorOfDerivedClass()) { return; } // Update information inside of the loop. funcInfo.codePath.traverseSegments({ first: toSegment, last: fromSegment }, function (segment, controller) { var info = segInfoMap[segment.id]; if (info.superCalled) { info.invalidNodes = []; controller.skip(); } else if (segment.prevSegments.length > 0 && segment.prevSegments.every(isCalled)) { info.superCalled = true; info.invalidNodes = []; } }); }, /** * Reports if this is before `super()`. * @param {ASTNode} node - A target node. * @returns {void} */ ThisExpression: function ThisExpression(node) { if (isBeforeCallOfSuper()) { setInvalid(node); } }, /** * Reports if this is before `super()`. * @param {ASTNode} node - A target node. * @returns {void} */ Super: function Super(node) { if (!astUtils.isCallee(node) && isBeforeCallOfSuper()) { setInvalid(node); } }, /** * Marks `super()` called. * @param {ASTNode} node - A target node. * @returns {void} */ "CallExpression:exit": function CallExpressionExit(node) { if (node.callee.type === "Super" && isBeforeCallOfSuper()) { setSuperCalled(); } }, /** * Resets state. * @returns {void} */ "Program:exit": function ProgramExit() { segInfoMap = Object.create(null); } }; } }; },{"../util/ast-utils":405}],305:[function(require,module,exports){ /** * @fileoverview Rule to restrict what can be thrown as an exception. * @author Dieter Oberkofler */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow throwing literals as exceptions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-throw-literal" }, schema: [] }, create: function create(context) { return { ThrowStatement: function ThrowStatement(node) { if (!astUtils.couldBeError(node.argument)) { context.report({ node: node, message: "Expected an object to be thrown." }); } else if (node.argument.type === "Identifier") { if (node.argument.name === "undefined") { context.report({ node: node, message: "Do not throw undefined." }); } } } }; } }; },{"../util/ast-utils":405}],306:[function(require,module,exports){ /** * @fileoverview Disallow trailing spaces at the end of lines. * @author Nodeca Team */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow trailing whitespace at the end of lines", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-trailing-spaces" }, fixable: "whitespace", schema: [{ type: "object", properties: { skipBlankLines: { type: "boolean" }, ignoreComments: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var BLANK_CLASS = "[ \t\xA0\u2000-\u200B\u3000]", SKIP_BLANK = "^" + BLANK_CLASS + "*$", NONBLANK = BLANK_CLASS + "+$"; var options = context.options[0] || {}, skipBlankLines = options.skipBlankLines || false, ignoreComments = typeof options.ignoreComments === "boolean" && options.ignoreComments; /** * Report the error message * @param {ASTNode} node node to report * @param {int[]} location range information * @param {int[]} fixRange Range based on the whole program * @returns {void} */ function report(node, location, fixRange) { /* * Passing node is a bit dirty, because message data will contain big * text in `source`. But... who cares :) ? * One more kludge will not make worse the bloody wizardry of this * plugin. */ context.report({ node: node, loc: location, message: "Trailing spaces not allowed.", fix: function fix(fixer) { return fixer.removeRange(fixRange); } }); } /** * Given a list of comment nodes, return the line numbers for those comments. * @param {Array} comments An array of comment nodes. * @returns {number[]} An array of line numbers containing comments. */ function getCommentLineNumbers(comments) { var lines = new Set(); comments.forEach(function (comment) { for (var i = comment.loc.start.line; i <= comment.loc.end.line; i++) { lines.add(i); } }); return lines; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function checkTrailingSpaces(node) { /* * Let's hack. Since Espree does not return whitespace nodes, * fetch the source code and do matching via regexps. */ var re = new RegExp(NONBLANK), skipMatch = new RegExp(SKIP_BLANK), lines = sourceCode.lines, linebreaks = sourceCode.getText().match(astUtils.createGlobalLinebreakMatcher()), comments = sourceCode.getAllComments(), commentLineNumbers = getCommentLineNumbers(comments); var totalLength = 0, fixRange = []; for (var i = 0, ii = lines.length; i < ii; i++) { var matches = re.exec(lines[i]); /* * Always add linebreak length to line length to accommodate for line break (\n or \r\n) * Because during the fix time they also reserve one spot in the array. * Usually linebreak length is 2 for \r\n (CRLF) and 1 for \n (LF) */ var linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; var lineLength = lines[i].length + linebreakLength; if (matches) { var location = { line: i + 1, column: matches.index }; var rangeStart = totalLength + location.column; var rangeEnd = totalLength + lineLength - linebreakLength; var containingNode = sourceCode.getNodeByRangeIndex(rangeStart); if (containingNode && containingNode.type === "TemplateElement" && rangeStart > containingNode.parent.range[0] && rangeEnd < containingNode.parent.range[1]) { totalLength += lineLength; continue; } /* * If the line has only whitespace, and skipBlankLines * is true, don't report it */ if (skipBlankLines && skipMatch.test(lines[i])) { totalLength += lineLength; continue; } fixRange = [rangeStart, rangeEnd]; if (!ignoreComments || !commentLineNumbers.has(location.line)) { report(node, location, fixRange); } } totalLength += lineLength; } } }; } }; },{"../util/ast-utils":405}],307:[function(require,module,exports){ /** * @fileoverview Rule to flag when initializing to undefined * @author Ilya Volodin */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow initializing variables to `undefined`", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-undef-init" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { VariableDeclarator: function VariableDeclarator(node) { var name = sourceCode.getText(node.id), init = node.init && node.init.name, scope = context.getScope(), undefinedVar = astUtils.getVariableByName(scope, "undefined"), shadowed = undefinedVar && undefinedVar.defs.length > 0; if (init === "undefined" && node.parent.kind !== "const" && !shadowed) { context.report({ node: node, message: "It's not necessary to initialize '{{name}}' to undefined.", data: { name: name }, fix: function fix(fixer) { if (node.parent.kind === "var") { return null; } if (node.id.type === "ArrayPattern" || node.id.type === "ObjectPattern") { // Don't fix destructuring assignment to `undefined`. return null; } return fixer.removeRange([node.id.range[1], node.range[1]]); } }); } } }; } }; },{"../util/ast-utils":405}],308:[function(require,module,exports){ /** * @fileoverview Rule to flag references to undeclared variables. * @author Mark Macdonald */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks if the given node is the argument of a typeof operator. * @param {ASTNode} node The AST node being checked. * @returns {boolean} Whether or not the node is the argument of a typeof operator. */ function hasTypeOfOperator(node) { var parent = node.parent; return parent.type === "UnaryExpression" && parent.operator === "typeof"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow the use of undeclared variables unless mentioned in `/*global */` comments", category: "Variables", recommended: true, url: "https://eslint.org/docs/rules/no-undef" }, schema: [{ type: "object", properties: { typeof: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0]; var considerTypeOf = options && options.typeof === true || false; return { "Program:exit": function ProgramExit() /* node */{ var globalScope = context.getScope(); globalScope.through.forEach(function (ref) { var identifier = ref.identifier; if (!considerTypeOf && hasTypeOfOperator(identifier)) { return; } context.report({ node: identifier, message: "'{{name}}' is not defined.", data: identifier }); }); } }; } }; },{}],309:[function(require,module,exports){ /** * @fileoverview Rule to flag references to the undefined variable. * @author Michael Ficarra */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } module.exports = { meta: { type: "suggestion", docs: { description: "disallow the use of `undefined` as an identifier", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-undefined" }, schema: [] }, create: function create(context) { /** * Report an invalid "undefined" identifier node. * @param {ASTNode} node The node to report. * @returns {void} */ function report(node) { context.report({ node: node, message: "Unexpected use of undefined." }); } /** * Checks the given scope for references to `undefined` and reports * all references found. * @param {eslint-scope.Scope} scope The scope to check. * @returns {void} */ function checkScope(scope) { var undefinedVar = scope.set.get("undefined"); if (!undefinedVar) { return; } var references = undefinedVar.references; var defs = undefinedVar.defs; // Report non-initializing references (those are covered in defs below) references.filter(function (ref) { return !ref.init; }).forEach(function (ref) { return report(ref.identifier); }); defs.forEach(function (def) { return report(def.name); }); } return { "Program:exit": function ProgramExit() { var globalScope = context.getScope(); var stack = [globalScope]; while (stack.length) { var scope = stack.pop(); stack.push.apply(stack, _toConsumableArray(scope.childScopes)); checkScope(scope); } } }; } }; },{}],310:[function(require,module,exports){ /** * @fileoverview Rule to flag trailing underscores in variable declarations. * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow dangling underscores in identifiers", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-underscore-dangle" }, schema: [{ type: "object", properties: { allow: { type: "array", items: { type: "string" } }, allowAfterThis: { type: "boolean" }, allowAfterSuper: { type: "boolean" }, enforceInMethodNames: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] || {}; var ALLOWED_VARIABLES = options.allow ? options.allow : []; var allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; var allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; var enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false; //------------------------------------------------------------------------- // Helpers //------------------------------------------------------------------------- /** * Check if identifier is present inside the allowed option * @param {string} identifier name of the node * @returns {boolean} true if its is present * @private */ function isAllowed(identifier) { return ALLOWED_VARIABLES.some(function (ident) { return ident === identifier; }); } /** * Check if identifier has a underscore at the end * @param {ASTNode} identifier node to evaluate * @returns {boolean} true if its is present * @private */ function hasTrailingUnderscore(identifier) { var len = identifier.length; return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_"); } /** * Check if identifier is a special case member expression * @param {ASTNode} identifier node to evaluate * @returns {boolean} true if its is a special case * @private */ function isSpecialCaseIdentifierForMemberExpression(identifier) { return identifier === "__proto__"; } /** * Check if identifier is a special case variable expression * @param {ASTNode} identifier node to evaluate * @returns {boolean} true if its is a special case * @private */ function isSpecialCaseIdentifierInVariableExpression(identifier) { // Checks for the underscore library usage here return identifier === "_"; } /** * Check if function has a underscore at the end * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkForTrailingUnderscoreInFunctionDeclaration(node) { if (node.id) { var identifier = node.id.name; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) { context.report({ node: node, message: "Unexpected dangling '_' in '{{identifier}}'.", data: { identifier: identifier } }); } } } /** * Check if variable expression has a underscore at the end * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkForTrailingUnderscoreInVariableExpression(node) { var identifier = node.id.name; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) { context.report({ node: node, message: "Unexpected dangling '_' in '{{identifier}}'.", data: { identifier: identifier } }); } } /** * Check if member expression has a underscore at the end * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkForTrailingUnderscoreInMemberExpression(node) { var identifier = node.property.name, isMemberOfThis = node.object.type === "ThisExpression", isMemberOfSuper = node.object.type === "Super"; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !(isMemberOfThis && allowAfterThis) && !(isMemberOfSuper && allowAfterSuper) && !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) { context.report({ node: node, message: "Unexpected dangling '_' in '{{identifier}}'.", data: { identifier: identifier } }); } } /** * Check if method declaration or method property has a underscore at the end * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkForTrailingUnderscoreInMethod(node) { var identifier = node.key.name; var isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method; if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasTrailingUnderscore(identifier)) { context.report({ node: node, message: "Unexpected dangling '_' in '{{identifier}}'.", data: { identifier: identifier } }); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { FunctionDeclaration: checkForTrailingUnderscoreInFunctionDeclaration, VariableDeclarator: checkForTrailingUnderscoreInVariableExpression, MemberExpression: checkForTrailingUnderscoreInMemberExpression, MethodDefinition: checkForTrailingUnderscoreInMethod, Property: checkForTrailingUnderscoreInMethod }; } }; },{}],311:[function(require,module,exports){ /** * @fileoverview Rule to spot scenarios where a newline looks like it is ending a statement, but is not. * @author Glen Mailer */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow confusing multiline expressions", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-unexpected-multiline" }, schema: [] }, create: function create(context) { var FUNCTION_MESSAGE = "Unexpected newline between function and ( of function call."; var PROPERTY_MESSAGE = "Unexpected newline between object and [ of property access."; var TAGGED_TEMPLATE_MESSAGE = "Unexpected newline between template tag and template literal."; var DIVISION_MESSAGE = "Unexpected newline between numerator and division operator."; var REGEX_FLAG_MATCHER = /^[gimsuy]+$/; var sourceCode = context.getSourceCode(); /** * Check to see if there is a newline between the node and the following open bracket * line's expression * @param {ASTNode} node The node to check. * @param {string} msg The error message to use. * @returns {void} * @private */ function checkForBreakAfter(node, msg) { var openParen = sourceCode.getTokenAfter(node, astUtils.isNotClosingParenToken); var nodeExpressionEnd = sourceCode.getTokenBefore(openParen); if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) { context.report({ node: node, loc: openParen.loc.start, message: msg, data: { char: openParen.value } }); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { MemberExpression: function MemberExpression(node) { if (!node.computed) { return; } checkForBreakAfter(node.object, PROPERTY_MESSAGE); }, TaggedTemplateExpression: function TaggedTemplateExpression(node) { if (node.tag.loc.end.line === node.quasi.loc.start.line) { return; } context.report({ node: node, loc: node.loc.start, message: TAGGED_TEMPLATE_MESSAGE }); }, CallExpression: function CallExpression(node) { if (node.arguments.length === 0) { return; } checkForBreakAfter(node.callee, FUNCTION_MESSAGE); }, "BinaryExpression[operator='/'] > BinaryExpression[operator='/'].left": function BinaryExpressionOperatorBinaryExpressionOperatorLeft(node) { var secondSlash = sourceCode.getTokenAfter(node, function (token) { return token.value === "/"; }); var tokenAfterOperator = sourceCode.getTokenAfter(secondSlash); if (tokenAfterOperator.type === "Identifier" && REGEX_FLAG_MATCHER.test(tokenAfterOperator.value) && secondSlash.range[1] === tokenAfterOperator.range[0]) { checkForBreakAfter(node.left, DIVISION_MESSAGE); } } }; } }; },{"../util/ast-utils":405}],312:[function(require,module,exports){ /** * @fileoverview Rule to disallow use of unmodified expressions in loop conditions * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var Traverser = require("../util/traverser"), astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/; var LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/; // for-in/of statements don't have `test` property. var GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/; var SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/; var DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/; /** * @typedef {Object} LoopConditionInfo * @property {eslint-scope.Reference} reference - The reference. * @property {ASTNode} group - BinaryExpression or ConditionalExpression nodes * that the reference is belonging to. * @property {Function} isInLoop - The predicate which checks a given reference * is in this loop. * @property {boolean} modified - The flag that the reference is modified in * this loop. */ /** * Checks whether or not a given reference is a write reference. * * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is a write reference. */ function isWriteReference(reference) { if (reference.init) { var def = reference.resolved && reference.resolved.defs[0]; if (!def || def.type !== "Variable" || def.parent.kind !== "var") { return false; } } return reference.isWrite(); } /** * Checks whether or not a given loop condition info does not have the modified * flag. * * @param {LoopConditionInfo} condition - A loop condition info to check. * @returns {boolean} `true` if the loop condition info is "unmodified". */ function isUnmodified(condition) { return !condition.modified; } /** * Checks whether or not a given loop condition info does not have the modified * flag and does not have the group this condition belongs to. * * @param {LoopConditionInfo} condition - A loop condition info to check. * @returns {boolean} `true` if the loop condition info is "unmodified". */ function isUnmodifiedAndNotBelongToGroup(condition) { return !(condition.modified || condition.group); } /** * Checks whether or not a given reference is inside of a given node. * * @param {ASTNode} node - A node to check. * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is inside of the node. */ function isInRange(node, reference) { var or = node.range; var ir = reference.identifier.range; return or[0] <= ir[0] && ir[1] <= or[1]; } /** * Checks whether or not a given reference is inside of a loop node's condition. * * @param {ASTNode} node - A node to check. * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is inside of the loop node's * condition. */ var isInLoop = { WhileStatement: isInRange, DoWhileStatement: isInRange, ForStatement: function ForStatement(node, reference) { return isInRange(node, reference) && !(node.init && isInRange(node.init, reference)); } }; /** * Gets the function which encloses a given reference. * This supports only FunctionDeclaration. * * @param {eslint-scope.Reference} reference - A reference to get. * @returns {ASTNode|null} The function node or null. */ function getEncloseFunctionDeclaration(reference) { var node = reference.identifier; while (node) { if (node.type === "FunctionDeclaration") { return node.id ? node : null; } node = node.parent; } return null; } /** * Updates the "modified" flags of given loop conditions with given modifiers. * * @param {LoopConditionInfo[]} conditions - The loop conditions to be updated. * @param {eslint-scope.Reference[]} modifiers - The references to update. * @returns {void} */ function updateModifiedFlag(conditions, modifiers) { for (var i = 0; i < conditions.length; ++i) { var condition = conditions[i]; for (var j = 0; !condition.modified && j < modifiers.length; ++j) { var modifier = modifiers[j]; var funcNode = void 0, funcVar = void 0; /* * Besides checking for the condition being in the loop, we want to * check the function that this modifier is belonging to is called * in the loop. * FIXME: This should probably be extracted to a function. */ var inLoop = condition.isInLoop(modifier) || Boolean((funcNode = getEncloseFunctionDeclaration(modifier)) && (funcVar = astUtils.getVariableByName(modifier.from.upper, funcNode.id.name)) && funcVar.references.some(condition.isInLoop)); condition.modified = inLoop; } } } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow unmodified loop conditions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-unmodified-loop-condition" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); var groupMap = null; /** * Reports a given condition info. * * @param {LoopConditionInfo} condition - A loop condition info to report. * @returns {void} */ function report(condition) { var node = condition.reference.identifier; context.report({ node: node, message: "'{{name}}' is not modified in this loop.", data: node }); } /** * Registers given conditions to the group the condition belongs to. * * @param {LoopConditionInfo[]} conditions - A loop condition info to * register. * @returns {void} */ function registerConditionsToGroup(conditions) { for (var i = 0; i < conditions.length; ++i) { var condition = conditions[i]; if (condition.group) { var group = groupMap.get(condition.group); if (!group) { group = []; groupMap.set(condition.group, group); } group.push(condition); } } } /** * Reports references which are inside of unmodified groups. * * @param {LoopConditionInfo[]} conditions - A loop condition info to report. * @returns {void} */ function checkConditionsInGroup(conditions) { if (conditions.every(isUnmodified)) { conditions.forEach(report); } } /** * Checks whether or not a given group node has any dynamic elements. * * @param {ASTNode} root - A node to check. * This node is one of BinaryExpression or ConditionalExpression. * @returns {boolean} `true` if the node is dynamic. */ function hasDynamicExpressions(root) { var retv = false; Traverser.traverse(root, { visitorKeys: sourceCode.visitorKeys, enter: function enter(node) { if (DYNAMIC_PATTERN.test(node.type)) { retv = true; this.break(); } else if (SKIP_PATTERN.test(node.type)) { this.skip(); } } }); return retv; } /** * Creates the loop condition information from a given reference. * * @param {eslint-scope.Reference} reference - A reference to create. * @returns {LoopConditionInfo|null} Created loop condition info, or null. */ function toLoopCondition(reference) { if (reference.init) { return null; } var group = null; var child = reference.identifier; var node = child.parent; while (node) { if (SENTINEL_PATTERN.test(node.type)) { if (LOOP_PATTERN.test(node.type) && node.test === child) { // This reference is inside of a loop condition. return { reference: reference, group: group, isInLoop: isInLoop[node.type].bind(null, node), modified: false }; } // This reference is outside of a loop condition. break; } /* * If it's inside of a group, OK if either operand is modified. * So stores the group this reference belongs to. */ if (GROUP_PATTERN.test(node.type)) { // If this expression is dynamic, no need to check. if (hasDynamicExpressions(node)) { break; } else { group = node; } } child = node; node = node.parent; } return null; } /** * Finds unmodified references which are inside of a loop condition. * Then reports the references which are outside of groups. * * @param {eslint-scope.Variable} variable - A variable to report. * @returns {void} */ function checkReferences(variable) { // Gets references that exist in loop conditions. var conditions = variable.references.map(toLoopCondition).filter(Boolean); if (conditions.length === 0) { return; } // Registers the conditions to belonging groups. registerConditionsToGroup(conditions); // Check the conditions are modified. var modifiers = variable.references.filter(isWriteReference); if (modifiers.length > 0) { updateModifiedFlag(conditions, modifiers); } /* * Reports the conditions which are not belonging to groups. * Others will be reported after all variables are done. */ conditions.filter(isUnmodifiedAndNotBelongToGroup).forEach(report); } return { "Program:exit": function ProgramExit() { var queue = [context.getScope()]; groupMap = new Map(); var scope = void 0; while (scope = queue.pop()) { queue.push.apply(queue, _toConsumableArray(scope.childScopes)); scope.variables.forEach(checkReferences); } groupMap.forEach(checkConditionsInGroup); groupMap = null; } }; } }; },{"../util/ast-utils":405,"../util/traverser":418}],313:[function(require,module,exports){ /** * @fileoverview Rule to flag no-unneeded-ternary * @author Gyandeep Singh */ "use strict"; var astUtils = require("../util/ast-utils"); // Operators that always result in a boolean value var BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]); var OPERATOR_INVERSES = { "==": "!=", "!=": "==", "===": "!==", "!==": "===" // Operators like < and >= are not true inverses, since both will return false with NaN. }; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow ternary operators when simpler alternatives exist", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-unneeded-ternary" }, schema: [{ type: "object", properties: { defaultAssignment: { type: "boolean" } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { var options = context.options[0] || {}; var defaultAssignment = options.defaultAssignment !== false; var sourceCode = context.getSourceCode(); /** * Test if the node is a boolean literal * @param {ASTNode} node - The node to report. * @returns {boolean} True if the its a boolean literal * @private */ function isBooleanLiteral(node) { return node.type === "Literal" && typeof node.value === "boolean"; } /** * Creates an expression that represents the boolean inverse of the expression represented by the original node * @param {ASTNode} node A node representing an expression * @returns {string} A string representing an inverted expression */ function invertExpression(node) { if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) { var operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, function (token) { return token.value === node.operator; }); var text = sourceCode.getText(); return text.slice(node.range[0], operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]); } if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) { return "!(" + astUtils.getParenthesisedText(sourceCode, node) + ")"; } return "!" + astUtils.getParenthesisedText(sourceCode, node); } /** * Tests if a given node always evaluates to a boolean value * @param {ASTNode} node - An expression node * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value */ function isBooleanExpression(node) { return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) || node.type === "UnaryExpression" && node.operator === "!"; } /** * Test if the node matches the pattern id ? id : expression * @param {ASTNode} node - The ConditionalExpression to check. * @returns {boolean} True if the pattern is matched, and false otherwise * @private */ function matchesDefaultAssignment(node) { return node.test.type === "Identifier" && node.consequent.type === "Identifier" && node.test.name === node.consequent.name; } return { ConditionalExpression: function ConditionalExpression(node) { if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { context.report({ node: node, loc: node.consequent.loc.start, message: "Unnecessary use of boolean literals in conditional expression.", fix: function fix(fixer) { if (node.consequent.value === node.alternate.value) { // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true` return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null; } if (node.alternate.value) { // Replace `foo() ? false : true` with `!(foo())` return fixer.replaceText(node, invertExpression(node.test)); } // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise. return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : "!" + invertExpression(node.test)); } }); } else if (!defaultAssignment && matchesDefaultAssignment(node)) { context.report({ node: node, loc: node.consequent.loc.start, message: "Unnecessary use of conditional expression for default assignment.", fix: function fix(fixer) { var nodeAlternate = astUtils.getParenthesisedText(sourceCode, node.alternate); if (node.alternate.type === "ConditionalExpression" || node.alternate.type === "YieldExpression") { var isAlternateParenthesised = astUtils.isParenthesised(sourceCode, node.alternate); nodeAlternate = isAlternateParenthesised ? nodeAlternate : "(" + nodeAlternate + ")"; } return fixer.replaceText(node, astUtils.getParenthesisedText(sourceCode, node.test) + " || " + nodeAlternate); } }); } } }; } }; },{"../util/ast-utils":405}],314:[function(require,module,exports){ /** * @fileoverview Checks for unreachable code due to return, throws, break, and continue. * @author Joel Feenstra */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given variable declarator has the initializer. * @param {ASTNode} node - A VariableDeclarator node to check. * @returns {boolean} `true` if the node has the initializer. */ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function isInitialized(node) { return Boolean(node.init); } /** * Checks whether or not a given code path segment is unreachable. * @param {CodePathSegment} segment - A CodePathSegment to check. * @returns {boolean} `true` if the segment is unreachable. */ function isUnreachable(segment) { return !segment.reachable; } /** * The class to distinguish consecutive unreachable statements. */ var ConsecutiveRange = function () { function ConsecutiveRange(sourceCode) { _classCallCheck(this, ConsecutiveRange); this.sourceCode = sourceCode; this.startNode = null; this.endNode = null; } /** * The location object of this range. * @type {Object} */ _createClass(ConsecutiveRange, [{ key: "contains", /** * Checks whether the given node is inside of this range. * @param {ASTNode|Token} node - The node to check. * @returns {boolean} `true` if the node is inside of this range. */ value: function contains(node) { return node.range[0] >= this.startNode.range[0] && node.range[1] <= this.endNode.range[1]; } /** * Checks whether the given node is consecutive to this range. * @param {ASTNode} node - The node to check. * @returns {boolean} `true` if the node is consecutive to this range. */ }, { key: "isConsecutive", value: function isConsecutive(node) { return this.contains(this.sourceCode.getTokenBefore(node)); } /** * Merges the given node to this range. * @param {ASTNode} node - The node to merge. * @returns {void} */ }, { key: "merge", value: function merge(node) { this.endNode = node; } /** * Resets this range by the given node or null. * @param {ASTNode|null} node - The node to reset, or null. * @returns {void} */ }, { key: "reset", value: function reset(node) { this.startNode = this.endNode = node; } }, { key: "location", get: function get() { return { start: this.startNode.loc.start, end: this.endNode.loc.end }; } /** * `true` if this range is empty. * @type {boolean} */ }, { key: "isEmpty", get: function get() { return !(this.startNode && this.endNode); } }]); return ConsecutiveRange; }(); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow unreachable code after `return`, `throw`, `continue`, and `break` statements", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-unreachable" }, schema: [] }, create: function create(context) { var currentCodePath = null; var range = new ConsecutiveRange(context.getSourceCode()); /** * Reports a given node if it's unreachable. * @param {ASTNode} node - A statement node to report. * @returns {void} */ function reportIfUnreachable(node) { var nextNode = null; if (node && currentCodePath.currentSegments.every(isUnreachable)) { // Store this statement to distinguish consecutive statements. if (range.isEmpty) { range.reset(node); return; } // Skip if this statement is inside of the current range. if (range.contains(node)) { return; } // Merge if this statement is consecutive to the current range. if (range.isConsecutive(node)) { range.merge(node); return; } nextNode = node; } /* * Report the current range since this statement is reachable or is * not consecutive to the current range. */ if (!range.isEmpty) { context.report({ message: "Unreachable code.", loc: range.location, node: range.startNode }); } // Update the current range. range.reset(nextNode); } return { // Manages the current code path. onCodePathStart: function onCodePathStart(codePath) { currentCodePath = codePath; }, onCodePathEnd: function onCodePathEnd() { currentCodePath = currentCodePath.upper; }, // Registers for all statement nodes (excludes FunctionDeclaration). BlockStatement: reportIfUnreachable, BreakStatement: reportIfUnreachable, ClassDeclaration: reportIfUnreachable, ContinueStatement: reportIfUnreachable, DebuggerStatement: reportIfUnreachable, DoWhileStatement: reportIfUnreachable, ExpressionStatement: reportIfUnreachable, ForInStatement: reportIfUnreachable, ForOfStatement: reportIfUnreachable, ForStatement: reportIfUnreachable, IfStatement: reportIfUnreachable, ImportDeclaration: reportIfUnreachable, LabeledStatement: reportIfUnreachable, ReturnStatement: reportIfUnreachable, SwitchStatement: reportIfUnreachable, ThrowStatement: reportIfUnreachable, TryStatement: reportIfUnreachable, VariableDeclaration: function VariableDeclaration(node) { if (node.kind !== "var" || node.declarations.some(isInitialized)) { reportIfUnreachable(node); } }, WhileStatement: reportIfUnreachable, WithStatement: reportIfUnreachable, ExportNamedDeclaration: reportIfUnreachable, ExportDefaultDeclaration: reportIfUnreachable, ExportAllDeclaration: reportIfUnreachable, "Program:exit": function ProgramExit() { reportIfUnreachable(); } }; } }; },{}],315:[function(require,module,exports){ /** * @fileoverview Rule to flag unsafe statements in finally block * @author Onur Temizkan */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/; var SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/; var SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow control flow statements in `finally` blocks", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-unsafe-finally" }, schema: [] }, create: function create(context) { /** * Checks if the node is the finalizer of a TryStatement * * @param {ASTNode} node - node to check. * @returns {boolean} - true if the node is the finalizer of a TryStatement */ function isFinallyBlock(node) { return node.parent.type === "TryStatement" && node.parent.finalizer === node; } /** * Climbs up the tree if the node is not a sentinel node * * @param {ASTNode} node - node to check. * @param {string} label - label of the break or continue statement * @returns {boolean} - return whether the node is a finally block or a sentinel node */ function isInFinallyBlock(node, label) { var labelInside = false; var sentinelNodeType = void 0; if (node.type === "BreakStatement" && !node.label) { sentinelNodeType = SENTINEL_NODE_TYPE_BREAK; } else if (node.type === "ContinueStatement") { sentinelNodeType = SENTINEL_NODE_TYPE_CONTINUE; } else { sentinelNodeType = SENTINEL_NODE_TYPE_RETURN_THROW; } for (var currentNode = node; currentNode && !sentinelNodeType.test(currentNode.type); currentNode = currentNode.parent) { if (currentNode.parent.label && label && currentNode.parent.label.name === label.name) { labelInside = true; } if (isFinallyBlock(currentNode)) { if (label && labelInside) { return false; } return true; } } return false; } /** * Checks whether the possibly-unsafe statement is inside a finally block. * * @param {ASTNode} node - node to check. * @returns {void} */ function check(node) { if (isInFinallyBlock(node, node.label)) { context.report({ message: "Unsafe usage of {{nodeType}}.", data: { nodeType: node.type }, node: node, line: node.loc.line, column: node.loc.column }); } } return { ReturnStatement: check, ThrowStatement: check, BreakStatement: check, ContinueStatement: check }; } }; },{}],316:[function(require,module,exports){ /** * @fileoverview Rule to disallow negating the left operand of relational operators * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether the given operator is a relational operator or not. * * @param {string} op - The operator type to check. * @returns {boolean} `true` if the operator is a relational operator. */ function isRelationalOperator(op) { return op === "in" || op === "instanceof"; } /** * Checks whether the given node is a logical negation expression or not. * * @param {ASTNode} node - The node to check. * @returns {boolean} `true` if the node is a logical negation expression. */ function isNegation(node) { return node.type === "UnaryExpression" && node.operator === "!"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow negating the left operand of relational operators", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-unsafe-negation" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { BinaryExpression: function BinaryExpression(node) { if (isRelationalOperator(node.operator) && isNegation(node.left) && !astUtils.isParenthesised(sourceCode, node.left)) { context.report({ node: node, loc: node.left.loc, message: "Unexpected negating the left operand of '{{operator}}' operator.", data: node, fix: function fix(fixer) { var negationToken = sourceCode.getFirstToken(node.left); var fixRange = [negationToken.range[1], node.range[1]]; var text = sourceCode.text.slice(fixRange[0], fixRange[1]); return fixer.replaceTextRange(fixRange, "(" + text + ")"); } }); } } }; } }; },{"../util/ast-utils":405}],317:[function(require,module,exports){ /** * @fileoverview Flag expressions in statement position that do not side effect * @author Michael Ficarra */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unused expressions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-unused-expressions" }, schema: [{ type: "object", properties: { allowShortCircuit: { type: "boolean" }, allowTernary: { type: "boolean" }, allowTaggedTemplates: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var config = context.options[0] || {}, allowShortCircuit = config.allowShortCircuit || false, allowTernary = config.allowTernary || false, allowTaggedTemplates = config.allowTaggedTemplates || false; /** * @param {ASTNode} node - any node * @returns {boolean} whether the given node structurally represents a directive */ function looksLikeDirective(node) { return node.type === "ExpressionStatement" && node.expression.type === "Literal" && typeof node.expression.value === "string"; } /** * @param {Function} predicate - ([a] -> Boolean) the function used to make the determination * @param {a[]} list - the input list * @returns {a[]} the leading sequence of members in the given list that pass the given predicate */ function takeWhile(predicate, list) { for (var i = 0; i < list.length; ++i) { if (!predicate(list[i])) { return list.slice(0, i); } } return list.slice(); } /** * @param {ASTNode} node - a Program or BlockStatement node * @returns {ASTNode[]} the leading sequence of directive nodes in the given node's body */ function directives(node) { return takeWhile(looksLikeDirective, node.body); } /** * @param {ASTNode} node - any node * @param {ASTNode[]} ancestors - the given node's ancestors * @returns {boolean} whether the given node is considered a directive in its current position */ function isDirective(node, ancestors) { var parent = ancestors[ancestors.length - 1], grandparent = ancestors[ancestors.length - 2]; return (parent.type === "Program" || parent.type === "BlockStatement" && /Function/.test(grandparent.type)) && directives(parent).indexOf(node) >= 0; } /** * Determines whether or not a given node is a valid expression. Recurses on short circuit eval and ternary nodes if enabled by flags. * @param {ASTNode} node - any node * @returns {boolean} whether the given node is a valid expression */ function isValidExpression(node) { if (allowTernary) { // Recursive check for ternary and logical expressions if (node.type === "ConditionalExpression") { return isValidExpression(node.consequent) && isValidExpression(node.alternate); } } if (allowShortCircuit) { if (node.type === "LogicalExpression") { return isValidExpression(node.right); } } if (allowTaggedTemplates && node.type === "TaggedTemplateExpression") { return true; } return (/^(?:Assignment|Call|New|Update|Yield|Await)Expression$/.test(node.type) || node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0 ); } return { ExpressionStatement: function ExpressionStatement(node) { if (!isValidExpression(node.expression) && !isDirective(node, context.getAncestors())) { context.report({ node: node, message: "Expected an assignment or function call and instead saw an expression." }); } } }; } }; },{}],318:[function(require,module,exports){ /** * @fileoverview Rule to disallow unused labels. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unused labels", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-unused-labels" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); var scopeInfo = null; /** * Adds a scope info to the stack. * * @param {ASTNode} node - A node to add. This is a LabeledStatement. * @returns {void} */ function enterLabeledScope(node) { scopeInfo = { label: node.label.name, used: false, upper: scopeInfo }; } /** * Removes the top of the stack. * At the same time, this reports the label if it's never used. * * @param {ASTNode} node - A node to report. This is a LabeledStatement. * @returns {void} */ function exitLabeledScope(node) { if (!scopeInfo.used) { context.report({ node: node.label, message: "'{{name}}:' is defined but never used.", data: node.label, fix: function fix(fixer) { /* * Only perform a fix if there are no comments between the label and the body. This will be the case * when there is exactly one token/comment (the ":") between the label and the body. */ if (sourceCode.getTokenAfter(node.label, { includeComments: true }) === sourceCode.getTokenBefore(node.body, { includeComments: true })) { return fixer.removeRange([node.range[0], node.body.range[0]]); } return null; } }); } scopeInfo = scopeInfo.upper; } /** * Marks the label of a given node as used. * * @param {ASTNode} node - A node to mark. This is a BreakStatement or * ContinueStatement. * @returns {void} */ function markAsUsed(node) { if (!node.label) { return; } var label = node.label.name; var info = scopeInfo; while (info) { if (info.label === label) { info.used = true; break; } info = info.upper; } } return { LabeledStatement: enterLabeledScope, "LabeledStatement:exit": exitLabeledScope, BreakStatement: markAsUsed, ContinueStatement: markAsUsed }; } }; },{}],319:[function(require,module,exports){ /** * @fileoverview Rule to flag declared but unused variables * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow unused variables", category: "Variables", recommended: true, url: "https://eslint.org/docs/rules/no-unused-vars" }, schema: [{ oneOf: [{ enum: ["all", "local"] }, { type: "object", properties: { vars: { enum: ["all", "local"] }, varsIgnorePattern: { type: "string" }, args: { enum: ["all", "after-used", "none"] }, ignoreRestSiblings: { type: "boolean" }, argsIgnorePattern: { type: "string" }, caughtErrors: { enum: ["all", "none"] }, caughtErrorsIgnorePattern: { type: "string" } } }] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/; var config = { vars: "all", args: "after-used", ignoreRestSiblings: false, caughtErrors: "none" }; var firstOption = context.options[0]; if (firstOption) { if (typeof firstOption === "string") { config.vars = firstOption; } else { config.vars = firstOption.vars || config.vars; config.args = firstOption.args || config.args; config.ignoreRestSiblings = firstOption.ignoreRestSiblings || config.ignoreRestSiblings; config.caughtErrors = firstOption.caughtErrors || config.caughtErrors; if (firstOption.varsIgnorePattern) { config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern); } if (firstOption.argsIgnorePattern) { config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern); } if (firstOption.caughtErrorsIgnorePattern) { config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern); } } } /** * Generate the warning message about the variable being * defined and unused, including the ignore pattern if configured. * @param {Variable} unusedVar - eslint-scope variable object. * @returns {string} The warning message to be used with this unused variable. */ function getDefinedMessage(unusedVar) { var defType = unusedVar.defs && unusedVar.defs[0] && unusedVar.defs[0].type; var type = void 0; var pattern = void 0; if (defType === "CatchClause" && config.caughtErrorsIgnorePattern) { type = "args"; pattern = config.caughtErrorsIgnorePattern.toString(); } else if (defType === "Parameter" && config.argsIgnorePattern) { type = "args"; pattern = config.argsIgnorePattern.toString(); } else if (defType !== "Parameter" && config.varsIgnorePattern) { type = "vars"; pattern = config.varsIgnorePattern.toString(); } var additional = type ? " Allowed unused " + type + " must match " + pattern + "." : ""; return "'{{name}}' is defined but never used." + additional; } /** * Generate the warning message about the variable being * assigned and unused, including the ignore pattern if configured. * @returns {string} The warning message to be used with this unused variable. */ function getAssignedMessage() { var additional = config.varsIgnorePattern ? " Allowed unused vars must match " + config.varsIgnorePattern.toString() + "." : ""; return "'{{name}}' is assigned a value but never used." + additional; } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var STATEMENT_TYPE = /(?:Statement|Declaration)$/; /** * Determines if a given variable is being exported from a module. * @param {Variable} variable - eslint-scope variable object. * @returns {boolean} True if the variable is exported, false if not. * @private */ function isExported(variable) { var definition = variable.defs[0]; if (definition) { var node = definition.node; if (node.type === "VariableDeclarator") { node = node.parent; } else if (definition.type === "Parameter") { return false; } return node.parent.type.indexOf("Export") === 0; } return false; } /** * Determines if a variable has a sibling rest property * @param {Variable} variable - eslint-scope variable object. * @returns {boolean} True if the variable is exported, false if not. * @private */ function hasRestSpreadSibling(variable) { if (config.ignoreRestSiblings) { return variable.defs.some(function (def) { var propertyNode = def.name.parent; var patternNode = propertyNode.parent; return propertyNode.type === "Property" && patternNode.type === "ObjectPattern" && REST_PROPERTY_TYPE.test(patternNode.properties[patternNode.properties.length - 1].type); }); } return false; } /** * Determines if a reference is a read operation. * @param {Reference} ref - An eslint-scope Reference * @returns {boolean} whether the given reference represents a read operation * @private */ function isReadRef(ref) { return ref.isRead(); } /** * Determine if an identifier is referencing an enclosing function name. * @param {Reference} ref - The reference to check. * @param {ASTNode[]} nodes - The candidate function nodes. * @returns {boolean} True if it's a self-reference, false if not. * @private */ function isSelfReference(ref, nodes) { var scope = ref.from; while (scope) { if (nodes.indexOf(scope.block) >= 0) { return true; } scope = scope.upper; } return false; } /** * Gets a list of function definitions for a specified variable. * @param {Variable} variable - eslint-scope variable object. * @returns {ASTNode[]} Function nodes. * @private */ function getFunctionDefinitions(variable) { var functionDefinitions = []; variable.defs.forEach(function (def) { var type = def.type, node = def.node; // FunctionDeclarations if (type === "FunctionName") { functionDefinitions.push(node); } // FunctionExpressions if (type === "Variable" && node.init && (node.init.type === "FunctionExpression" || node.init.type === "ArrowFunctionExpression")) { functionDefinitions.push(node.init); } }); return functionDefinitions; } /** * Checks the position of given nodes. * * @param {ASTNode} inner - A node which is expected as inside. * @param {ASTNode} outer - A node which is expected as outside. * @returns {boolean} `true` if the `inner` node exists in the `outer` node. * @private */ function isInside(inner, outer) { return inner.range[0] >= outer.range[0] && inner.range[1] <= outer.range[1]; } /** * If a given reference is left-hand side of an assignment, this gets * the right-hand side node of the assignment. * * In the following cases, this returns null. * * - The reference is not the LHS of an assignment expression. * - The reference is inside of a loop. * - The reference is inside of a function scope which is different from * the declaration. * * @param {eslint-scope.Reference} ref - A reference to check. * @param {ASTNode} prevRhsNode - The previous RHS node. * @returns {ASTNode|null} The RHS node or null. * @private */ function getRhsNode(ref, prevRhsNode) { var id = ref.identifier; var parent = id.parent; var granpa = parent.parent; var refScope = ref.from.variableScope; var varScope = ref.resolved.scope.variableScope; var canBeUsedLater = refScope !== varScope || astUtils.isInLoop(id); /* * Inherits the previous node if this reference is in the node. * This is for `a = a + a`-like code. */ if (prevRhsNode && isInside(id, prevRhsNode)) { return prevRhsNode; } if (parent.type === "AssignmentExpression" && granpa.type === "ExpressionStatement" && id === parent.left && !canBeUsedLater) { return parent.right; } return null; } /** * Checks whether a given function node is stored to somewhere or not. * If the function node is stored, the function can be used later. * * @param {ASTNode} funcNode - A function node to check. * @param {ASTNode} rhsNode - The RHS node of the previous assignment. * @returns {boolean} `true` if under the following conditions: * - the funcNode is assigned to a variable. * - the funcNode is bound as an argument of a function call. * - the function is bound to a property and the object satisfies above conditions. * @private */ function isStorableFunction(funcNode, rhsNode) { var node = funcNode; var parent = funcNode.parent; while (parent && isInside(parent, rhsNode)) { switch (parent.type) { case "SequenceExpression": if (parent.expressions[parent.expressions.length - 1] !== node) { return false; } break; case "CallExpression": case "NewExpression": return parent.callee !== node; case "AssignmentExpression": case "TaggedTemplateExpression": case "YieldExpression": return true; default: if (STATEMENT_TYPE.test(parent.type)) { /* * If it encountered statements, this is a complex pattern. * Since analyzeing complex patterns is hard, this returns `true` to avoid false positive. */ return true; } } node = parent; parent = parent.parent; } return false; } /** * Checks whether a given Identifier node exists inside of a function node which can be used later. * * "can be used later" means: * - the function is assigned to a variable. * - the function is bound to a property and the object can be used later. * - the function is bound as an argument of a function call. * * If a reference exists in a function which can be used later, the reference is read when the function is called. * * @param {ASTNode} id - An Identifier node to check. * @param {ASTNode} rhsNode - The RHS node of the previous assignment. * @returns {boolean} `true` if the `id` node exists inside of a function node which can be used later. * @private */ function isInsideOfStorableFunction(id, rhsNode) { var funcNode = astUtils.getUpperFunction(id); return funcNode && isInside(funcNode, rhsNode) && isStorableFunction(funcNode, rhsNode); } /** * Checks whether a given reference is a read to update itself or not. * * @param {eslint-scope.Reference} ref - A reference to check. * @param {ASTNode} rhsNode - The RHS node of the previous assignment. * @returns {boolean} The reference is a read to update itself. * @private */ function isReadForItself(ref, rhsNode) { var id = ref.identifier; var parent = id.parent; var granpa = parent.parent; return ref.isRead() && ( // self update. e.g. `a += 1`, `a++` // in RHS of an assignment for itself. e.g. `a = a + 1` parent.type === "AssignmentExpression" && granpa.type === "ExpressionStatement" && parent.left === id || parent.type === "UpdateExpression" && granpa.type === "ExpressionStatement" || rhsNode && isInside(id, rhsNode) && !isInsideOfStorableFunction(id, rhsNode)); } /** * Determine if an identifier is used either in for-in loops. * * @param {Reference} ref - The reference to check. * @returns {boolean} whether reference is used in the for-in loops * @private */ function isForInRef(ref) { var target = ref.identifier.parent; // "for (var ...) { return; }" if (target.type === "VariableDeclarator") { target = target.parent.parent; } if (target.type !== "ForInStatement") { return false; } // "for (...) { return; }" if (target.body.type === "BlockStatement") { target = target.body.body[0]; // "for (...) return;" } else { target = target.body; } // For empty loop body if (!target) { return false; } return target.type === "ReturnStatement"; } /** * Determines if the variable is used. * @param {Variable} variable - The variable to check. * @returns {boolean} True if the variable is used * @private */ function isUsedVariable(variable) { var functionNodes = getFunctionDefinitions(variable), isFunctionDefinition = functionNodes.length > 0; var rhsNode = null; return variable.references.some(function (ref) { if (isForInRef(ref)) { return true; } var forItself = isReadForItself(ref, rhsNode); rhsNode = getRhsNode(ref, rhsNode); return isReadRef(ref) && !forItself && !(isFunctionDefinition && isSelfReference(ref, functionNodes)); }); } /** * Checks whether the given variable is after the last used parameter. * * @param {eslint-scope.Variable} variable - The variable to check. * @returns {boolean} `true` if the variable is defined after the last * used parameter. */ function isAfterLastUsedArg(variable) { var def = variable.defs[0]; var params = context.getDeclaredVariables(def.node); var posteriorParams = params.slice(params.indexOf(variable) + 1); // If any used parameters occur after this parameter, do not report. return !posteriorParams.some(function (v) { return v.references.length > 0 || v.eslintUsed; }); } /** * Gets an array of variables without read references. * @param {Scope} scope - an eslint-scope Scope object. * @param {Variable[]} unusedVars - an array that saving result. * @returns {Variable[]} unused variables of the scope and descendant scopes. * @private */ function collectUnusedVariables(scope, unusedVars) { var variables = scope.variables; var childScopes = scope.childScopes; var i = void 0, l = void 0; if (scope.type !== "TDZ" && (scope.type !== "global" || config.vars === "all")) { for (i = 0, l = variables.length; i < l; ++i) { var variable = variables[i]; // skip a variable of class itself name in the class scope if (scope.type === "class" && scope.block.id === variable.identifiers[0]) { continue; } // skip function expression names and variables marked with markVariableAsUsed() if (scope.functionExpressionScope || variable.eslintUsed) { continue; } // skip implicit "arguments" variable if (scope.type === "function" && variable.name === "arguments" && variable.identifiers.length === 0) { continue; } // explicit global variables don't have definitions. var def = variable.defs[0]; if (def) { var type = def.type; // skip catch variables if (type === "CatchClause") { if (config.caughtErrors === "none") { continue; } // skip ignored parameters if (config.caughtErrorsIgnorePattern && config.caughtErrorsIgnorePattern.test(def.name.name)) { continue; } } if (type === "Parameter") { // skip any setter argument if ((def.node.parent.type === "Property" || def.node.parent.type === "MethodDefinition") && def.node.parent.kind === "set") { continue; } // if "args" option is "none", skip any parameter if (config.args === "none") { continue; } // skip ignored parameters if (config.argsIgnorePattern && config.argsIgnorePattern.test(def.name.name)) { continue; } // if "args" option is "after-used", skip used variables if (config.args === "after-used" && astUtils.isFunction(def.name.parent) && !isAfterLastUsedArg(variable)) { continue; } } else { // skip ignored variables if (config.varsIgnorePattern && config.varsIgnorePattern.test(def.name.name)) { continue; } } } if (!isUsedVariable(variable) && !isExported(variable) && !hasRestSpreadSibling(variable)) { unusedVars.push(variable); } } } for (i = 0, l = childScopes.length; i < l; ++i) { collectUnusedVariables(childScopes[i], unusedVars); } return unusedVars; } /** * Gets the index of a given variable name in a given comment. * @param {eslint-scope.Variable} variable - A variable to get. * @param {ASTNode} comment - A comment node which includes the variable name. * @returns {number} The index of the variable name's location. * @private */ function getColumnInComment(variable, comment) { var namePattern = new RegExp("[\\s,]" + lodash.escapeRegExp(variable.name) + "(?:$|[\\s,:])", "g"); // To ignore the first text "global". namePattern.lastIndex = comment.value.indexOf("global") + 6; // Search a given variable name. var match = namePattern.exec(comment.value); return match ? match.index + 1 : 0; } /** * Creates the correct location of a given variables. * The location is at its name string in a `/*global` comment. * * @param {eslint-scope.Variable} variable - A variable to get its location. * @returns {{line: number, column: number}} The location object for the variable. * @private */ function getLocation(variable) { var comment = variable.eslintExplicitGlobalComment; return sourceCode.getLocFromIndex(comment.range[0] + 2 + getColumnInComment(variable, comment)); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { "Program:exit": function ProgramExit(programNode) { var unusedVars = collectUnusedVariables(context.getScope(), []); for (var i = 0, l = unusedVars.length; i < l; ++i) { var unusedVar = unusedVars[i]; if (unusedVar.eslintExplicitGlobal) { context.report({ node: programNode, loc: getLocation(unusedVar), message: getDefinedMessage(unusedVar), data: unusedVar }); } else if (unusedVar.defs.length > 0) { context.report({ node: unusedVar.identifiers[0], message: unusedVar.references.some(function (ref) { return ref.isWrite(); }) ? getAssignedMessage() : getDefinedMessage(unusedVar), data: unusedVar }); } } } }; } }; },{"../util/ast-utils":405,"lodash":92}],320:[function(require,module,exports){ /** * @fileoverview Rule to flag use of variables before they are defined * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; var FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/; /** * Parses a given value as options. * * @param {any} options - A value to parse. * @returns {Object} The parsed options. */ function parseOptions(options) { var functions = true; var classes = true; var variables = true; if (typeof options === "string") { functions = options !== "nofunc"; } else if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object" && options !== null) { functions = options.functions !== false; classes = options.classes !== false; variables = options.variables !== false; } return { functions: functions, classes: classes, variables: variables }; } /** * Checks whether or not a given variable is a function declaration. * * @param {eslint-scope.Variable} variable - A variable to check. * @returns {boolean} `true` if the variable is a function declaration. */ function isFunction(variable) { return variable.defs[0].type === "FunctionName"; } /** * Checks whether or not a given variable is a class declaration in an upper function scope. * * @param {eslint-scope.Variable} variable - A variable to check. * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the variable is a class declaration. */ function isOuterClass(variable, reference) { return variable.defs[0].type === "ClassName" && variable.scope.variableScope !== reference.from.variableScope; } /** * Checks whether or not a given variable is a variable declaration in an upper function scope. * @param {eslint-scope.Variable} variable - A variable to check. * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the variable is a variable declaration. */ function isOuterVariable(variable, reference) { return variable.defs[0].type === "Variable" && variable.scope.variableScope !== reference.from.variableScope; } /** * Checks whether or not a given location is inside of the range of a given node. * * @param {ASTNode} node - An node to check. * @param {number} location - A location to check. * @returns {boolean} `true` if the location is inside of the range of the node. */ function isInRange(node, location) { return node && node.range[0] <= location && location <= node.range[1]; } /** * Checks whether or not a given reference is inside of the initializers of a given variable. * * This returns `true` in the following cases: * * var a = a * var [a = a] = list * var {a = a} = obj * for (var a in a) {} * for (var a of a) {} * * @param {Variable} variable - A variable to check. * @param {Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is inside of the initializers. */ function isInInitializer(variable, reference) { if (variable.scope !== reference.from) { return false; } var node = variable.identifiers[0].parent; var location = reference.identifier.range[1]; while (node) { if (node.type === "VariableDeclarator") { if (isInRange(node.init, location)) { return true; } if (FOR_IN_OF_TYPE.test(node.parent.parent.type) && isInRange(node.parent.parent.right, location)) { return true; } break; } else if (node.type === "AssignmentPattern") { if (isInRange(node.right, location)) { return true; } } else if (SENTINEL_TYPE.test(node.type)) { break; } node = node.parent; } return false; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow the use of variables before they are defined", category: "Variables", recommended: false, url: "https://eslint.org/docs/rules/no-use-before-define" }, schema: [{ oneOf: [{ enum: ["nofunc"] }, { type: "object", properties: { functions: { type: "boolean" }, classes: { type: "boolean" }, variables: { type: "boolean" } }, additionalProperties: false }] }] }, create: function create(context) { var options = parseOptions(context.options[0]); /** * Determines whether a given use-before-define case should be reported according to the options. * @param {eslint-scope.Variable} variable The variable that gets used before being defined * @param {eslint-scope.Reference} reference The reference to the variable * @returns {boolean} `true` if the usage should be reported */ function isForbidden(variable, reference) { if (isFunction(variable)) { return options.functions; } if (isOuterClass(variable, reference)) { return options.classes; } if (isOuterVariable(variable, reference)) { return options.variables; } return true; } /** * Finds and validates all variables in a given scope. * @param {Scope} scope The scope object. * @returns {void} * @private */ function findVariablesInScope(scope) { scope.references.forEach(function (reference) { var variable = reference.resolved; /* * Skips when the reference is: * - initialization's. * - referring to an undefined variable. * - referring to a global environment variable (there're no identifiers). * - located preceded by the variable (except in initializers). * - allowed by options. */ if (reference.init || !variable || variable.identifiers.length === 0 || variable.identifiers[0].range[1] < reference.identifier.range[1] && !isInInitializer(variable, reference) || !isForbidden(variable, reference)) { return; } // Reports. context.report({ node: reference.identifier, message: "'{{name}}' was used before it was defined.", data: reference.identifier }); }); scope.childScopes.forEach(findVariablesInScope); } return { Program: function Program() { findVariablesInScope(context.getScope()); } }; } }; },{}],321:[function(require,module,exports){ /** * @fileoverview A rule to disallow unnecessary `.call()` and `.apply()`. * @author Toru Nagashima */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a node is a `.call()`/`.apply()`. * @param {ASTNode} node - A CallExpression node to check. * @returns {boolean} Whether or not the node is a `.call()`/`.apply()`. */ function isCallOrNonVariadicApply(node) { return node.callee.type === "MemberExpression" && node.callee.property.type === "Identifier" && node.callee.computed === false && (node.callee.property.name === "call" && node.arguments.length >= 1 || node.callee.property.name === "apply" && node.arguments.length === 2 && node.arguments[1].type === "ArrayExpression"); } /** * Checks whether or not `thisArg` is not changed by `.call()`/`.apply()`. * @param {ASTNode|null} expectedThis - The node that is the owner of the applied function. * @param {ASTNode} thisArg - The node that is given to the first argument of the `.call()`/`.apply()`. * @param {SourceCode} sourceCode - The ESLint source code object. * @returns {boolean} Whether or not `thisArg` is not changed by `.call()`/`.apply()`. */ function isValidThisArg(expectedThis, thisArg, sourceCode) { if (!expectedThis) { return astUtils.isNullOrUndefined(thisArg); } return astUtils.equalTokens(expectedThis, thisArg, sourceCode); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary calls to `.call()` and `.apply()`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-useless-call" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); return { CallExpression: function CallExpression(node) { if (!isCallOrNonVariadicApply(node)) { return; } var applied = node.callee.object; var expectedThis = applied.type === "MemberExpression" ? applied.object : null; var thisArg = node.arguments[0]; if (isValidThisArg(expectedThis, thisArg, sourceCode)) { context.report({ node: node, message: "unnecessary '.{{name}}()'.", data: { name: node.callee.property.name } }); } } }; } }; },{"../util/ast-utils":405}],322:[function(require,module,exports){ /** * @fileoverview Reports useless `catch` clauses that just rethrow their error. * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary `catch` clauses", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-useless-catch" }, schema: [] }, create: function create(context) { return { CatchClause: function CatchClause(node) { if (node.param && node.param.type === "Identifier" && node.body.body.length && node.body.body[0].type === "ThrowStatement" && node.body.body[0].argument.type === "Identifier" && node.body.body[0].argument.name === node.param.name) { if (node.parent.finalizer) { context.report({ node: node, message: "Unnecessary catch clause." }); } else { context.report({ node: node.parent, message: "Unnecessary try/catch wrapper." }); } } } }; } }; },{}],323:[function(require,module,exports){ /** * @fileoverview Rule to disallow unnecessary computed property keys in object literals * @author Burak Yigit Kaya */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var MESSAGE_UNNECESSARY_COMPUTED = "Unnecessarily computed property [{{property}}] found."; module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary computed property keys in object literals", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-useless-computed-key" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { Property: function Property(node) { if (!node.computed) { return; } var key = node.key, nodeType = _typeof(key.value); if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== "__proto__") { context.report({ node: node, message: MESSAGE_UNNECESSARY_COMPUTED, data: { property: sourceCode.getText(key) }, fix: function fix(fixer) { var leftSquareBracket = sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken); var rightSquareBracket = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken); var tokensBetween = sourceCode.getTokensBetween(leftSquareBracket, rightSquareBracket, 1); if (tokensBetween.slice(0, -1).some(function (token, index) { return sourceCode.getText().slice(token.range[1], tokensBetween[index + 1].range[0]).trim(); })) { // If there are comments between the brackets and the property name, don't do a fix. return null; } var tokenBeforeLeftBracket = sourceCode.getTokenBefore(leftSquareBracket); // Insert a space before the key to avoid changing identifiers, e.g. ({ get[2]() {} }) to ({ get2() {} }) var needsSpaceBeforeKey = tokenBeforeLeftBracket.range[1] === leftSquareBracket.range[0] && !astUtils.canTokensBeAdjacent(tokenBeforeLeftBracket, sourceCode.getFirstToken(key)); var replacementKey = (needsSpaceBeforeKey ? " " : "") + key.raw; return fixer.replaceTextRange([leftSquareBracket.range[0], rightSquareBracket.range[1]], replacementKey); } }); } } }; } }; },{"../util/ast-utils":405}],324:[function(require,module,exports){ /** * @fileoverview disallow unncessary concatenation of template strings * @author Henry Zhu */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is a concatenation. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a concatenation. */ function isConcatenation(node) { return node.type === "BinaryExpression" && node.operator === "+"; } /** * Checks if the given token is a `+` token or not. * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a `+` token. */ function isConcatOperatorToken(token) { return token.value === "+" && token.type === "Punctuator"; } /** * Get's the right most node on the left side of a BinaryExpression with + operator. * @param {ASTNode} node - A BinaryExpression node to check. * @returns {ASTNode} node */ function getLeft(node) { var left = node.left; while (isConcatenation(left)) { left = left.right; } return left; } /** * Get's the left most node on the right side of a BinaryExpression with + operator. * @param {ASTNode} node - A BinaryExpression node to check. * @returns {ASTNode} node */ function getRight(node) { var right = node.right; while (isConcatenation(right)) { right = right.left; } return right; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary concatenation of literals or template literals", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-useless-concat" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); return { BinaryExpression: function BinaryExpression(node) { // check if not concatenation if (node.operator !== "+") { return; } // account for the `foo + "a" + "b"` case var left = getLeft(node); var right = getRight(node); if (astUtils.isStringLiteral(left) && astUtils.isStringLiteral(right) && astUtils.isTokenOnSameLine(left, right)) { var operatorToken = sourceCode.getFirstTokenBetween(left, right, isConcatOperatorToken); context.report({ node: node, loc: operatorToken.loc.start, message: "Unexpected string concatenation of literals." }); } } }; } }; },{"../util/ast-utils":405}],325:[function(require,module,exports){ /** * @fileoverview Rule to flag the use of redundant constructors in classes. * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether a given array of statements is a single call of `super`. * * @param {ASTNode[]} body - An array of statements to check. * @returns {boolean} `true` if the body is a single call of `super`. */ function isSingleSuperCall(body) { return body.length === 1 && body[0].type === "ExpressionStatement" && body[0].expression.type === "CallExpression" && body[0].expression.callee.type === "Super"; } /** * Checks whether a given node is a pattern which doesn't have any side effects. * Default parameters and Destructuring parameters can have side effects. * * @param {ASTNode} node - A pattern node. * @returns {boolean} `true` if the node doesn't have any side effects. */ function isSimple(node) { return node.type === "Identifier" || node.type === "RestElement"; } /** * Checks whether a given array of expressions is `...arguments` or not. * `super(...arguments)` passes all arguments through. * * @param {ASTNode[]} superArgs - An array of expressions to check. * @returns {boolean} `true` if the superArgs is `...arguments`. */ function isSpreadArguments(superArgs) { return superArgs.length === 1 && superArgs[0].type === "SpreadElement" && superArgs[0].argument.type === "Identifier" && superArgs[0].argument.name === "arguments"; } /** * Checks whether given 2 nodes are identifiers which have the same name or not. * * @param {ASTNode} ctorParam - A node to check. * @param {ASTNode} superArg - A node to check. * @returns {boolean} `true` if the nodes are identifiers which have the same * name. */ function isValidIdentifierPair(ctorParam, superArg) { return ctorParam.type === "Identifier" && superArg.type === "Identifier" && ctorParam.name === superArg.name; } /** * Checks whether given 2 nodes are a rest/spread pair which has the same values. * * @param {ASTNode} ctorParam - A node to check. * @param {ASTNode} superArg - A node to check. * @returns {boolean} `true` if the nodes are a rest/spread pair which has the * same values. */ function isValidRestSpreadPair(ctorParam, superArg) { return ctorParam.type === "RestElement" && superArg.type === "SpreadElement" && isValidIdentifierPair(ctorParam.argument, superArg.argument); } /** * Checks whether given 2 nodes have the same value or not. * * @param {ASTNode} ctorParam - A node to check. * @param {ASTNode} superArg - A node to check. * @returns {boolean} `true` if the nodes have the same value or not. */ function isValidPair(ctorParam, superArg) { return isValidIdentifierPair(ctorParam, superArg) || isValidRestSpreadPair(ctorParam, superArg); } /** * Checks whether the parameters of a constructor and the arguments of `super()` * have the same values or not. * * @param {ASTNode} ctorParams - The parameters of a constructor to check. * @param {ASTNode} superArgs - The arguments of `super()` to check. * @returns {boolean} `true` if those have the same values. */ function isPassingThrough(ctorParams, superArgs) { if (ctorParams.length !== superArgs.length) { return false; } for (var i = 0; i < ctorParams.length; ++i) { if (!isValidPair(ctorParams[i], superArgs[i])) { return false; } } return true; } /** * Checks whether the constructor body is a redundant super call. * * @param {Array} body - constructor body content. * @param {Array} ctorParams - The params to check against super call. * @returns {boolean} true if the construtor body is redundant */ function isRedundantSuperCall(body, ctorParams) { return isSingleSuperCall(body) && ctorParams.every(isSimple) && (isSpreadArguments(body[0].expression.arguments) || isPassingThrough(ctorParams, body[0].expression.arguments)); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary constructors", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-useless-constructor" }, schema: [] }, create: function create(context) { /** * Checks whether a node is a redundant constructor * @param {ASTNode} node - node to check * @returns {void} */ function checkForConstructor(node) { if (node.kind !== "constructor") { return; } var body = node.value.body.body; var ctorParams = node.value.params; var superClass = node.parent.parent.superClass; if (superClass ? isRedundantSuperCall(body, ctorParams) : body.length === 0) { context.report({ node: node, message: "Useless constructor." }); } } return { MethodDefinition: checkForConstructor }; } }; },{}],326:[function(require,module,exports){ /** * @fileoverview Look for useless escapes in strings and regexes * @author Onur Temizkan */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** * Returns the union of two sets. * @param {Set} setA The first set * @param {Set} setB The second set * @returns {Set} The union of the two sets */ function union(setA, setB) { return new Set( /*#__PURE__*/regeneratorRuntime.mark(function _callee() { return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: return _context.delegateYield(setA, "t0", 1); case 1: return _context.delegateYield(setB, "t1", 2); case 2: case "end": return _context.stop(); } } }, _callee, this); })()); } var VALID_STRING_ESCAPES = union(new Set("\\nrvtbfux"), astUtils.LINEBREAKS); var REGEX_GENERAL_ESCAPES = new Set("\\bcdDfnpPrsStvwWxu0123456789]"); var REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+?[{}|()Bk")); /** * Parses a regular expression into a list of characters with character class info. * @param {string} regExpText The raw text used to create the regular expression * @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class. * @example * * parseRegExp('a\\b[cd-]') * * returns: * [ * {text: 'a', index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false}, * {text: 'b', index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false}, * {text: 'c', index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false}, * {text: 'd', index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false}, * {text: '-', index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false} * ] */ function parseRegExp(regExpText) { var charList = []; regExpText.split("").reduce(function (state, char, index) { if (!state.escapeNextChar) { if (char === "\\") { return Object.assign(state, { escapeNextChar: true }); } if (char === "[" && !state.inCharClass) { return Object.assign(state, { inCharClass: true, startingCharClass: true }); } if (char === "]" && state.inCharClass) { if (charList.length && charList[charList.length - 1].inCharClass) { charList[charList.length - 1].endsCharClass = true; } return Object.assign(state, { inCharClass: false, startingCharClass: false }); } } charList.push({ text: char, index: index, escaped: state.escapeNextChar, inCharClass: state.inCharClass, startsCharClass: state.startingCharClass, endsCharClass: false }); return Object.assign(state, { escapeNextChar: false, startingCharClass: false }); }, { escapeNextChar: false, inCharClass: false, startingCharClass: false }); return charList; } module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary escape characters", category: "Best Practices", recommended: true, url: "https://eslint.org/docs/rules/no-useless-escape" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Reports a node * @param {ASTNode} node The node to report * @param {number} startOffset The backslash's offset from the start of the node * @param {string} character The uselessly escaped character (not including the backslash) * @returns {void} */ function report(node, startOffset, character) { context.report({ node: node, loc: sourceCode.getLocFromIndex(sourceCode.getIndexFromLoc(node.loc.start) + startOffset), message: "Unnecessary escape character: \\{{character}}.", data: { character: character } }); } /** * Checks if the escape character in given string slice is unnecessary. * * @private * @param {ASTNode} node - node to validate. * @param {string} match - string slice to validate. * @returns {void} */ function validateString(node, match) { var isTemplateElement = node.type === "TemplateElement"; var escapedChar = match[0][1]; var isUnnecessaryEscape = !VALID_STRING_ESCAPES.has(escapedChar); var isQuoteEscape = void 0; if (isTemplateElement) { isQuoteEscape = escapedChar === "`"; if (escapedChar === "$") { // Warn if `\$` is not followed by `{` isUnnecessaryEscape = match.input[match.index + 2] !== "{"; } else if (escapedChar === "{") { /* * Warn if `\{` is not preceded by `$`. If preceded by `$`, escaping * is necessary and the rule should not warn. If preceded by `/$`, the rule * will warn for the `/$` instead, as it is the first unnecessarily escaped character. */ isUnnecessaryEscape = match.input[match.index - 1] !== "$"; } } else { isQuoteEscape = escapedChar === node.raw[0]; } if (isUnnecessaryEscape && !isQuoteEscape) { report(node, match.index + 1, match[0].slice(1)); } } /** * Checks if a node has an escape. * * @param {ASTNode} node - node to check. * @returns {void} */ function check(node) { var isTemplateElement = node.type === "TemplateElement"; if (isTemplateElement && node.parent && node.parent.parent && node.parent.parent.type === "TaggedTemplateExpression" && node.parent === node.parent.parent.quasi) { // Don't report tagged template literals, because the backslash character is accessible to the tag function. return; } if (typeof node.value === "string" || isTemplateElement) { /* * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/. * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25. */ if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment") { return; } var value = isTemplateElement ? node.value.raw : node.raw.slice(1, -1); var pattern = /\\[^\d]/g; var match = void 0; while (match = pattern.exec(value)) { validateString(node, match); } } else if (node.regex) { parseRegExp(node.regex.pattern) /* * The '-' character is a special case, because it's only valid to escape it if it's in a character * class, and is not at either edge of the character class. To account for this, don't consider '-' * characters to be valid in general, and filter out '-' characters that appear in the middle of a * character class. */ .filter(function (charInfo) { return !(charInfo.text === "-" && charInfo.inCharClass && !charInfo.startsCharClass && !charInfo.endsCharClass); }) /* * The '^' character is also a special case; it must always be escaped outside of character classes, but * it only needs to be escaped in character classes if it's at the beginning of the character class. To * account for this, consider it to be a valid escape character outside of character classes, and filter * out '^' characters that appear at the start of a character class. */ .filter(function (charInfo) { return !(charInfo.text === "^" && charInfo.startsCharClass); }) // Filter out characters that aren't escaped. .filter(function (charInfo) { return charInfo.escaped; }) // Filter out characters that are valid to escape, based on their position in the regular expression. .filter(function (charInfo) { return !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text); }) // Report all the remaining characters. .forEach(function (charInfo) { return report(node, charInfo.index, charInfo.text); }); } } return { Literal: check, TemplateElement: check }; } }; },{"../util/ast-utils":405}],327:[function(require,module,exports){ /** * @fileoverview Disallow renaming import, export, and destructured assignments to the same name. * @author Kai Cataldo */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow renaming import, export, and destructured assignments to the same name", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-useless-rename" }, fixable: "code", schema: [{ type: "object", properties: { ignoreDestructuring: { type: "boolean" }, ignoreImport: { type: "boolean" }, ignoreExport: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] || {}, ignoreDestructuring = options.ignoreDestructuring === true, ignoreImport = options.ignoreImport === true, ignoreExport = options.ignoreExport === true; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports error for unnecessarily renamed assignments * @param {ASTNode} node - node to report * @param {ASTNode} initial - node with initial name value * @param {ASTNode} result - node with new name value * @param {string} type - the type of the offending node * @returns {void} */ function reportError(node, initial, result, type) { var name = initial.type === "Identifier" ? initial.name : initial.value; return context.report({ node: node, message: "{{type}} {{name}} unnecessarily renamed.", data: { name: name, type: type }, fix: function fix(fixer) { return fixer.replaceTextRange([initial.range[0], result.range[1]], name); } }); } /** * Checks whether a destructured assignment is unnecessarily renamed * @param {ASTNode} node - node to check * @returns {void} */ function checkDestructured(node) { if (ignoreDestructuring) { return; } var properties = node.properties; for (var i = 0; i < properties.length; i++) { if (properties[i].shorthand) { continue; } /** * If an ObjectPattern property is computed, we have no idea * if a rename is useless or not. If an ObjectPattern property * lacks a key, it is likely an ExperimentalRestProperty and * so there is no "renaming" occurring here. */ if (properties[i].computed || !properties[i].key) { continue; } if (properties[i].key.type === "Identifier" && properties[i].key.name === properties[i].value.name || properties[i].key.type === "Literal" && properties[i].key.value === properties[i].value.name) { reportError(properties[i], properties[i].key, properties[i].value, "Destructuring assignment"); } } } /** * Checks whether an import is unnecessarily renamed * @param {ASTNode} node - node to check * @returns {void} */ function checkImport(node) { if (ignoreImport) { return; } if (node.imported.name === node.local.name && node.imported.range[0] !== node.local.range[0]) { reportError(node, node.imported, node.local, "Import"); } } /** * Checks whether an export is unnecessarily renamed * @param {ASTNode} node - node to check * @returns {void} */ function checkExport(node) { if (ignoreExport) { return; } if (node.local.name === node.exported.name && node.local.range[0] !== node.exported.range[0]) { reportError(node, node.local, node.exported, "Export"); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ObjectPattern: checkDestructured, ImportSpecifier: checkImport, ExportSpecifier: checkExport }; } }; },{}],328:[function(require,module,exports){ /** * @fileoverview Disallow redundant return statements * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var astUtils = require("../util/ast-utils"), FixTracker = require("../util/fix-tracker"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Removes the given element from the array. * * @param {Array} array - The source array to remove. * @param {any} element - The target item to remove. * @returns {void} */ function remove(array, element) { var index = array.indexOf(element); if (index !== -1) { array.splice(index, 1); } } /** * Checks whether it can remove the given return statement or not. * * @param {ASTNode} node - The return statement node to check. * @returns {boolean} `true` if the node is removeable. */ function isRemovable(node) { return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type); } /** * Checks whether the given return statement is in a `finally` block or not. * * @param {ASTNode} node - The return statement node to check. * @returns {boolean} `true` if the node is in a `finally` block. */ function isInFinally(node) { for (var currentNode = node; currentNode && currentNode.parent && !astUtils.isFunction(currentNode); currentNode = currentNode.parent) { if (currentNode.parent.type === "TryStatement" && currentNode.parent.finalizer === currentNode) { return true; } } return false; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow redundant return statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-useless-return" }, fixable: "code", schema: [] }, create: function create(context) { var segmentInfoMap = new WeakMap(); var usedUnreachableSegments = new WeakSet(); var scopeInfo = null; /** * Checks whether the given segment is terminated by a return statement or not. * * @param {CodePathSegment} segment - The segment to check. * @returns {boolean} `true` if the segment is terminated by a return statement, or if it's still a part of unreachable. */ function isReturned(segment) { var info = segmentInfoMap.get(segment); return !info || info.returned; } /** * Collects useless return statements from the given previous segments. * * A previous segment may be an unreachable segment. * In that case, the information object of the unreachable segment is not * initialized because `onCodePathSegmentStart` event is not notified for * unreachable segments. * This goes to the previous segments of the unreachable segment recursively * if the unreachable segment was generated by a return statement. Otherwise, * this ignores the unreachable segment. * * This behavior would simulate code paths for the case that the return * statement does not exist. * * @param {ASTNode[]} uselessReturns - The collected return statements. * @param {CodePathSegment[]} prevSegments - The previous segments to traverse. * @param {WeakSet} [providedTraversedSegments] A set of segments that have already been traversed in this call * @returns {ASTNode[]} `uselessReturns`. */ function getUselessReturns(uselessReturns, prevSegments, providedTraversedSegments) { var traversedSegments = providedTraversedSegments || new WeakSet(); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = prevSegments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var segment = _step.value; if (!segment.reachable) { if (!traversedSegments.has(segment)) { traversedSegments.add(segment); getUselessReturns(uselessReturns, segment.allPrevSegments.filter(isReturned), traversedSegments); } continue; } uselessReturns.push.apply(uselessReturns, _toConsumableArray(segmentInfoMap.get(segment).uselessReturns)); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return uselessReturns; } /** * Removes the return statements on the given segment from the useless return * statement list. * * This segment may be an unreachable segment. * In that case, the information object of the unreachable segment is not * initialized because `onCodePathSegmentStart` event is not notified for * unreachable segments. * This goes to the previous segments of the unreachable segment recursively * if the unreachable segment was generated by a return statement. Otherwise, * this ignores the unreachable segment. * * This behavior would simulate code paths for the case that the return * statement does not exist. * * @param {CodePathSegment} segment - The segment to get return statements. * @returns {void} */ function markReturnStatementsOnSegmentAsUsed(segment) { if (!segment.reachable) { usedUnreachableSegments.add(segment); segment.allPrevSegments.filter(isReturned).filter(function (prevSegment) { return !usedUnreachableSegments.has(prevSegment); }).forEach(markReturnStatementsOnSegmentAsUsed); return; } var info = segmentInfoMap.get(segment); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = info.uselessReturns[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var node = _step2.value; remove(scopeInfo.uselessReturns, node); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } info.uselessReturns = []; } /** * Removes the return statements on the current segments from the useless * return statement list. * * This function will be called at every statement except FunctionDeclaration, * BlockStatement, and BreakStatement. * * - FunctionDeclarations are always executed whether it's returned or not. * - BlockStatements do nothing. * - BreakStatements go the next merely. * * @returns {void} */ function markReturnStatementsOnCurrentSegmentsAsUsed() { scopeInfo.codePath.currentSegments.forEach(markReturnStatementsOnSegmentAsUsed); } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { // Makes and pushs a new scope information. onCodePathStart: function onCodePathStart(codePath) { scopeInfo = { upper: scopeInfo, uselessReturns: [], codePath: codePath }; }, // Reports useless return statements if exist. onCodePathEnd: function onCodePathEnd() { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { var _loop = function _loop() { var node = _step3.value; context.report({ node: node, loc: node.loc, message: "Unnecessary return statement.", fix: function fix(fixer) { if (isRemovable(node)) { /* * Extend the replacement range to include the * entire function to avoid conflicting with * no-else-return. * https://github.com/eslint/eslint/issues/8026 */ return new FixTracker(fixer, context.getSourceCode()).retainEnclosingFunction(node).remove(node); } return null; } }); }; for (var _iterator3 = scopeInfo.uselessReturns[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { _loop(); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } scopeInfo = scopeInfo.upper; }, /* * Initializes segments. * NOTE: This event is notified for only reachable segments. */ onCodePathSegmentStart: function onCodePathSegmentStart(segment) { var info = { uselessReturns: getUselessReturns([], segment.allPrevSegments), returned: false }; // Stores the info. segmentInfoMap.set(segment, info); }, // Adds ReturnStatement node to check whether it's useless or not. ReturnStatement: function ReturnStatement(node) { if (node.argument) { markReturnStatementsOnCurrentSegmentsAsUsed(); } if (node.argument || astUtils.isInLoop(node) || isInFinally(node)) { return; } var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = scopeInfo.codePath.currentSegments[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var segment = _step4.value; var info = segmentInfoMap.get(segment); if (info) { info.uselessReturns.push(node); info.returned = true; } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } scopeInfo.uselessReturns.push(node); }, /* * Registers for all statement nodes except FunctionDeclaration, BlockStatement, BreakStatement. * Removes return statements of the current segments from the useless return statement list. */ ClassDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, ContinueStatement: markReturnStatementsOnCurrentSegmentsAsUsed, DebuggerStatement: markReturnStatementsOnCurrentSegmentsAsUsed, DoWhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, EmptyStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ExpressionStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ForInStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ForOfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ForStatement: markReturnStatementsOnCurrentSegmentsAsUsed, IfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ImportDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, LabeledStatement: markReturnStatementsOnCurrentSegmentsAsUsed, SwitchStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ThrowStatement: markReturnStatementsOnCurrentSegmentsAsUsed, TryStatement: markReturnStatementsOnCurrentSegmentsAsUsed, VariableDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, WhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, WithStatement: markReturnStatementsOnCurrentSegmentsAsUsed, ExportNamedDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, ExportDefaultDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, ExportAllDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed }; } }; },{"../util/ast-utils":405,"../util/fix-tracker":407}],329:[function(require,module,exports){ /** * @fileoverview Rule to check for the usage of var. * @author Jamund Ferguson */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Check whether a given variable is a global variable or not. * @param {eslint-scope.Variable} variable The variable to check. * @returns {boolean} `true` if the variable is a global variable. */ function isGlobal(variable) { return Boolean(variable.scope) && variable.scope.type === "global"; } /** * Finds the nearest function scope or global scope walking up the scope * hierarchy. * * @param {eslint-scope.Scope} scope - The scope to traverse. * @returns {eslint-scope.Scope} a function scope or global scope containing the given * scope. */ function getEnclosingFunctionScope(scope) { var currentScope = scope; while (currentScope.type !== "function" && currentScope.type !== "global") { currentScope = currentScope.upper; } return currentScope; } /** * Checks whether the given variable has any references from a more specific * function expression (i.e. a closure). * * @param {eslint-scope.Variable} variable - A variable to check. * @returns {boolean} `true` if the variable is used from a closure. */ function isReferencedInClosure(variable) { var enclosingFunctionScope = getEnclosingFunctionScope(variable.scope); return variable.references.some(function (reference) { return getEnclosingFunctionScope(reference.from) !== enclosingFunctionScope; }); } /** * Checks whether the given node is the assignee of a loop. * * @param {ASTNode} node - A VariableDeclaration node to check. * @returns {boolean} `true` if the declaration is assigned as part of loop * iteration. */ function isLoopAssignee(node) { return (node.parent.type === "ForOfStatement" || node.parent.type === "ForInStatement") && node === node.parent.left; } /** * Checks whether the given variable declaration is immediately initialized. * * @param {ASTNode} node - A VariableDeclaration node to check. * @returns {boolean} `true` if the declaration has an initializer. */ function isDeclarationInitialized(node) { return node.declarations.every(function (declarator) { return declarator.init !== null; }); } var SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/; /** * Gets the scope node which directly contains a given node. * * @param {ASTNode} node - A node to get. This is a `VariableDeclaration` or * an `Identifier`. * @returns {ASTNode} A scope node. This is one of `Program`, `BlockStatement`, * `SwitchStatement`, `ForStatement`, `ForInStatement`, and * `ForOfStatement`. */ function getScopeNode(node) { for (var currentNode = node; currentNode; currentNode = currentNode.parent) { if (SCOPE_NODE_TYPE.test(currentNode.type)) { return currentNode; } } /* istanbul ignore next : unreachable */ return null; } /** * Checks whether a given variable is redeclared or not. * * @param {eslint-scope.Variable} variable - A variable to check. * @returns {boolean} `true` if the variable is redeclared. */ function isRedeclared(variable) { return variable.defs.length >= 2; } /** * Checks whether a given variable is used from outside of the specified scope. * * @param {ASTNode} scopeNode - A scope node to check. * @returns {Function} The predicate function which checks whether a given * variable is used from outside of the specified scope. */ function isUsedFromOutsideOf(scopeNode) { /** * Checks whether a given reference is inside of the specified scope or not. * * @param {eslint-scope.Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is inside of the specified * scope. */ function isOutsideOfScope(reference) { var scope = scopeNode.range; var id = reference.identifier.range; return id[0] < scope[0] || id[1] > scope[1]; } return function (variable) { return variable.references.some(isOutsideOfScope); }; } /** * Creates the predicate function which checks whether a variable has their references in TDZ. * * The predicate function would return `true`: * * - if a reference is before the declarator. E.g. (var a = b, b = 1;)(var {a = b, b} = {};) * - if a reference is in the expression of their default value. E.g. (var {a = a} = {};) * - if a reference is in the expression of their initializer. E.g. (var a = a;) * * @param {ASTNode} node - The initializer node of VariableDeclarator. * @returns {Function} The predicate function. * @private */ function hasReferenceInTDZ(node) { var initStart = node.range[0]; var initEnd = node.range[1]; return function (variable) { var id = variable.defs[0].name; var idStart = id.range[0]; var defaultValue = id.parent.type === "AssignmentPattern" ? id.parent.right : null; var defaultStart = defaultValue && defaultValue.range[0]; var defaultEnd = defaultValue && defaultValue.range[1]; return variable.references.some(function (reference) { var start = reference.identifier.range[0]; var end = reference.identifier.range[1]; return !reference.init && (start < idStart || defaultValue !== null && start >= defaultStart && end <= defaultEnd || start >= initStart && end <= initEnd); }); }; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `let` or `const` instead of `var`", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/no-var" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Checks whether the variables which are defined by the given declarator node have their references in TDZ. * * @param {ASTNode} declarator - The VariableDeclarator node to check. * @returns {boolean} `true` if one of the variables which are defined by the given declarator node have their references in TDZ. */ function hasSelfReferenceInTDZ(declarator) { if (!declarator.init) { return false; } var variables = context.getDeclaredVariables(declarator); return variables.some(hasReferenceInTDZ(declarator.init)); } /** * Checks whether it can fix a given variable declaration or not. * It cannot fix if the following cases: * * - A variable is a global variable. * - A variable is declared on a SwitchCase node. * - A variable is redeclared. * - A variable is used from outside the scope. * - A variable is used from a closure within a loop. * - A variable might be used before it is assigned within a loop. * - A variable might be used in TDZ. * - A variable is declared in statement position (e.g. a single-line `IfStatement`) * * ## A variable is declared on a SwitchCase node. * * If this rule modifies 'var' declarations on a SwitchCase node, it * would generate the warnings of 'no-case-declarations' rule. And the * 'eslint:recommended' preset includes 'no-case-declarations' rule, so * this rule doesn't modify those declarations. * * ## A variable is redeclared. * * The language spec disallows redeclarations of `let` declarations. * Those variables would cause syntax errors. * * ## A variable is used from outside the scope. * * The language spec disallows accesses from outside of the scope for * `let` declarations. Those variables would cause reference errors. * * ## A variable is used from a closure within a loop. * * A `var` declaration within a loop shares the same variable instance * across all loop iterations, while a `let` declaration creates a new * instance for each iteration. This means if a variable in a loop is * referenced by any closure, changing it from `var` to `let` would * change the behavior in a way that is generally unsafe. * * ## A variable might be used before it is assigned within a loop. * * Within a loop, a `let` declaration without an initializer will be * initialized to null, while a `var` declaration will retain its value * from the previous iteration, so it is only safe to change `var` to * `let` if we can statically determine that the variable is always * assigned a value before its first access in the loop body. To keep * the implementation simple, we only convert `var` to `let` within * loops when the variable is a loop assignee or the declaration has an * initializer. * * @param {ASTNode} node - A variable declaration node to check. * @returns {boolean} `true` if it can fix the node. */ function canFix(node) { var variables = context.getDeclaredVariables(node); var scopeNode = getScopeNode(node); if (node.parent.type === "SwitchCase" || node.declarations.some(hasSelfReferenceInTDZ) || variables.some(isGlobal) || variables.some(isRedeclared) || variables.some(isUsedFromOutsideOf(scopeNode))) { return false; } if (astUtils.isInLoop(node)) { if (variables.some(isReferencedInClosure)) { return false; } if (!isLoopAssignee(node) && !isDeclarationInitialized(node)) { return false; } } if (!isLoopAssignee(node) && !(node.parent.type === "ForStatement" && node.parent.init === node) && !astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { // If the declaration is not in a block, e.g. `if (foo) var bar = 1;`, then it can't be fixed. return false; } return true; } /** * Reports a given variable declaration node. * * @param {ASTNode} node - A variable declaration node to report. * @returns {void} */ function report(node) { var varToken = sourceCode.getFirstToken(node); context.report({ node: node, message: "Unexpected var, use let or const instead.", fix: function fix(fixer) { if (canFix(node)) { return fixer.replaceText(varToken, "let"); } return null; } }); } return { "VariableDeclaration:exit": function VariableDeclarationExit(node) { if (node.kind === "var") { report(node); } } }; } }; },{"../util/ast-utils":405}],330:[function(require,module,exports){ /** * @fileoverview Rule to disallow use of void operator. * @author Mike Sidorov */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `void` operators", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-void" }, schema: [] }, create: function create(context) { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { UnaryExpression: function UnaryExpression(node) { if (node.operator === "void") { context.report({ node: node, message: "Expected 'undefined' and instead saw 'void'." }); } } }; } }; },{}],331:[function(require,module,exports){ /** * @fileoverview Rule that warns about used warning comments * @author Alexander Schmidt */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow specified warning terms in comments", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-warning-comments" }, schema: [{ type: "object", properties: { terms: { type: "array", items: { type: "string" } }, location: { enum: ["start", "anywhere"] } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(), configuration = context.options[0] || {}, warningTerms = configuration.terms || ["todo", "fixme", "xxx"], location = configuration.location || "start", selfConfigRegEx = /\bno-warning-comments\b/; /** * Convert a warning term into a RegExp which will match a comment containing that whole word in the specified * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not * require word boundaries on that side. * * @param {string} term A term to convert to a RegExp * @returns {RegExp} The term converted to a RegExp */ function convertToRegExp(term) { var escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/g, "\\$&"); var wordBoundary = "\\b"; var eitherOrWordBoundary = "|" + wordBoundary; var prefix = void 0; /* * If the term ends in a word character (a-z0-9_), ensure a word * boundary at the end, so that substrings do not get falsely * matched. eg "todo" in a string such as "mastodon". * If the term ends in a non-word character, then \b won't match on * the boundary to the next non-word character, which would likely * be a space. For example `/\bFIX!\b/.test('FIX! blah') === false`. * In these cases, use no bounding match. Same applies for the * prefix, handled below. */ var suffix = /\w$/.test(term) ? "\\b" : ""; if (location === "start") { /* * When matching at the start, ignore leading whitespace, and * there's no need to worry about word boundaries. */ prefix = "^\\s*"; } else if (/^\w/.test(term)) { prefix = wordBoundary; } else { prefix = ""; } if (location === "start") { /* * For location "start" the regex should be * ^\s*TERM\b. This checks the word boundary * at the beginning of the comment. */ return new RegExp(prefix + escaped + suffix, "i"); } /* * For location "anywhere" the regex should be * \bTERM\b|\bTERM\b, this checks the entire comment * for the term. */ return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); } var warningRegExps = warningTerms.map(convertToRegExp); /** * Checks the specified comment for matches of the configured warning terms and returns the matches. * @param {string} comment The comment which is checked. * @returns {Array} All matched warning terms for this comment. */ function commentContainsWarningTerm(comment) { var matches = []; warningRegExps.forEach(function (regex, index) { if (regex.test(comment)) { matches.push(warningTerms[index]); } }); return matches; } /** * Checks the specified node for matching warning comments and reports them. * @param {ASTNode} node The AST node being checked. * @returns {void} undefined. */ function checkComment(node) { if (astUtils.isDirectiveComment(node) && selfConfigRegEx.test(node.value)) { return; } var matches = commentContainsWarningTerm(node.value); matches.forEach(function (matchedTerm) { context.report({ node: node, message: "Unexpected '{{matchedTerm}}' comment.", data: { matchedTerm: matchedTerm } }); }); } return { Program: function Program() { var comments = sourceCode.getAllComments(); comments.filter(function (token) { return token.type !== "Shebang"; }).forEach(checkComment); } }; } }; },{"../util/ast-utils":405}],332:[function(require,module,exports){ /** * @fileoverview Rule to disallow whitespace before properties * @author Kai Cataldo */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "disallow whitespace before properties", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/no-whitespace-before-property" }, fixable: "whitespace", schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports whitespace before property token * @param {ASTNode} node - the node to report in the event of an error * @param {Token} leftToken - the left token * @param {Token} rightToken - the right token * @returns {void} * @private */ function reportError(node, leftToken, rightToken) { var replacementText = node.computed ? "" : "."; context.report({ node: node, message: "Unexpected whitespace before property {{propName}}.", data: { propName: sourceCode.getText(node.property) }, fix: function fix(fixer) { if (!node.computed && astUtils.isDecimalInteger(node.object)) { /* * If the object is a number literal, fixing it to something like 5.toString() would cause a SyntaxError. * Don't fix this case. */ return null; } return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], replacementText); } }); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { MemberExpression: function MemberExpression(node) { var rightToken = void 0; var leftToken = void 0; if (!astUtils.isTokenOnSameLine(node.object, node.property)) { return; } if (node.computed) { rightToken = sourceCode.getTokenBefore(node.property, astUtils.isOpeningBracketToken); leftToken = sourceCode.getTokenBefore(rightToken); } else { rightToken = sourceCode.getFirstToken(node.property); leftToken = sourceCode.getTokenBefore(rightToken, 1); } if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) { reportError(node, leftToken, rightToken); } } }; } }; },{"../util/ast-utils":405}],333:[function(require,module,exports){ /** * @fileoverview Rule to flag use of with statement * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `with` statements", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/no-with" }, schema: [] }, create: function create(context) { return { WithStatement: function WithStatement(node) { context.report({ node: node, message: "Unexpected use of 'with' statement." }); } }; } }; },{}],334:[function(require,module,exports){ /** * @fileoverview enforce the location of single-line statements * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var POSITION_SCHEMA = { enum: ["beside", "below", "any"] }; module.exports = { meta: { type: "layout", docs: { description: "enforce the location of single-line statements", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/nonblock-statement-body-position" }, fixable: "whitespace", schema: [POSITION_SCHEMA, { properties: { overrides: { properties: { if: POSITION_SCHEMA, else: POSITION_SCHEMA, while: POSITION_SCHEMA, do: POSITION_SCHEMA, for: POSITION_SCHEMA }, additionalProperties: false } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Gets the applicable preference for a particular keyword * @param {string} keywordName The name of a keyword, e.g. 'if' * @returns {string} The applicable option for the keyword, e.g. 'beside' */ function getOption(keywordName) { return context.options[1] && context.options[1].overrides && context.options[1].overrides[keywordName] || context.options[0] || "beside"; } /** * Validates the location of a single-line statement * @param {ASTNode} node The single-line statement * @param {string} keywordName The applicable keyword name for the single-line statement * @returns {void} */ function validateStatement(node, keywordName) { var option = getOption(keywordName); if (node.type === "BlockStatement" || option === "any") { return; } var tokenBefore = sourceCode.getTokenBefore(node); if (tokenBefore.loc.end.line === node.loc.start.line && option === "below") { context.report({ node: node, message: "Expected a linebreak before this statement.", fix: function fix(fixer) { return fixer.insertTextBefore(node, "\n"); } }); } else if (tokenBefore.loc.end.line !== node.loc.start.line && option === "beside") { context.report({ node: node, message: "Expected no linebreak before this statement.", fix: function fix(fixer) { if (sourceCode.getText().slice(tokenBefore.range[1], node.range[0]).trim()) { return null; } return fixer.replaceTextRange([tokenBefore.range[1], node.range[0]], " "); } }); } } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { IfStatement: function IfStatement(node) { validateStatement(node.consequent, "if"); // Check the `else` node, but don't check 'else if' statements. if (node.alternate && node.alternate.type !== "IfStatement") { validateStatement(node.alternate, "else"); } }, WhileStatement: function WhileStatement(node) { return validateStatement(node.body, "while"); }, DoWhileStatement: function DoWhileStatement(node) { return validateStatement(node.body, "do"); }, ForStatement: function ForStatement(node) { return validateStatement(node.body, "for"); }, ForInStatement: function ForInStatement(node) { return validateStatement(node.body, "for"); }, ForOfStatement: function ForOfStatement(node) { return validateStatement(node.body, "for"); } }; } }; },{}],335:[function(require,module,exports){ /** * @fileoverview Rule to require or disallow line breaks inside braces. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); var lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ // Schema objects. var OPTION_VALUE = { oneOf: [{ enum: ["always", "never"] }, { type: "object", properties: { multiline: { type: "boolean" }, minProperties: { type: "integer", minimum: 0 }, consistent: { type: "boolean" } }, additionalProperties: false, minProperties: 1 }] }; /** * Normalizes a given option value. * * @param {string|Object|undefined} value - An option value to parse. * @returns {{multiline: boolean, minProperties: number, consistent: boolean}} Normalized option object. */ function normalizeOptionValue(value) { var multiline = false; var minProperties = Number.POSITIVE_INFINITY; var consistent = false; if (value) { if (value === "always") { minProperties = 0; } else if (value === "never") { minProperties = Number.POSITIVE_INFINITY; } else { multiline = Boolean(value.multiline); minProperties = value.minProperties || Number.POSITIVE_INFINITY; consistent = Boolean(value.consistent); } } else { consistent = true; } return { multiline: multiline, minProperties: minProperties, consistent: consistent }; } /** * Normalizes a given option value. * * @param {string|Object|undefined} options - An option value to parse. * @returns {{ * ObjectExpression: {multiline: boolean, minProperties: number, consistent: boolean}, * ObjectPattern: {multiline: boolean, minProperties: number, consistent: boolean}, * ImportDeclaration: {multiline: boolean, minProperties: number, consistent: boolean}, * ExportNamedDeclaration : {multiline: boolean, minProperties: number, consistent: boolean} * }} Normalized option object. */ function normalizeOptions(options) { var isNodeSpecificOption = lodash.overSome([lodash.isPlainObject, lodash.isString]); if (lodash.isPlainObject(options) && lodash.some(options, isNodeSpecificOption)) { return { ObjectExpression: normalizeOptionValue(options.ObjectExpression), ObjectPattern: normalizeOptionValue(options.ObjectPattern), ImportDeclaration: normalizeOptionValue(options.ImportDeclaration), ExportNamedDeclaration: normalizeOptionValue(options.ExportDeclaration) }; } var value = normalizeOptionValue(options); return { ObjectExpression: value, ObjectPattern: value, ImportDeclaration: value, ExportNamedDeclaration: value }; } /** * Determines if ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration * node needs to be checked for missing line breaks * * @param {ASTNode} node - Node under inspection * @param {Object} options - option specific to node type * @param {Token} first - First object property * @param {Token} last - Last object property * @returns {boolean} `true` if node needs to be checked for missing line breaks */ function areLineBreaksRequired(node, options, first, last) { var objectProperties = void 0; if (node.type === "ObjectExpression" || node.type === "ObjectPattern") { objectProperties = node.properties; } else { // is ImportDeclaration or ExportNamedDeclaration objectProperties = node.specifiers.filter(function (s) { return s.type === "ImportSpecifier" || s.type === "ExportSpecifier"; }); } return objectProperties.length >= options.minProperties || options.multiline && objectProperties.length > 0 && first.loc.start.line !== last.loc.end.line; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent line breaks inside braces", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/object-curly-newline" }, fixable: "whitespace", schema: [{ oneOf: [OPTION_VALUE, { type: "object", properties: { ObjectExpression: OPTION_VALUE, ObjectPattern: OPTION_VALUE, ImportDeclaration: OPTION_VALUE, ExportDeclaration: OPTION_VALUE }, additionalProperties: false, minProperties: 1 }] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var normalizedOptions = normalizeOptions(context.options[0]); /** * Reports a given node if it violated this rule. * @param {ASTNode} node - A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node. * @returns {void} */ function check(node) { var options = normalizedOptions[node.type]; if (node.type === "ImportDeclaration" && !node.specifiers.some(function (specifier) { return specifier.type === "ImportSpecifier"; }) || node.type === "ExportNamedDeclaration" && !node.specifiers.some(function (specifier) { return specifier.type === "ExportSpecifier"; })) { return; } var openBrace = sourceCode.getFirstToken(node, function (token) { return token.value === "{"; }); var closeBrace = void 0; if (node.typeAnnotation) { closeBrace = sourceCode.getTokenBefore(node.typeAnnotation); } else { closeBrace = sourceCode.getLastToken(node, function (token) { return token.value === "}"; }); } var first = sourceCode.getTokenAfter(openBrace, { includeComments: true }); var last = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); var needsLineBreaks = areLineBreaksRequired(node, options, first, last); var hasCommentsFirstToken = astUtils.isCommentToken(first); var hasCommentsLastToken = astUtils.isCommentToken(last); /* * Use tokens or comments to check multiline or not. * But use only tokens to check whether line breaks are needed. * This allows: * var obj = { // eslint-disable-line foo * a: 1 * } */ first = sourceCode.getTokenAfter(openBrace); last = sourceCode.getTokenBefore(closeBrace); if (needsLineBreaks) { if (astUtils.isTokenOnSameLine(openBrace, first)) { context.report({ message: "Expected a line break after this opening brace.", node: node, loc: openBrace.loc.start, fix: function fix(fixer) { if (hasCommentsFirstToken) { return null; } return fixer.insertTextAfter(openBrace, "\n"); } }); } if (astUtils.isTokenOnSameLine(last, closeBrace)) { context.report({ message: "Expected a line break before this closing brace.", node: node, loc: closeBrace.loc.start, fix: function fix(fixer) { if (hasCommentsLastToken) { return null; } return fixer.insertTextBefore(closeBrace, "\n"); } }); } } else { var consistent = options.consistent; var hasLineBreakBetweenOpenBraceAndFirst = !astUtils.isTokenOnSameLine(openBrace, first); var hasLineBreakBetweenCloseBraceAndLast = !astUtils.isTokenOnSameLine(last, closeBrace); if (!consistent && hasLineBreakBetweenOpenBraceAndFirst || consistent && hasLineBreakBetweenOpenBraceAndFirst && !hasLineBreakBetweenCloseBraceAndLast) { context.report({ message: "Unexpected line break after this opening brace.", node: node, loc: openBrace.loc.start, fix: function fix(fixer) { if (hasCommentsFirstToken) { return null; } return fixer.removeRange([openBrace.range[1], first.range[0]]); } }); } if (!consistent && hasLineBreakBetweenCloseBraceAndLast || consistent && !hasLineBreakBetweenOpenBraceAndFirst && hasLineBreakBetweenCloseBraceAndLast) { context.report({ message: "Unexpected line break before this closing brace.", node: node, loc: closeBrace.loc.start, fix: function fix(fixer) { if (hasCommentsLastToken) { return null; } return fixer.removeRange([last.range[1], closeBrace.range[0]]); } }); } } } return { ObjectExpression: check, ObjectPattern: check, ImportDeclaration: check, ExportNamedDeclaration: check }; } }; },{"../util/ast-utils":405,"lodash":92}],336:[function(require,module,exports){ /** * @fileoverview Disallows or enforces spaces inside of object literals. * @author Jamund Ferguson */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing inside braces", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/object-curly-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }, { type: "object", properties: { arraysInObjects: { type: "boolean" }, objectsInObjects: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var spaced = context.options[0] === "always", sourceCode = context.getSourceCode(); /** * Determines whether an option is set, relative to the spacing option. * If spaced is "always", then check whether option is set to false. * If spaced is "never", then check whether option is set to true. * @param {Object} option - The option to exclude. * @returns {boolean} Whether or not the property is excluded. */ function isOptionSet(option) { return context.options[1] ? context.options[1][option] === !spaced : false; } var options = { spaced: spaced, arraysInObjectsException: isOptionSet("arraysInObjects"), objectsInObjectsException: isOptionSet("objectsInObjects") }; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports that there shouldn't be a space after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoBeginningSpace(node, token) { context.report({ node: node, loc: token.loc.start, message: "There should be no space after '{{token}}'.", data: { token: token.value }, fix: function fix(fixer) { var nextToken = context.getSourceCode().getTokenAfter(token); return fixer.removeRange([token.range[1], nextToken.range[0]]); } }); } /** * Reports that there shouldn't be a space before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportNoEndingSpace(node, token) { context.report({ node: node, loc: token.loc.start, message: "There should be no space before '{{token}}'.", data: { token: token.value }, fix: function fix(fixer) { var previousToken = context.getSourceCode().getTokenBefore(token); return fixer.removeRange([previousToken.range[1], token.range[0]]); } }); } /** * Reports that there should be a space after the first token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredBeginningSpace(node, token) { context.report({ node: node, loc: token.loc.start, message: "A space is required after '{{token}}'.", data: { token: token.value }, fix: function fix(fixer) { return fixer.insertTextAfter(token, " "); } }); } /** * Reports that there should be a space before the last token * @param {ASTNode} node - The node to report in the event of an error. * @param {Token} token - The token to use for the report. * @returns {void} */ function reportRequiredEndingSpace(node, token) { context.report({ node: node, loc: token.loc.start, message: "A space is required before '{{token}}'.", data: { token: token.value }, fix: function fix(fixer) { return fixer.insertTextBefore(token, " "); } }); } /** * Determines if spacing in curly braces is valid. * @param {ASTNode} node The AST node to check. * @param {Token} first The first token to check (should be the opening brace) * @param {Token} second The second token to check (should be first after the opening brace) * @param {Token} penultimate The penultimate token to check (should be last before closing brace) * @param {Token} last The last token to check (should be closing brace) * @returns {void} */ function validateBraceSpacing(node, first, second, penultimate, last) { if (astUtils.isTokenOnSameLine(first, second)) { var firstSpaced = sourceCode.isSpaceBetweenTokens(first, second); if (options.spaced && !firstSpaced) { reportRequiredBeginningSpace(node, first); } if (!options.spaced && firstSpaced) { reportNoBeginningSpace(node, first); } } if (astUtils.isTokenOnSameLine(penultimate, last)) { var shouldCheckPenultimate = options.arraysInObjectsException && astUtils.isClosingBracketToken(penultimate) || options.objectsInObjectsException && astUtils.isClosingBraceToken(penultimate); var penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.range[0]).type; var closingCurlyBraceMustBeSpaced = options.arraysInObjectsException && penultimateType === "ArrayExpression" || options.objectsInObjectsException && (penultimateType === "ObjectExpression" || penultimateType === "ObjectPattern") ? !options.spaced : options.spaced; var lastSpaced = sourceCode.isSpaceBetweenTokens(penultimate, last); if (closingCurlyBraceMustBeSpaced && !lastSpaced) { reportRequiredEndingSpace(node, last); } if (!closingCurlyBraceMustBeSpaced && lastSpaced) { reportNoEndingSpace(node, last); } } } /** * Gets '}' token of an object node. * * Because the last token of object patterns might be a type annotation, * this traverses tokens preceded by the last property, then returns the * first '}' token. * * @param {ASTNode} node - The node to get. This node is an * ObjectExpression or an ObjectPattern. And this node has one or * more properties. * @returns {Token} '}' token. */ function getClosingBraceOfObject(node) { var lastProperty = node.properties[node.properties.length - 1]; return sourceCode.getTokenAfter(lastProperty, astUtils.isClosingBraceToken); } /** * Reports a given object node if spacing in curly braces is invalid. * @param {ASTNode} node - An ObjectExpression or ObjectPattern node to check. * @returns {void} */ function checkForObject(node) { if (node.properties.length === 0) { return; } var first = sourceCode.getFirstToken(node), last = getClosingBraceOfObject(node), second = sourceCode.getTokenAfter(first), penultimate = sourceCode.getTokenBefore(last); validateBraceSpacing(node, first, second, penultimate, last); } /** * Reports a given import node if spacing in curly braces is invalid. * @param {ASTNode} node - An ImportDeclaration node to check. * @returns {void} */ function checkForImport(node) { if (node.specifiers.length === 0) { return; } var firstSpecifier = node.specifiers[0]; var lastSpecifier = node.specifiers[node.specifiers.length - 1]; if (lastSpecifier.type !== "ImportSpecifier") { return; } if (firstSpecifier.type !== "ImportSpecifier") { firstSpecifier = node.specifiers[1]; } var first = sourceCode.getTokenBefore(firstSpecifier), last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken), second = sourceCode.getTokenAfter(first), penultimate = sourceCode.getTokenBefore(last); validateBraceSpacing(node, first, second, penultimate, last); } /** * Reports a given export node if spacing in curly braces is invalid. * @param {ASTNode} node - An ExportNamedDeclaration node to check. * @returns {void} */ function checkForExport(node) { if (node.specifiers.length === 0) { return; } var firstSpecifier = node.specifiers[0], lastSpecifier = node.specifiers[node.specifiers.length - 1], first = sourceCode.getTokenBefore(firstSpecifier), last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken), second = sourceCode.getTokenAfter(first), penultimate = sourceCode.getTokenBefore(last); validateBraceSpacing(node, first, second, penultimate, last); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { // var {x} = y; ObjectPattern: checkForObject, // var y = {x: 'y'} ObjectExpression: checkForObject, // import {y} from 'x'; ImportDeclaration: checkForImport, // export {name} from 'yo'; ExportNamedDeclaration: checkForExport }; } }; },{"../util/ast-utils":405}],337:[function(require,module,exports){ /** * @fileoverview Rule to enforce placing object properties on separate lines. * @author Vitor Balocco */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce placing object properties on separate lines", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/object-property-newline" }, schema: [{ type: "object", properties: { allowAllPropertiesOnSameLine: { type: "boolean" }, allowMultiplePropertiesPerLine: { // Deprecated type: "boolean" } }, additionalProperties: false }], fixable: "whitespace" }, create: function create(context) { var allowSameLine = context.options[0] && (Boolean(context.options[0].allowAllPropertiesOnSameLine) || Boolean(context.options[0].allowMultiplePropertiesPerLine)); var errorMessage = allowSameLine ? "Object properties must go on a new line if they aren't all on the same line." : "Object properties must go on a new line."; var sourceCode = context.getSourceCode(); return { ObjectExpression: function ObjectExpression(node) { if (allowSameLine) { if (node.properties.length > 1) { var firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]); var lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]); if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) { // All keys and values are on the same line return; } } } var _loop = function _loop(i) { var lastTokenOfPreviousProperty = sourceCode.getLastToken(node.properties[i - 1]); var firstTokenOfCurrentProperty = sourceCode.getFirstToken(node.properties[i]); if (lastTokenOfPreviousProperty.loc.end.line === firstTokenOfCurrentProperty.loc.start.line) { context.report({ node: node, loc: firstTokenOfCurrentProperty.loc.start, message: errorMessage, fix: function fix(fixer) { var comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty); var rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]]; // Don't perform a fix if there are any comments between the comma and the next property. if (sourceCode.text.slice(rangeAfterComma[0], rangeAfterComma[1]).trim()) { return null; } return fixer.replaceTextRange(rangeAfterComma, "\n"); } }); } }; for (var i = 1; i < node.properties.length; i++) { _loop(i); } } }; } }; },{}],338:[function(require,module,exports){ /** * @fileoverview Rule to enforce concise object methods and properties. * @author Jamund Ferguson */ "use strict"; var OPTIONS = { always: "always", never: "never", methods: "methods", properties: "properties", consistent: "consistent", consistentAsNeeded: "consistent-as-needed" }; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow method and property shorthand syntax for object literals", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/object-shorthand" }, fixable: "code", schema: { anyOf: [{ type: "array", items: [{ enum: ["always", "methods", "properties", "never", "consistent", "consistent-as-needed"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["always", "methods", "properties"] }, { type: "object", properties: { avoidQuotes: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }, { type: "array", items: [{ enum: ["always", "methods"] }, { type: "object", properties: { ignoreConstructors: { type: "boolean" }, avoidQuotes: { type: "boolean" }, avoidExplicitReturnArrows: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] } }, create: function create(context) { var APPLY = context.options[0] || OPTIONS.always; var APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always; var APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always; var APPLY_NEVER = APPLY === OPTIONS.never; var APPLY_CONSISTENT = APPLY === OPTIONS.consistent; var APPLY_CONSISTENT_AS_NEEDED = APPLY === OPTIONS.consistentAsNeeded; var PARAMS = context.options[1] || {}; var IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; var AVOID_QUOTES = PARAMS.avoidQuotes; var AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Determines if the first character of the name is a capital letter. * @param {string} name The name of the node to evaluate. * @returns {boolean} True if the first character of the property name is a capital letter, false if not. * @private */ function isConstructor(name) { var firstChar = name.charAt(0); return firstChar === firstChar.toUpperCase(); } /** * Determines if the property can have a shorthand form. * @param {ASTNode} property Property AST node * @returns {boolean} True if the property can have a shorthand form * @private * */ function canHaveShorthand(property) { return property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty"; } /** * Checks whether a node is a string literal. * @param {ASTNode} node - Any AST node. * @returns {boolean} `true` if it is a string literal. */ function isStringLiteral(node) { return node.type === "Literal" && typeof node.value === "string"; } /** * Determines if the property is a shorthand or not. * @param {ASTNode} property Property AST node * @returns {boolean} True if the property is considered shorthand, false if not. * @private * */ function isShorthand(property) { // property.method is true when `{a(){}}`. return property.shorthand || property.method; } /** * Determines if the property's key and method or value are named equally. * @param {ASTNode} property Property AST node * @returns {boolean} True if the key and value are named equally, false if not. * @private * */ function isRedundant(property) { var value = property.value; if (value.type === "FunctionExpression") { return !value.id; // Only anonymous should be shorthand method. } if (value.type === "Identifier") { return astUtils.getStaticPropertyName(property) === value.name; } return false; } /** * Ensures that an object's properties are consistently shorthand, or not shorthand at all. * @param {ASTNode} node Property AST node * @param {boolean} checkRedundancy Whether to check longform redundancy * @returns {void} * */ function checkConsistency(node, checkRedundancy) { // We are excluding getters/setters and spread properties as they are considered neither longform nor shorthand. var properties = node.properties.filter(canHaveShorthand); // Do we still have properties left after filtering the getters and setters? if (properties.length > 0) { var shorthandProperties = properties.filter(isShorthand); /* * If we do not have an equal number of longform properties as * shorthand properties, we are using the annotations inconsistently */ if (shorthandProperties.length !== properties.length) { // We have at least 1 shorthand property if (shorthandProperties.length > 0) { context.report({ node: node, message: "Unexpected mix of shorthand and non-shorthand properties." }); } else if (checkRedundancy) { /* * If all properties of the object contain a method or value with a name matching it's key, * all the keys are redundant. */ var canAlwaysUseShorthand = properties.every(isRedundant); if (canAlwaysUseShorthand) { context.report({ node: node, message: "Expected shorthand for all properties." }); } } } } } /** * Fixes a FunctionExpression node by making it into a shorthand property. * @param {SourceCodeFixer} fixer The fixer object * @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value * @returns {Object} A fix for this node */ function makeFunctionShorthand(fixer, node) { var firstKeyToken = node.computed ? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken) : sourceCode.getFirstToken(node.key); var lastKeyToken = node.computed ? sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken) : sourceCode.getLastToken(node.key); var keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); var keyPrefix = ""; if (sourceCode.commentsExistBetween(lastKeyToken, node.value)) { return null; } if (node.value.async) { keyPrefix += "async "; } if (node.value.generator) { keyPrefix += "*"; } if (node.value.type === "FunctionExpression") { var functionToken = sourceCode.getTokens(node.value).find(function (token) { return token.type === "Keyword" && token.value === "function"; }); var tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken; return fixer.replaceTextRange([firstKeyToken.range[0], node.range[1]], keyPrefix + keyText + sourceCode.text.slice(tokenBeforeParams.range[1], node.value.range[1])); } var arrowToken = sourceCode.getTokens(node.value).find(function (token) { return token.value === "=>"; }); var tokenBeforeArrow = sourceCode.getTokenBefore(arrowToken); var hasParensAroundParameters = tokenBeforeArrow.type === "Punctuator" && tokenBeforeArrow.value === ")"; var oldParamText = sourceCode.text.slice(sourceCode.getFirstToken(node.value, node.value.async ? 1 : 0).range[0], tokenBeforeArrow.range[1]); var newParamText = hasParensAroundParameters ? oldParamText : "(" + oldParamText + ")"; return fixer.replaceTextRange([firstKeyToken.range[0], node.range[1]], keyPrefix + keyText + newParamText + sourceCode.text.slice(arrowToken.range[1], node.value.range[1])); } /** * Fixes a FunctionExpression node by making it into a longform property. * @param {SourceCodeFixer} fixer The fixer object * @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value * @returns {Object} A fix for this node */ function makeFunctionLongform(fixer, node) { var firstKeyToken = node.computed ? sourceCode.getTokens(node).find(function (token) { return token.value === "["; }) : sourceCode.getFirstToken(node.key); var lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(function (token) { return token.value === "]"; }) : sourceCode.getLastToken(node.key); var keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); var functionHeader = "function"; if (node.value.async) { functionHeader = "async " + functionHeader; } if (node.value.generator) { functionHeader = functionHeader + "*"; } return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], keyText + ": " + functionHeader); } /* * To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`), * create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is * traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical * scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered, * keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited. * When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them * to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule, * because converting it into a method would change the value of one of the lexical identifiers. */ var lexicalScopeStack = []; var arrowsWithLexicalIdentifiers = new WeakSet(); var argumentsIdentifiers = new WeakSet(); /** * Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack. * Also, this marks all `arguments` identifiers so that they can be detected later. * @returns {void} */ function enterFunction() { lexicalScopeStack.unshift(new Set()); context.getScope().variables.filter(function (variable) { return variable.name === "arguments"; }).forEach(function (variable) { variable.references.map(function (ref) { return ref.identifier; }).forEach(function (identifier) { return argumentsIdentifiers.add(identifier); }); }); } /** * Exits a function. This pops the current set of arrow functions off the lexical scope stack. * @returns {void} */ function exitFunction() { lexicalScopeStack.shift(); } /** * Marks the current function as having a lexical keyword. This implies that all arrow functions * in the current lexical scope contain a reference to this lexical keyword. * @returns {void} */ function reportLexicalIdentifier() { lexicalScopeStack[0].forEach(function (arrowFunction) { return arrowsWithLexicalIdentifiers.add(arrowFunction); }); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: enterFunction, FunctionDeclaration: enterFunction, FunctionExpression: enterFunction, "Program:exit": exitFunction, "FunctionDeclaration:exit": exitFunction, "FunctionExpression:exit": exitFunction, ArrowFunctionExpression: function ArrowFunctionExpression(node) { lexicalScopeStack[0].add(node); }, "ArrowFunctionExpression:exit": function ArrowFunctionExpressionExit(node) { lexicalScopeStack[0].delete(node); }, ThisExpression: reportLexicalIdentifier, Super: reportLexicalIdentifier, MetaProperty: function MetaProperty(node) { if (node.meta.name === "new" && node.property.name === "target") { reportLexicalIdentifier(); } }, Identifier: function Identifier(node) { if (argumentsIdentifiers.has(node)) { reportLexicalIdentifier(); } }, ObjectExpression: function ObjectExpression(node) { if (APPLY_CONSISTENT) { checkConsistency(node, false); } else if (APPLY_CONSISTENT_AS_NEEDED) { checkConsistency(node, true); } }, "Property:exit": function PropertyExit(node) { var isConciseProperty = node.method || node.shorthand; // Ignore destructuring assignment if (node.parent.type === "ObjectPattern") { return; } // getters and setters are ignored if (node.kind === "get" || node.kind === "set") { return; } // only computed methods can fail the following checks if (node.computed && node.value.type !== "FunctionExpression" && node.value.type !== "ArrowFunctionExpression") { return; } //-------------------------------------------------------------- // Checks for property/method shorthand. if (isConciseProperty) { if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) { var message = APPLY_NEVER ? "Expected longform method syntax." : "Expected longform method syntax for string literal keys."; // { x() {} } should be written as { x: function() {} } context.report({ node: node, message: message, fix: function fix(fixer) { return makeFunctionLongform(fixer, node); } }); } else if (APPLY_NEVER) { // { x } should be written as { x: x } context.report({ node: node, message: "Expected longform property syntax.", fix: function fix(fixer) { return fixer.insertTextAfter(node.key, ": " + node.key.name); } }); } } else if (APPLY_TO_METHODS && !node.value.id && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) { if (IGNORE_CONSTRUCTORS && node.key.type === "Identifier" && isConstructor(node.key.name)) { return; } if (AVOID_QUOTES && isStringLiteral(node.key)) { return; } // {[x]: function(){}} should be written as {[x]() {}} if (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression" && node.value.body.type === "BlockStatement" && AVOID_EXPLICIT_RETURN_ARROWS && !arrowsWithLexicalIdentifiers.has(node.value)) { context.report({ node: node, message: "Expected method shorthand.", fix: function fix(fixer) { return makeFunctionShorthand(fixer, node); } }); } } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) { // {x: x} should be written as {x} context.report({ node: node, message: "Expected property shorthand.", fix: function fix(fixer) { return fixer.replaceText(node, node.value.name); } }); } else if (node.value.type === "Identifier" && node.key.type === "Literal" && node.key.value === node.value.name && APPLY_TO_PROPS) { if (AVOID_QUOTES) { return; } // {"x": x} should be written as {x} context.report({ node: node, message: "Expected property shorthand.", fix: function fix(fixer) { return fixer.replaceText(node, node.value.name); } }); } } }; } }; },{"../util/ast-utils":405}],339:[function(require,module,exports){ /** * @fileoverview Rule to check multiple var declarations per line * @author Alberto Rodríguez */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow newlines around variable declarations", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/one-var-declaration-per-line" }, schema: [{ enum: ["always", "initializations"] }], fixable: "whitespace" }, create: function create(context) { var ERROR_MESSAGE = "Expected variable declaration to be on a new line."; var always = context.options[0] === "always"; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Determine if provided keyword is a variant of for specifiers * @private * @param {string} keyword - keyword to test * @returns {boolean} True if `keyword` is a variant of for specifier */ function isForTypeSpecifier(keyword) { return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; } /** * Checks newlines around variable declarations. * @private * @param {ASTNode} node - `VariableDeclaration` node to test * @returns {void} */ function checkForNewLine(node) { if (isForTypeSpecifier(node.parent.type)) { return; } var declarations = node.declarations; var prev = void 0; declarations.forEach(function (current) { if (prev && prev.loc.end.line === current.loc.start.line) { if (always || prev.init || current.init) { context.report({ node: node, message: ERROR_MESSAGE, loc: current.loc.start, fix: function fix(fixer) { return fixer.insertTextBefore(current, "\n"); } }); } } prev = current; }); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { VariableDeclaration: checkForNewLine }; } }; },{}],340:[function(require,module,exports){ /** * @fileoverview A rule to control the use of single variable declarations. * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; module.exports = { meta: { type: "suggestion", docs: { description: "enforce variables to be declared either together or separately in functions", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/one-var" }, fixable: "code", schema: [{ oneOf: [{ enum: ["always", "never", "consecutive"] }, { type: "object", properties: { separateRequires: { type: "boolean" }, var: { enum: ["always", "never", "consecutive"] }, let: { enum: ["always", "never", "consecutive"] }, const: { enum: ["always", "never", "consecutive"] } }, additionalProperties: false }, { type: "object", properties: { initialized: { enum: ["always", "never", "consecutive"] }, uninitialized: { enum: ["always", "never", "consecutive"] } }, additionalProperties: false }] }] }, create: function create(context) { var MODE_ALWAYS = "always"; var MODE_NEVER = "never"; var MODE_CONSECUTIVE = "consecutive"; var mode = context.options[0] || MODE_ALWAYS; var options = {}; if (typeof mode === "string") { // simple options configuration with just a string options.var = { uninitialized: mode, initialized: mode }; options.let = { uninitialized: mode, initialized: mode }; options.const = { uninitialized: mode, initialized: mode }; } else if ((typeof mode === "undefined" ? "undefined" : _typeof(mode)) === "object") { // options configuration is an object if (Object.prototype.hasOwnProperty.call(mode, "separateRequires")) { options.separateRequires = !!mode.separateRequires; } if (Object.prototype.hasOwnProperty.call(mode, "var")) { options.var = { uninitialized: mode.var, initialized: mode.var }; } if (Object.prototype.hasOwnProperty.call(mode, "let")) { options.let = { uninitialized: mode.let, initialized: mode.let }; } if (Object.prototype.hasOwnProperty.call(mode, "const")) { options.const = { uninitialized: mode.const, initialized: mode.const }; } if (Object.prototype.hasOwnProperty.call(mode, "uninitialized")) { if (!options.var) { options.var = {}; } if (!options.let) { options.let = {}; } if (!options.const) { options.const = {}; } options.var.uninitialized = mode.uninitialized; options.let.uninitialized = mode.uninitialized; options.const.uninitialized = mode.uninitialized; } if (Object.prototype.hasOwnProperty.call(mode, "initialized")) { if (!options.var) { options.var = {}; } if (!options.let) { options.let = {}; } if (!options.const) { options.const = {}; } options.var.initialized = mode.initialized; options.let.initialized = mode.initialized; options.const.initialized = mode.initialized; } } var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var functionStack = []; var blockStack = []; /** * Increments the blockStack counter. * @returns {void} * @private */ function startBlock() { blockStack.push({ let: { initialized: false, uninitialized: false }, const: { initialized: false, uninitialized: false } }); } /** * Increments the functionStack counter. * @returns {void} * @private */ function startFunction() { functionStack.push({ initialized: false, uninitialized: false }); startBlock(); } /** * Decrements the blockStack counter. * @returns {void} * @private */ function endBlock() { blockStack.pop(); } /** * Decrements the functionStack counter. * @returns {void} * @private */ function endFunction() { functionStack.pop(); endBlock(); } /** * Check if a variable declaration is a require. * @param {ASTNode} decl variable declaration Node * @returns {bool} if decl is a require, return true; else return false. * @private */ function isRequire(decl) { return decl.init && decl.init.type === "CallExpression" && decl.init.callee.name === "require"; } /** * Records whether initialized/uninitialized/required variables are defined in current scope. * @param {string} statementType node.kind, one of: "var", "let", or "const" * @param {ASTNode[]} declarations List of declarations * @param {Object} currentScope The scope being investigated * @returns {void} * @private */ function recordTypes(statementType, declarations, currentScope) { for (var i = 0; i < declarations.length; i++) { if (declarations[i].init === null) { if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) { currentScope.uninitialized = true; } } else { if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) { if (options.separateRequires && isRequire(declarations[i])) { currentScope.required = true; } else { currentScope.initialized = true; } } } } } /** * Determines the current scope (function or block) * @param {string} statementType node.kind, one of: "var", "let", or "const" * @returns {Object} The scope associated with statementType */ function getCurrentScope(statementType) { var currentScope = void 0; if (statementType === "var") { currentScope = functionStack[functionStack.length - 1]; } else if (statementType === "let") { currentScope = blockStack[blockStack.length - 1].let; } else if (statementType === "const") { currentScope = blockStack[blockStack.length - 1].const; } return currentScope; } /** * Counts the number of initialized and uninitialized declarations in a list of declarations * @param {ASTNode[]} declarations List of declarations * @returns {Object} Counts of 'uninitialized' and 'initialized' declarations * @private */ function countDeclarations(declarations) { var counts = { uninitialized: 0, initialized: 0 }; for (var i = 0; i < declarations.length; i++) { if (declarations[i].init === null) { counts.uninitialized++; } else { counts.initialized++; } } return counts; } /** * Determines if there is more than one var statement in the current scope. * @param {string} statementType node.kind, one of: "var", "let", or "const" * @param {ASTNode[]} declarations List of declarations * @returns {boolean} Returns true if it is the first var declaration, false if not. * @private */ function hasOnlyOneStatement(statementType, declarations) { var declarationCounts = countDeclarations(declarations); var currentOptions = options[statementType] || {}; var currentScope = getCurrentScope(statementType); var hasRequires = declarations.some(isRequire); if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) { if (currentScope.uninitialized || currentScope.initialized) { return false; } } if (declarationCounts.uninitialized > 0) { if (currentOptions.uninitialized === MODE_ALWAYS && currentScope.uninitialized) { return false; } } if (declarationCounts.initialized > 0) { if (currentOptions.initialized === MODE_ALWAYS && currentScope.initialized) { return false; } } if (currentScope.required && hasRequires) { return false; } recordTypes(statementType, declarations, currentScope); return true; } /** * Fixer to join VariableDeclaration's into a single declaration * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join * @returns {Function} The fixer function */ function joinDeclarations(declarations) { var declaration = declarations[0]; var body = Array.isArray(declaration.parent.parent.body) ? declaration.parent.parent.body : []; var currentIndex = body.findIndex(function (node) { return node.range[0] === declaration.parent.range[0]; }); var previousNode = body[currentIndex - 1]; return function (fixer) { var type = sourceCode.getTokenBefore(declaration); var prevSemi = sourceCode.getTokenBefore(type); var res = []; if (previousNode && previousNode.kind === sourceCode.getText(type)) { if (prevSemi.value === ";") { res.push(fixer.replaceText(prevSemi, ",")); } else { res.push(fixer.insertTextAfter(prevSemi, ",")); } res.push(fixer.replaceText(type, "")); } return res; }; } /** * Fixer to split a VariableDeclaration into individual declarations * @param {VariableDeclaration} declaration The `VariableDeclaration` to split * @returns {Function} The fixer function */ function splitDeclarations(declaration) { return function (fixer) { return declaration.declarations.map(function (declarator) { var tokenAfterDeclarator = sourceCode.getTokenAfter(declarator); if (tokenAfterDeclarator === null) { return null; } var afterComma = sourceCode.getTokenAfter(tokenAfterDeclarator, { includeComments: true }); if (tokenAfterDeclarator.value !== ",") { return null; } /* * `var x,y` * tokenAfterDeclarator ^^ afterComma */ if (afterComma.range[0] === tokenAfterDeclarator.range[1]) { return fixer.replaceText(tokenAfterDeclarator, "; " + declaration.kind + " "); } /* * `var x, * tokenAfterDeclarator ^ * y` * ^ afterComma */ if (afterComma.loc.start.line > tokenAfterDeclarator.loc.end.line || afterComma.type === "Line" || afterComma.type === "Block") { var lastComment = afterComma; while (lastComment.type === "Line" || lastComment.type === "Block") { lastComment = sourceCode.getTokenAfter(lastComment, { includeComments: true }); } return fixer.replaceTextRange([tokenAfterDeclarator.range[0], lastComment.range[0]], ";\n" + sourceCode.text.slice(tokenAfterDeclarator.range[1], lastComment.range[0]) + "\n" + declaration.kind + " "); } return fixer.replaceText(tokenAfterDeclarator, "; " + declaration.kind); }).filter(function (x) { return x; }); }; } /** * Checks a given VariableDeclaration node for errors. * @param {ASTNode} node The VariableDeclaration node to check * @returns {void} * @private */ function checkVariableDeclaration(node) { var parent = node.parent; var type = node.kind; if (!options[type]) { return; } var declarations = node.declarations; var declarationCounts = countDeclarations(declarations); var mixedRequires = declarations.some(isRequire) && !declarations.every(isRequire); if (options[type].initialized === MODE_ALWAYS) { if (options.separateRequires && mixedRequires) { context.report({ node: node, message: "Split requires to be separated into a single block." }); } } // consecutive var nodeIndex = parent.body && parent.body.length > 0 && parent.body.indexOf(node) || 0; if (nodeIndex > 0) { var previousNode = parent.body[nodeIndex - 1]; var isPreviousNodeDeclaration = previousNode.type === "VariableDeclaration"; var declarationsWithPrevious = declarations.concat(previousNode.declarations || []); if (isPreviousNodeDeclaration && previousNode.kind === type && !(declarationsWithPrevious.some(isRequire) && !declarationsWithPrevious.every(isRequire))) { var previousDeclCounts = countDeclarations(previousNode.declarations); if (options[type].initialized === MODE_CONSECUTIVE && options[type].uninitialized === MODE_CONSECUTIVE) { context.report({ node: node, message: "Combine this with the previous '{{type}}' statement.", data: { type: type }, fix: joinDeclarations(declarations) }); } else if (options[type].initialized === MODE_CONSECUTIVE && declarationCounts.initialized > 0 && previousDeclCounts.initialized > 0) { context.report({ node: node, message: "Combine this with the previous '{{type}}' statement with initialized variables.", data: { type: type }, fix: joinDeclarations(declarations) }); } else if (options[type].uninitialized === MODE_CONSECUTIVE && declarationCounts.uninitialized > 0 && previousDeclCounts.uninitialized > 0) { context.report({ node: node, message: "Combine this with the previous '{{type}}' statement with uninitialized variables.", data: { type: type }, fix: joinDeclarations(declarations) }); } } } // always if (!hasOnlyOneStatement(type, declarations)) { if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) { context.report({ node: node, message: "Combine this with the previous '{{type}}' statement.", data: { type: type }, fix: joinDeclarations(declarations) }); } else { if (options[type].initialized === MODE_ALWAYS && declarationCounts.initialized > 0) { context.report({ node: node, message: "Combine this with the previous '{{type}}' statement with initialized variables.", data: { type: type }, fix: joinDeclarations(declarations) }); } if (options[type].uninitialized === MODE_ALWAYS && declarationCounts.uninitialized > 0) { if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) { return; } context.report({ node: node, message: "Combine this with the previous '{{type}}' statement with uninitialized variables.", data: { type: type }, fix: joinDeclarations(declarations) }); } } } // never if (parent.type !== "ForStatement" || parent.init !== node) { var totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; if (totalDeclarations > 1) { if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) { // both initialized and uninitialized context.report({ node: node, message: "Split '{{type}}' declarations into multiple statements.", data: { type: type }, fix: splitDeclarations(node) }); } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) { // initialized context.report({ node: node, message: "Split initialized '{{type}}' declarations into multiple statements.", data: { type: type }, fix: splitDeclarations(node) }); } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) { // uninitialized context.report({ node: node, message: "Split uninitialized '{{type}}' declarations into multiple statements.", data: { type: type }, fix: splitDeclarations(node) }); } } } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { Program: startFunction, FunctionDeclaration: startFunction, FunctionExpression: startFunction, ArrowFunctionExpression: startFunction, BlockStatement: startBlock, ForStatement: startBlock, ForInStatement: startBlock, ForOfStatement: startBlock, SwitchStatement: startBlock, VariableDeclaration: checkVariableDeclaration, "ForStatement:exit": endBlock, "ForOfStatement:exit": endBlock, "ForInStatement:exit": endBlock, "SwitchStatement:exit": endBlock, "BlockStatement:exit": endBlock, "Program:exit": endFunction, "FunctionDeclaration:exit": endFunction, "FunctionExpression:exit": endFunction, "ArrowFunctionExpression:exit": endFunction }; } }; },{}],341:[function(require,module,exports){ /** * @fileoverview Rule to replace assignment expressions with operator assignment * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether an operator is commutative and has an operator assignment * shorthand form. * @param {string} operator Operator to check. * @returns {boolean} True if the operator is commutative and has a * shorthand form. */ function isCommutativeOperatorWithShorthand(operator) { return ["*", "&", "^", "|"].indexOf(operator) >= 0; } /** * Checks whether an operator is not commuatative and has an operator assignment * shorthand form. * @param {string} operator Operator to check. * @returns {boolean} True if the operator is not commuatative and has * a shorthand form. */ function isNonCommutativeOperatorWithShorthand(operator) { return ["+", "-", "/", "%", "<<", ">>", ">>>", "**"].indexOf(operator) >= 0; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** * Checks whether two expressions reference the same value. For example: * a = a * a.b = a.b * a[0] = a[0] * a['b'] = a['b'] * @param {ASTNode} a Left side of the comparison. * @param {ASTNode} b Right side of the comparison. * @returns {boolean} True if both sides match and reference the same value. */ function same(a, b) { if (a.type !== b.type) { return false; } switch (a.type) { case "Identifier": return a.name === b.name; case "Literal": return a.value === b.value; case "MemberExpression": /* * x[0] = x[0] * x[y] = x[y] * x.y = x.y */ return same(a.object, b.object) && same(a.property, b.property); default: return false; } } /** * Determines if the left side of a node can be safely fixed (i.e. if it activates the same getters/setters and) * toString calls regardless of whether assignment shorthand is used) * @param {ASTNode} node The node on the left side of the expression * @returns {boolean} `true` if the node can be fixed */ function canBeFixed(node) { return node.type === "Identifier" || node.type === "MemberExpression" && node.object.type === "Identifier" && (!node.computed || node.property.type === "Literal"); } module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow assignment operator shorthand where possible", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/operator-assignment" }, schema: [{ enum: ["always", "never"] }], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); /** * Returns the operator token of an AssignmentExpression or BinaryExpression * @param {ASTNode} node An AssignmentExpression or BinaryExpression node * @returns {Token} The operator token in the node */ function getOperatorToken(node) { return sourceCode.getFirstTokenBetween(node.left, node.right, function (token) { return token.value === node.operator; }); } /** * Ensures that an assignment uses the shorthand form where possible. * @param {ASTNode} node An AssignmentExpression node. * @returns {void} */ function verify(node) { if (node.operator !== "=" || node.right.type !== "BinaryExpression") { return; } var left = node.left; var expr = node.right; var operator = expr.operator; if (isCommutativeOperatorWithShorthand(operator) || isNonCommutativeOperatorWithShorthand(operator)) { if (same(left, expr.left)) { context.report({ node: node, message: "Assignment can be replaced with operator assignment.", fix: function fix(fixer) { if (canBeFixed(left)) { var equalsToken = getOperatorToken(node); var operatorToken = getOperatorToken(expr); var leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]); var rightText = sourceCode.getText().slice(operatorToken.range[1], node.right.range[1]); return fixer.replaceText(node, "" + leftText + expr.operator + "=" + rightText); } return null; } }); } else if (same(left, expr.right) && isCommutativeOperatorWithShorthand(operator)) { /* * This case can't be fixed safely. * If `a` and `b` both have custom valueOf() behavior, then fixing `a = b * a` to `a *= b` would * change the execution order of the valueOf() functions. */ context.report({ node: node, message: "Assignment can be replaced with operator assignment." }); } } } /** * Warns if an assignment expression uses operator assignment shorthand. * @param {ASTNode} node An AssignmentExpression node. * @returns {void} */ function prohibit(node) { if (node.operator !== "=") { context.report({ node: node, message: "Unexpected operator assignment shorthand.", fix: function fix(fixer) { if (canBeFixed(node.left)) { var operatorToken = getOperatorToken(node); var leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]); var newOperator = node.operator.slice(0, -1); var rightText = void 0; // If this change would modify precedence (e.g. `foo *= bar + 1` => `foo = foo * (bar + 1)`), parenthesize the right side. if (astUtils.getPrecedence(node.right) <= astUtils.getPrecedence({ type: "BinaryExpression", operator: newOperator }) && !astUtils.isParenthesised(sourceCode, node.right)) { rightText = sourceCode.text.slice(operatorToken.range[1], node.right.range[0]) + "(" + sourceCode.getText(node.right) + ")"; } else { rightText = sourceCode.text.slice(operatorToken.range[1], node.range[1]); } return fixer.replaceText(node, leftText + "= " + leftText + newOperator + rightText); } return null; } }); } } return { AssignmentExpression: context.options[0] !== "never" ? verify : prohibit }; } }; },{"../util/ast-utils":405}],342:[function(require,module,exports){ /** * @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before * @author Benoît Zugmeyer */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent linebreak style for operators", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/operator-linebreak" }, schema: [{ enum: ["after", "before", "none", null] }, { type: "object", properties: { overrides: { type: "object", properties: { anyOf: { type: "string", enum: ["after", "before", "none", "ignore"] } } } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { var usedDefaultGlobal = !context.options[0]; var globalStyle = context.options[0] || "after"; var options = context.options[1] || {}; var styleOverrides = options.overrides ? Object.assign({}, options.overrides) : {}; if (usedDefaultGlobal && !styleOverrides["?"]) { styleOverrides["?"] = "before"; } if (usedDefaultGlobal && !styleOverrides[":"]) { styleOverrides[":"] = "before"; } var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Gets a fixer function to fix rule issues * @param {Token} operatorToken The operator token of an expression * @param {string} desiredStyle The style for the rule. One of 'before', 'after', 'none' * @returns {Function} A fixer function */ function getFixer(operatorToken, desiredStyle) { return function (fixer) { var tokenBefore = sourceCode.getTokenBefore(operatorToken); var tokenAfter = sourceCode.getTokenAfter(operatorToken); var textBefore = sourceCode.text.slice(tokenBefore.range[1], operatorToken.range[0]); var textAfter = sourceCode.text.slice(operatorToken.range[1], tokenAfter.range[0]); var hasLinebreakBefore = !astUtils.isTokenOnSameLine(tokenBefore, operatorToken); var hasLinebreakAfter = !astUtils.isTokenOnSameLine(operatorToken, tokenAfter); var newTextBefore = void 0, newTextAfter = void 0; if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") { // If there is a comment before and after the operator, don't do a fix. if (sourceCode.getTokenBefore(operatorToken, { includeComments: true }) !== tokenBefore && sourceCode.getTokenAfter(operatorToken, { includeComments: true }) !== tokenAfter) { return null; } /* * If there is only one linebreak and it's on the wrong side of the operator, swap the text before and after the operator. * foo && * bar * would get fixed to * foo * && bar */ newTextBefore = textAfter; newTextAfter = textBefore; } else { var LINEBREAK_REGEX = astUtils.createGlobalLinebreakMatcher(); // Otherwise, if no linebreak is desired and no comments interfere, replace the linebreaks with empty strings. newTextBefore = desiredStyle === "before" || textBefore.trim() ? textBefore : textBefore.replace(LINEBREAK_REGEX, ""); newTextAfter = desiredStyle === "after" || textAfter.trim() ? textAfter : textAfter.replace(LINEBREAK_REGEX, ""); // If there was no change (due to interfering comments), don't output a fix. if (newTextBefore === textBefore && newTextAfter === textAfter) { return null; } } if (newTextAfter === "" && tokenAfter.type === "Punctuator" && "+-".includes(operatorToken.value) && tokenAfter.value === operatorToken.value) { // To avoid accidentally creating a ++ or -- operator, insert a space if the operator is a +/- and the following token is a unary +/-. newTextAfter += " "; } return fixer.replaceTextRange([tokenBefore.range[1], tokenAfter.range[0]], newTextBefore + operatorToken.value + newTextAfter); }; } /** * Checks the operator placement * @param {ASTNode} node The node to check * @param {ASTNode} leftSide The node that comes before the operator in `node` * @private * @returns {void} */ function validateNode(node, leftSide) { /* * When the left part of a binary expression is a single expression wrapped in * parentheses (ex: `(a) + b`), leftToken will be the last token of the expression * and operatorToken will be the closing parenthesis. * The leftToken should be the last closing parenthesis, and the operatorToken * should be the token right after that. */ var operatorToken = sourceCode.getTokenAfter(leftSide, astUtils.isNotClosingParenToken); var leftToken = sourceCode.getTokenBefore(operatorToken); var rightToken = sourceCode.getTokenAfter(operatorToken); var operator = operatorToken.value; var operatorStyleOverride = styleOverrides[operator]; var style = operatorStyleOverride || globalStyle; var fix = getFixer(operatorToken, style); // if single line if (astUtils.isTokenOnSameLine(leftToken, operatorToken) && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { // do nothing. } else if (operatorStyleOverride !== "ignore" && !astUtils.isTokenOnSameLine(leftToken, operatorToken) && !astUtils.isTokenOnSameLine(operatorToken, rightToken)) { // lone operator context.report({ node: node, loc: { line: operatorToken.loc.end.line, column: operatorToken.loc.end.column }, message: "Bad line breaking before and after '{{operator}}'.", data: { operator: operator }, fix: fix }); } else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) { context.report({ node: node, loc: { line: operatorToken.loc.end.line, column: operatorToken.loc.end.column }, message: "'{{operator}}' should be placed at the beginning of the line.", data: { operator: operator }, fix: fix }); } else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { context.report({ node: node, loc: { line: operatorToken.loc.end.line, column: operatorToken.loc.end.column }, message: "'{{operator}}' should be placed at the end of the line.", data: { operator: operator }, fix: fix }); } else if (style === "none") { context.report({ node: node, loc: { line: operatorToken.loc.end.line, column: operatorToken.loc.end.column }, message: "There should be no line break before or after '{{operator}}'.", data: { operator: operator }, fix: fix }); } } /** * Validates a binary expression using `validateNode` * @param {BinaryExpression|LogicalExpression|AssignmentExpression} node node to be validated * @returns {void} */ function validateBinaryExpression(node) { validateNode(node, node.left); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { BinaryExpression: validateBinaryExpression, LogicalExpression: validateBinaryExpression, AssignmentExpression: validateBinaryExpression, VariableDeclarator: function VariableDeclarator(node) { if (node.init) { validateNode(node, node.id); } }, ConditionalExpression: function ConditionalExpression(node) { validateNode(node, node.test); validateNode(node, node.consequent); } }; } }; },{"../util/ast-utils":405}],343:[function(require,module,exports){ /** * @fileoverview A rule to ensure blank lines within blocks. * @author Mathias Schreck */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow padding within blocks", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/padded-blocks" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["always", "never"] }, { type: "object", properties: { blocks: { enum: ["always", "never"] }, switches: { enum: ["always", "never"] }, classes: { enum: ["always", "never"] } }, additionalProperties: false, minProperties: 1 }] }] }, create: function create(context) { var options = {}; var config = context.options[0] || "always"; if (typeof config === "string") { var shouldHavePadding = config === "always"; options.blocks = shouldHavePadding; options.switches = shouldHavePadding; options.classes = shouldHavePadding; } else { if (Object.prototype.hasOwnProperty.call(config, "blocks")) { options.blocks = config.blocks === "always"; } if (Object.prototype.hasOwnProperty.call(config, "switches")) { options.switches = config.switches === "always"; } if (Object.prototype.hasOwnProperty.call(config, "classes")) { options.classes = config.classes === "always"; } } var ALWAYS_MESSAGE = "Block must be padded by blank lines.", NEVER_MESSAGE = "Block must not be padded by blank lines."; var sourceCode = context.getSourceCode(); /** * Gets the open brace token from a given node. * @param {ASTNode} node - A BlockStatement or SwitchStatement node from which to get the open brace. * @returns {Token} The token of the open brace. */ function getOpenBrace(node) { if (node.type === "SwitchStatement") { return sourceCode.getTokenBefore(node.cases[0]); } return sourceCode.getFirstToken(node); } /** * Checks if the given parameter is a comment node * @param {ASTNode|Token} node An AST node or token * @returns {boolean} True if node is a comment */ function isComment(node) { return node.type === "Line" || node.type === "Block"; } /** * Checks if there is padding between two tokens * @param {Token} first The first token * @param {Token} second The second token * @returns {boolean} True if there is at least a line between the tokens */ function isPaddingBetweenTokens(first, second) { return second.loc.start.line - first.loc.end.line >= 2; } /** * Checks if the given token has a blank line after it. * @param {Token} token The token to check. * @returns {boolean} Whether or not the token is followed by a blank line. */ function getFirstBlockToken(token) { var prev = void 0, first = token; do { prev = first; first = sourceCode.getTokenAfter(first, { includeComments: true }); } while (isComment(first) && first.loc.start.line === prev.loc.end.line); return first; } /** * Checks if the given token is preceeded by a blank line. * @param {Token} token The token to check * @returns {boolean} Whether or not the token is preceeded by a blank line */ function getLastBlockToken(token) { var last = token, next = void 0; do { next = last; last = sourceCode.getTokenBefore(last, { includeComments: true }); } while (isComment(last) && last.loc.end.line === next.loc.start.line); return last; } /** * Checks if a node should be padded, according to the rule config. * @param {ASTNode} node The AST node to check. * @returns {boolean} True if the node should be padded, false otherwise. */ function requirePaddingFor(node) { switch (node.type) { case "BlockStatement": return options.blocks; case "SwitchStatement": return options.switches; case "ClassBody": return options.classes; /* istanbul ignore next */ default: throw new Error("unreachable"); } } /** * Checks the given BlockStatement node to be padded if the block is not empty. * @param {ASTNode} node The AST node of a BlockStatement. * @returns {void} undefined. */ function checkPadding(node) { var openBrace = getOpenBrace(node), firstBlockToken = getFirstBlockToken(openBrace), tokenBeforeFirst = sourceCode.getTokenBefore(firstBlockToken, { includeComments: true }), closeBrace = sourceCode.getLastToken(node), lastBlockToken = getLastBlockToken(closeBrace), tokenAfterLast = sourceCode.getTokenAfter(lastBlockToken, { includeComments: true }), blockHasTopPadding = isPaddingBetweenTokens(tokenBeforeFirst, firstBlockToken), blockHasBottomPadding = isPaddingBetweenTokens(lastBlockToken, tokenAfterLast); if (requirePaddingFor(node)) { if (!blockHasTopPadding) { context.report({ node: node, loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column }, fix: function fix(fixer) { return fixer.insertTextAfter(tokenBeforeFirst, "\n"); }, message: ALWAYS_MESSAGE }); } if (!blockHasBottomPadding) { context.report({ node: node, loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 }, fix: function fix(fixer) { return fixer.insertTextBefore(tokenAfterLast, "\n"); }, message: ALWAYS_MESSAGE }); } } else { if (blockHasTopPadding) { context.report({ node: node, loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column }, fix: function fix(fixer) { return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n"); }, message: NEVER_MESSAGE }); } if (blockHasBottomPadding) { context.report({ node: node, loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 }, message: NEVER_MESSAGE, fix: function fix(fixer) { return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n"); } }); } } } var rule = {}; if (Object.prototype.hasOwnProperty.call(options, "switches")) { rule.SwitchStatement = function (node) { if (node.cases.length === 0) { return; } checkPadding(node); }; } if (Object.prototype.hasOwnProperty.call(options, "blocks")) { rule.BlockStatement = function (node) { if (node.body.length === 0) { return; } checkPadding(node); }; } if (Object.prototype.hasOwnProperty.call(options, "classes")) { rule.ClassBody = function (node) { if (node.body.length === 0) { return; } checkPadding(node); }; } return rule; } }; },{}],344:[function(require,module,exports){ /** * @fileoverview Rule to require or disallow newlines between statements * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _templateObject = _taggedTemplateLiteral(["^(s*?", ")s*", "(s*;?)$"], ["^(\\s*?", ")\\s*", "(\\s*;?)$"]); function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var LT = "[" + Array.from(astUtils.LINEBREAKS).join("") + "]"; var PADDING_LINE_SEQUENCE = new RegExp(String.raw(_templateObject, LT, LT)); var CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/; var CJS_IMPORT = /^require\(/; /** * Creates tester which check if a node starts with specific keyword. * * @param {string} keyword The keyword to test. * @returns {Object} the created tester. * @private */ function newKeywordTester(keyword) { return { test: function test(node, sourceCode) { return sourceCode.getFirstToken(node).value === keyword; } }; } /** * Creates tester which check if a node starts with specific keyword and spans a single line. * * @param {string} keyword The keyword to test. * @returns {Object} the created tester. * @private */ function newSinglelineKeywordTester(keyword) { return { test: function test(node, sourceCode) { return node.loc.start.line === node.loc.end.line && sourceCode.getFirstToken(node).value === keyword; } }; } /** * Creates tester which check if a node starts with specific keyword and spans multiple lines. * * @param {string} keyword The keyword to test. * @returns {Object} the created tester. * @private */ function newMultilineKeywordTester(keyword) { return { test: function test(node, sourceCode) { return node.loc.start.line !== node.loc.end.line && sourceCode.getFirstToken(node).value === keyword; } }; } /** * Creates tester which check if a node is specific type. * * @param {string} type The node type to test. * @returns {Object} the created tester. * @private */ function newNodeTypeTester(type) { return { test: function test(node) { return node.type === type; } }; } /** * Checks the given node is an expression statement of IIFE. * * @param {ASTNode} node The node to check. * @returns {boolean} `true` if the node is an expression statement of IIFE. * @private */ function isIIFEStatement(node) { if (node.type === "ExpressionStatement") { var call = node.expression; if (call.type === "UnaryExpression") { call = call.argument; } return call.type === "CallExpression" && astUtils.isFunction(call.callee); } return false; } /** * Checks whether the given node is a block-like statement. * This checks the last token of the node is the closing brace of a block. * * @param {SourceCode} sourceCode The source code to get tokens. * @param {ASTNode} node The node to check. * @returns {boolean} `true` if the node is a block-like statement. * @private */ function isBlockLikeStatement(sourceCode, node) { // do-while with a block is a block-like statement. if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") { return true; } /* * IIFE is a block-like statement specially from * JSCS#disallowPaddingNewLinesAfterBlocks. */ if (isIIFEStatement(node)) { return true; } // Checks the last token is a closing brace of blocks. var lastToken = sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); var belongingNode = lastToken && astUtils.isClosingBraceToken(lastToken) ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) : null; return Boolean(belongingNode) && (belongingNode.type === "BlockStatement" || belongingNode.type === "SwitchStatement"); } /** * Check whether the given node is a directive or not. * @param {ASTNode} node The node to check. * @param {SourceCode} sourceCode The source code object to get tokens. * @returns {boolean} `true` if the node is a directive. */ function isDirective(node, sourceCode) { return node.type === "ExpressionStatement" && (node.parent.type === "Program" || node.parent.type === "BlockStatement" && astUtils.isFunction(node.parent.parent)) && node.expression.type === "Literal" && typeof node.expression.value === "string" && !astUtils.isParenthesised(sourceCode, node.expression); } /** * Check whether the given node is a part of directive prologue or not. * @param {ASTNode} node The node to check. * @param {SourceCode} sourceCode The source code object to get tokens. * @returns {boolean} `true` if the node is a part of directive prologue. */ function isDirectivePrologue(node, sourceCode) { if (isDirective(node, sourceCode)) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = node.parent.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var sibling = _step.value; if (sibling === node) { break; } if (!isDirective(sibling, sourceCode)) { return false; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return true; } return false; } /** * Gets the actual last token. * * If a semicolon is semicolon-less style's semicolon, this ignores it. * For example: * * foo() * ;[1, 2, 3].forEach(bar) * * @param {SourceCode} sourceCode The source code to get tokens. * @param {ASTNode} node The node to get. * @returns {Token} The actual last token. * @private */ function getActualLastToken(sourceCode, node) { var semiToken = sourceCode.getLastToken(node); var prevToken = sourceCode.getTokenBefore(semiToken); var nextToken = sourceCode.getTokenAfter(semiToken); var isSemicolonLessStyle = Boolean(prevToken && nextToken && prevToken.range[0] >= node.range[0] && astUtils.isSemicolonToken(semiToken) && semiToken.loc.start.line !== prevToken.loc.end.line && semiToken.loc.end.line === nextToken.loc.start.line); return isSemicolonLessStyle ? prevToken : semiToken; } /** * This returns the concatenation of the first 2 captured strings. * @param {string} _ Unused. Whole matched string. * @param {string} trailingSpaces The trailing spaces of the first line. * @param {string} indentSpaces The indentation spaces of the last line. * @returns {string} The concatenation of trailingSpaces and indentSpaces. * @private */ function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) { return trailingSpaces + indentSpaces; } /** * Check and report statements for `any` configuration. * It does nothing. * * @returns {void} * @private */ function verifyForAny() {} /** * Check and report statements for `never` configuration. * This autofix removes blank lines between the given 2 statements. * However, if comments exist between 2 blank lines, it does not remove those * blank lines automatically. * * @param {RuleContext} context The rule context to report. * @param {ASTNode} _ Unused. The previous node to check. * @param {ASTNode} nextNode The next node to check. * @param {Array} paddingLines The array of token pairs that blank * lines exist between the pair. * @returns {void} * @private */ function verifyForNever(context, _, nextNode, paddingLines) { if (paddingLines.length === 0) { return; } context.report({ node: nextNode, message: "Unexpected blank line before this statement.", fix: function fix(fixer) { if (paddingLines.length >= 2) { return null; } var prevToken = paddingLines[0][0]; var nextToken = paddingLines[0][1]; var start = prevToken.range[1]; var end = nextToken.range[0]; var text = context.getSourceCode().text.slice(start, end).replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines); return fixer.replaceTextRange([start, end], text); } }); } /** * Check and report statements for `always` configuration. * This autofix inserts a blank line between the given 2 statements. * If the `prevNode` has trailing comments, it inserts a blank line after the * trailing comments. * * @param {RuleContext} context The rule context to report. * @param {ASTNode} prevNode The previous node to check. * @param {ASTNode} nextNode The next node to check. * @param {Array} paddingLines The array of token pairs that blank * lines exist between the pair. * @returns {void} * @private */ function verifyForAlways(context, prevNode, nextNode, paddingLines) { if (paddingLines.length > 0) { return; } context.report({ node: nextNode, message: "Expected blank line before this statement.", fix: function fix(fixer) { var sourceCode = context.getSourceCode(); var prevToken = getActualLastToken(sourceCode, prevNode); var nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, { includeComments: true, /** * Skip the trailing comments of the previous node. * This inserts a blank line after the last trailing comment. * * For example: * * foo(); // trailing comment. * // comment. * bar(); * * Get fixed to: * * foo(); // trailing comment. * * // comment. * bar(); * * @param {Token} token The token to check. * @returns {boolean} `true` if the token is not a trailing comment. * @private */ filter: function filter(token) { if (astUtils.isTokenOnSameLine(prevToken, token)) { prevToken = token; return false; } return true; } }) || nextNode; var insertText = astUtils.isTokenOnSameLine(prevToken, nextToken) ? "\n\n" : "\n"; return fixer.insertTextAfter(prevToken, insertText); } }); } /** * Types of blank lines. * `any`, `never`, and `always` are defined. * Those have `verify` method to check and report statements. * @private */ var PaddingTypes = { any: { verify: verifyForAny }, never: { verify: verifyForNever }, always: { verify: verifyForAlways } }; /** * Types of statements. * Those have `test` method to check it matches to the given statement. * @private */ var StatementTypes = { "*": { test: function test() { return true; } }, "block-like": { test: function test(node, sourceCode) { return isBlockLikeStatement(sourceCode, node); } }, "cjs-export": { test: function test(node, sourceCode) { return node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && CJS_EXPORT.test(sourceCode.getText(node.expression.left)); } }, "cjs-import": { test: function test(node, sourceCode) { return node.type === "VariableDeclaration" && node.declarations.length > 0 && Boolean(node.declarations[0].init) && CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init)); } }, directive: { test: isDirectivePrologue }, expression: { test: function test(node, sourceCode) { return node.type === "ExpressionStatement" && !isDirectivePrologue(node, sourceCode); } }, iife: { test: isIIFEStatement }, "multiline-block-like": { test: function test(node, sourceCode) { return node.loc.start.line !== node.loc.end.line && isBlockLikeStatement(sourceCode, node); } }, "multiline-expression": { test: function test(node, sourceCode) { return node.loc.start.line !== node.loc.end.line && node.type === "ExpressionStatement" && !isDirectivePrologue(node, sourceCode); } }, "multiline-const": newMultilineKeywordTester("const"), "multiline-let": newMultilineKeywordTester("let"), "multiline-var": newMultilineKeywordTester("var"), "singleline-const": newSinglelineKeywordTester("const"), "singleline-let": newSinglelineKeywordTester("let"), "singleline-var": newSinglelineKeywordTester("var"), block: newNodeTypeTester("BlockStatement"), empty: newNodeTypeTester("EmptyStatement"), function: newNodeTypeTester("FunctionDeclaration"), break: newKeywordTester("break"), case: newKeywordTester("case"), class: newKeywordTester("class"), const: newKeywordTester("const"), continue: newKeywordTester("continue"), debugger: newKeywordTester("debugger"), default: newKeywordTester("default"), do: newKeywordTester("do"), export: newKeywordTester("export"), for: newKeywordTester("for"), if: newKeywordTester("if"), import: newKeywordTester("import"), let: newKeywordTester("let"), return: newKeywordTester("return"), switch: newKeywordTester("switch"), throw: newKeywordTester("throw"), try: newKeywordTester("try"), var: newKeywordTester("var"), while: newKeywordTester("while"), with: newKeywordTester("with") }; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow padding lines between statements", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/padding-line-between-statements" }, fixable: "whitespace", schema: { definitions: { paddingType: { enum: Object.keys(PaddingTypes) }, statementType: { anyOf: [{ enum: Object.keys(StatementTypes) }, { type: "array", items: { enum: Object.keys(StatementTypes) }, minItems: 1, uniqueItems: true, additionalItems: false }] } }, type: "array", items: { type: "object", properties: { blankLine: { $ref: "#/definitions/paddingType" }, prev: { $ref: "#/definitions/statementType" }, next: { $ref: "#/definitions/statementType" } }, additionalProperties: false, required: ["blankLine", "prev", "next"] }, additionalItems: false } }, create: function create(context) { var sourceCode = context.getSourceCode(); var configureList = context.options || []; var scopeInfo = null; /** * Processes to enter to new scope. * This manages the current previous statement. * @returns {void} * @private */ function enterScope() { scopeInfo = { upper: scopeInfo, prevNode: null }; } /** * Processes to exit from the current scope. * @returns {void} * @private */ function exitScope() { scopeInfo = scopeInfo.upper; } /** * Checks whether the given node matches the given type. * * @param {ASTNode} node The statement node to check. * @param {string|string[]} type The statement type to check. * @returns {boolean} `true` if the statement node matched the type. * @private */ function match(node, type) { var innerStatementNode = node; while (innerStatementNode.type === "LabeledStatement") { innerStatementNode = innerStatementNode.body; } if (Array.isArray(type)) { return type.some(match.bind(null, innerStatementNode)); } return StatementTypes[type].test(innerStatementNode, sourceCode); } /** * Finds the last matched configure from configureList. * * @param {ASTNode} prevNode The previous statement to match. * @param {ASTNode} nextNode The current statement to match. * @returns {Object} The tester of the last matched configure. * @private */ function getPaddingType(prevNode, nextNode) { for (var i = configureList.length - 1; i >= 0; --i) { var configure = configureList[i]; var matched = match(prevNode, configure.prev) && match(nextNode, configure.next); if (matched) { return PaddingTypes[configure.blankLine]; } } return PaddingTypes.any; } /** * Gets padding line sequences between the given 2 statements. * Comments are separators of the padding line sequences. * * @param {ASTNode} prevNode The previous statement to count. * @param {ASTNode} nextNode The current statement to count. * @returns {Array} The array of token pairs. * @private */ function getPaddingLineSequences(prevNode, nextNode) { var pairs = []; var prevToken = getActualLastToken(sourceCode, prevNode); if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) { do { var token = sourceCode.getTokenAfter(prevToken, { includeComments: true }); if (token.loc.start.line - prevToken.loc.end.line >= 2) { pairs.push([prevToken, token]); } prevToken = token; } while (prevToken.range[0] < nextNode.range[0]); } return pairs; } /** * Verify padding lines between the given node and the previous node. * * @param {ASTNode} node The node to verify. * @returns {void} * @private */ function verify(node) { var parentType = node.parent.type; var validParent = astUtils.STATEMENT_LIST_PARENTS.has(parentType) || parentType === "SwitchStatement"; if (!validParent) { return; } // Save this node as the current previous statement. var prevNode = scopeInfo.prevNode; // Verify. if (prevNode) { var type = getPaddingType(prevNode, node); var paddingLines = getPaddingLineSequences(prevNode, node); type.verify(context, prevNode, node, paddingLines); } scopeInfo.prevNode = node; } /** * Verify padding lines between the given node and the previous node. * Then process to enter to new scope. * * @param {ASTNode} node The node to verify. * @returns {void} * @private */ function verifyThenEnterScope(node) { verify(node); enterScope(); } return { Program: enterScope, BlockStatement: enterScope, SwitchStatement: enterScope, "Program:exit": exitScope, "BlockStatement:exit": exitScope, "SwitchStatement:exit": exitScope, ":statement": verify, SwitchCase: verifyThenEnterScope, "SwitchCase:exit": exitScope }; } }; },{"../util/ast-utils":405}],345:[function(require,module,exports){ /** * @fileoverview A rule to suggest using arrow functions as callbacks. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given variable is a function name. * @param {eslint-scope.Variable} variable - A variable to check. * @returns {boolean} `true` if the variable is a function name. */ function isFunctionName(variable) { return variable && variable.defs[0].type === "FunctionName"; } /** * Checks whether or not a given MetaProperty node equals to a given value. * @param {ASTNode} node - A MetaProperty node to check. * @param {string} metaName - The name of `MetaProperty.meta`. * @param {string} propertyName - The name of `MetaProperty.property`. * @returns {boolean} `true` if the node is the specific value. */ function checkMetaProperty(node, metaName, propertyName) { return node.meta.name === metaName && node.property.name === propertyName; } /** * Gets the variable object of `arguments` which is defined implicitly. * @param {eslint-scope.Scope} scope - A scope to get. * @returns {eslint-scope.Variable} The found variable object. */ function getVariableOfArguments(scope) { var variables = scope.variables; for (var i = 0; i < variables.length; ++i) { var variable = variables[i]; if (variable.name === "arguments") { /* * If there was a parameter which is named "arguments", the * implicit "arguments" is not defined. * So does fast return with null. */ return variable.identifiers.length === 0 ? variable : null; } } /* istanbul ignore next */ return null; } /** * Checkes whether or not a given node is a callback. * @param {ASTNode} node - A node to check. * @returns {Object} * {boolean} retv.isCallback - `true` if the node is a callback. * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. */ function getCallbackInfo(node) { var retv = { isCallback: false, isLexicalThis: false }; var currentNode = node; var parent = node.parent; while (currentNode) { switch (parent.type) { // Checks parents recursively. case "LogicalExpression": case "ConditionalExpression": break; // Checks whether the parent node is `.bind(this)` call. case "MemberExpression": if (parent.object === currentNode && !parent.property.computed && parent.property.type === "Identifier" && parent.property.name === "bind" && parent.parent.type === "CallExpression" && parent.parent.callee === parent) { retv.isLexicalThis = parent.parent.arguments.length === 1 && parent.parent.arguments[0].type === "ThisExpression"; parent = parent.parent; } else { return retv; } break; // Checks whether the node is a callback. case "CallExpression": case "NewExpression": if (parent.callee !== currentNode) { retv.isCallback = true; } return retv; default: return retv; } currentNode = parent; parent = parent.parent; } /* istanbul ignore next */ throw new Error("unreachable"); } /** * Checks whether a simple list of parameters contains any duplicates. This does not handle complex * parameter lists (e.g. with destructuring), since complex parameter lists are a SyntaxError with duplicate * parameter names anyway. Instead, it always returns `false` for complex parameter lists. * @param {ASTNode[]} paramsList The list of parameters for a function * @returns {boolean} `true` if the list of parameters contains any duplicates */ function hasDuplicateParams(paramsList) { return paramsList.every(function (param) { return param.type === "Identifier"; }) && paramsList.length !== new Set(paramsList.map(function (param) { return param.name; })).size; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require using arrow functions for callbacks", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-arrow-callback" }, schema: [{ type: "object", properties: { allowNamedFunctions: { type: "boolean" }, allowUnboundThis: { type: "boolean" } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { var options = context.options[0] || {}; var allowUnboundThis = options.allowUnboundThis !== false; // default to true var allowNamedFunctions = options.allowNamedFunctions; var sourceCode = context.getSourceCode(); /* * {Array<{this: boolean, super: boolean, meta: boolean}>} * - this - A flag which shows there are one or more ThisExpression. * - super - A flag which shows there are one or more Super. * - meta - A flag which shows there are one or more MethProperty. */ var stack = []; /** * Pushes new function scope with all `false` flags. * @returns {void} */ function enterScope() { stack.push({ this: false, super: false, meta: false }); } /** * Pops a function scope from the stack. * @returns {{this: boolean, super: boolean, meta: boolean}} The information of the last scope. */ function exitScope() { return stack.pop(); } return { // Reset internal state. Program: function Program() { stack = []; }, // If there are below, it cannot replace with arrow functions merely. ThisExpression: function ThisExpression() { var info = stack[stack.length - 1]; if (info) { info.this = true; } }, Super: function Super() { var info = stack[stack.length - 1]; if (info) { info.super = true; } }, MetaProperty: function MetaProperty(node) { var info = stack[stack.length - 1]; if (info && checkMetaProperty(node, "new", "target")) { info.meta = true; } }, // To skip nested scopes. FunctionDeclaration: enterScope, "FunctionDeclaration:exit": exitScope, // Main. FunctionExpression: enterScope, "FunctionExpression:exit": function FunctionExpressionExit(node) { var scopeInfo = exitScope(); // Skip named function expressions if (allowNamedFunctions && node.id && node.id.name) { return; } // Skip generators. if (node.generator) { return; } // Skip recursive functions. var nameVar = context.getDeclaredVariables(node)[0]; if (isFunctionName(nameVar) && nameVar.references.length > 0) { return; } // Skip if it's using arguments. var variable = getVariableOfArguments(context.getScope()); if (variable && variable.references.length > 0) { return; } // Reports if it's a callback which can replace with arrows. var callbackInfo = getCallbackInfo(node); if (callbackInfo.isCallback && (!allowUnboundThis || !scopeInfo.this || callbackInfo.isLexicalThis) && !scopeInfo.super && !scopeInfo.meta) { context.report({ node: node, message: "Unexpected function expression.", fix: function fix(fixer) { if (!callbackInfo.isLexicalThis && scopeInfo.this || hasDuplicateParams(node.params)) { /* * If the callback function does not have .bind(this) and contains a reference to `this`, there * is no way to determine what `this` should be, so don't perform any fixes. * If the callback function has duplicates in its list of parameters (possible in sloppy mode), * don't replace it with an arrow function, because this is a SyntaxError with arrow functions. */ return null; } var paramsLeftParen = node.params.length ? sourceCode.getTokenBefore(node.params[0]) : sourceCode.getTokenBefore(node.body, 1); var paramsRightParen = sourceCode.getTokenBefore(node.body); var asyncKeyword = node.async ? "async " : ""; var paramsFullText = sourceCode.text.slice(paramsLeftParen.range[0], paramsRightParen.range[1]); var arrowFunctionText = "" + asyncKeyword + paramsFullText + " => " + sourceCode.getText(node.body); /* * If the callback function has `.bind(this)`, replace it with an arrow function and remove the binding. * Otherwise, just replace the arrow function itself. */ var replacedNode = callbackInfo.isLexicalThis ? node.parent.parent : node; /* * If the replaced node is part of a BinaryExpression, LogicalExpression, or MemberExpression, then * the arrow function needs to be parenthesized, because `foo || () => {}` is invalid syntax even * though `foo || function() {}` is valid. */ var needsParens = replacedNode.parent.type !== "CallExpression" && replacedNode.parent.type !== "ConditionalExpression"; var replacementText = needsParens ? "(" + arrowFunctionText + ")" : arrowFunctionText; return fixer.replaceText(replacedNode, replacementText); } }); } } }; } }; },{}],346:[function(require,module,exports){ /** * @fileoverview A rule to suggest using of const declaration for variables that are never reassigned after declared. * @author Toru Nagashima */ "use strict"; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/; var DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/; var DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/; /** * Checks whether a given node is located at `ForStatement.init` or not. * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is located at `ForStatement.init`. */ function isInitOfForStatement(node) { return node.parent.type === "ForStatement" && node.parent.init === node; } /** * Checks whether a given Identifier node becomes a VariableDeclaration or not. * * @param {ASTNode} identifier - An Identifier node to check. * @returns {boolean} `true` if the node can become a VariableDeclaration. */ function canBecomeVariableDeclaration(identifier) { var node = identifier.parent; while (PATTERN_TYPE.test(node.type)) { node = node.parent; } return node.type === "VariableDeclarator" || node.type === "AssignmentExpression" && node.parent.type === "ExpressionStatement" && DECLARATION_HOST_TYPE.test(node.parent.parent.type); } /** * Checks if an property or element is from outer scope or function parameters * in destructing pattern. * * @param {string} name - A variable name to be checked. * @param {eslint-scope.Scope} initScope - A scope to start find. * @returns {boolean} Indicates if the variable is from outer scope or function parameters. */ function isOuterVariableInDestructing(name, initScope) { if (initScope.through.find(function (ref) { return ref.resolved && ref.resolved.name === name; })) { return true; } var variable = astUtils.getVariableByName(initScope, name); if (variable !== null) { return variable.defs.some(function (def) { return def.type === "Parameter"; }); } return false; } /** * Gets the VariableDeclarator/AssignmentExpression node that a given reference * belongs to. * This is used to detect a mix of reassigned and never reassigned in a * destructuring. * * @param {eslint-scope.Reference} reference - A reference to get. * @returns {ASTNode|null} A VariableDeclarator/AssignmentExpression node or * null. */ function getDestructuringHost(reference) { if (!reference.isWrite()) { return null; } var node = reference.identifier.parent; while (PATTERN_TYPE.test(node.type)) { node = node.parent; } if (!DESTRUCTURING_HOST_TYPE.test(node.type)) { return null; } return node; } /** * Determines if a destructuring assignment node contains * any MemberExpression nodes. This is used to determine if a * variable that is only written once using destructuring can be * safely converted into a const declaration. * @param {ASTNode} node The ObjectPattern or ArrayPattern node to check. * @returns {boolean} True if the destructuring pattern contains * a MemberExpression, false if not. */ function hasMemberExpressionAssignment(node) { switch (node.type) { case "ObjectPattern": return node.properties.some(function (prop) { if (prop) { /* * Spread elements have an argument property while * others have a value property. Because different * parsers use different node types for spread elements, * we just check if there is an argument property. */ return hasMemberExpressionAssignment(prop.argument || prop.value); } return false; }); case "ArrayPattern": return node.elements.some(function (element) { if (element) { return hasMemberExpressionAssignment(element); } return false; }); case "AssignmentPattern": return hasMemberExpressionAssignment(node.left); case "MemberExpression": return true; // no default } return false; } /** * Gets an identifier node of a given variable. * * If the initialization exists or one or more reading references exist before * the first assignment, the identifier node is the node of the declaration. * Otherwise, the identifier node is the node of the first assignment. * * If the variable should not change to const, this function returns null. * - If the variable is reassigned. * - If the variable is never initialized nor assigned. * - If the variable is initialized in a different scope from the declaration. * - If the unique assignment of the variable cannot change to a declaration. * e.g. `if (a) b = 1` / `return (b = 1)` * - If the variable is declared in the global scope and `eslintUsed` is `true`. * `/*exported foo` directive comment makes such variables. This rule does not * warn such variables because this rule cannot distinguish whether the * exported variables are reassigned or not. * * @param {eslint-scope.Variable} variable - A variable to get. * @param {boolean} ignoreReadBeforeAssign - * The value of `ignoreReadBeforeAssign` option. * @returns {ASTNode|null} * An Identifier node if the variable should change to const. * Otherwise, null. */ function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { if (variable.eslintUsed && variable.scope.type === "global") { return null; } // Finds the unique WriteReference. var writer = null; var isReadBeforeInit = false; var references = variable.references; for (var i = 0; i < references.length; ++i) { var reference = references[i]; if (reference.isWrite()) { var isReassigned = writer !== null && writer.identifier !== reference.identifier; if (isReassigned) { return null; } var destructuringHost = getDestructuringHost(reference); if (destructuringHost !== null && destructuringHost.left !== void 0) { var leftNode = destructuringHost.left; var hasOuterVariables = false, hasNonIdentifiers = false; if (leftNode.type === "ObjectPattern") { var properties = leftNode.properties; hasOuterVariables = properties.filter(function (prop) { return prop.value; }).map(function (prop) { return prop.value.name; }).some(function (name) { return isOuterVariableInDestructing(name, variable.scope); }); hasNonIdentifiers = hasMemberExpressionAssignment(leftNode); } else if (leftNode.type === "ArrayPattern") { var elements = leftNode.elements; hasOuterVariables = elements.map(function (element) { return element && element.name; }).some(function (name) { return isOuterVariableInDestructing(name, variable.scope); }); hasNonIdentifiers = hasMemberExpressionAssignment(leftNode); } if (hasOuterVariables || hasNonIdentifiers) { return null; } } writer = reference; } else if (reference.isRead() && writer === null) { if (ignoreReadBeforeAssign) { return null; } isReadBeforeInit = true; } } /* * If the assignment is from a different scope, ignore it. * If the assignment cannot change to a declaration, ignore it. */ var shouldBeConst = writer !== null && writer.from === variable.scope && canBecomeVariableDeclaration(writer.identifier); if (!shouldBeConst) { return null; } if (isReadBeforeInit) { return variable.defs[0].name; } return writer.identifier; } /** * Groups by the VariableDeclarator/AssignmentExpression node that each * reference of given variables belongs to. * This is used to detect a mix of reassigned and never reassigned in a * destructuring. * * @param {eslint-scope.Variable[]} variables - Variables to group by destructuring. * @param {boolean} ignoreReadBeforeAssign - * The value of `ignoreReadBeforeAssign` option. * @returns {Map} Grouped identifier nodes. */ function groupByDestructuring(variables, ignoreReadBeforeAssign) { var identifierMap = new Map(); for (var i = 0; i < variables.length; ++i) { var variable = variables[i]; var references = variable.references; var identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); var prevId = null; for (var j = 0; j < references.length; ++j) { var reference = references[j]; var id = reference.identifier; /* * Avoid counting a reference twice or more for default values of * destructuring. */ if (id === prevId) { continue; } prevId = id; // Add the identifier node into the destructuring group. var group = getDestructuringHost(reference); if (group) { if (identifierMap.has(group)) { identifierMap.get(group).push(identifier); } else { identifierMap.set(group, [identifier]); } } } } return identifierMap; } /** * Finds the nearest parent of node with a given type. * * @param {ASTNode} node – The node to search from. * @param {string} type – The type field of the parent node. * @param {Function} shouldStop – a predicate that returns true if the traversal should stop, and false otherwise. * @returns {ASTNode} The closest ancestor with the specified type; null if no such ancestor exists. */ function findUp(node, type, shouldStop) { if (!node || shouldStop(node)) { return null; } if (node.type === type) { return node; } return findUp(node.parent, type, shouldStop); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `const` declarations for variables that are never reassigned after declared", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-const" }, fixable: "code", schema: [{ type: "object", properties: { destructuring: { enum: ["any", "all"] }, ignoreReadBeforeAssign: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var options = context.options[0] || {}; var sourceCode = context.getSourceCode(); var shouldMatchAnyDestructuredVariable = options.destructuring !== "all"; var ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; var variables = []; var reportCount = 0; var name = ""; /** * Reports given identifier nodes if all of the nodes should be declared * as const. * * The argument 'nodes' is an array of Identifier nodes. * This node is the result of 'getIdentifierIfShouldBeConst()', so it's * nullable. In simple declaration or assignment cases, the length of * the array is 1. In destructuring cases, the length of the array can * be 2 or more. * * @param {(eslint-scope.Reference|null)[]} nodes - * References which are grouped by destructuring to report. * @returns {void} */ function checkGroup(nodes) { var nodesToReport = nodes.filter(Boolean); if (nodes.length && (shouldMatchAnyDestructuredVariable || nodesToReport.length === nodes.length)) { var varDeclParent = findUp(nodes[0], "VariableDeclaration", function (parentNode) { return parentNode.type.endsWith("Statement"); }); var isVarDecParentNull = varDeclParent === null; if (!isVarDecParentNull && varDeclParent.declarations.length > 0) { var firstDeclaration = varDeclParent.declarations[0]; if (firstDeclaration.init) { var firstDecParent = firstDeclaration.init.parent; /* * First we check the declaration type and then depending on * if the type is a "VariableDeclarator" or its an "ObjectPattern" * we compare the name from the first identifier, if the names are different * we assign the new name and reset the count of reportCount and nodeCount in * order to check each block for the number of reported errors and base our fix * based on comparing nodes.length and nodesToReport.length. */ if (firstDecParent.type === "VariableDeclarator") { if (firstDecParent.id.name !== name) { name = firstDecParent.id.name; reportCount = 0; } if (firstDecParent.id.type === "ObjectPattern") { if (firstDecParent.init.name !== name) { name = firstDecParent.init.name; reportCount = 0; } } } } } var shouldFix = varDeclParent && ( // Don't do a fix unless the variable is initialized (or it's in a for-in or for-of loop) varDeclParent.parent.type === "ForInStatement" || varDeclParent.parent.type === "ForOfStatement" || varDeclParent.declarations[0].init) && /* * If options.destructuring is "all", then this warning will not occur unless * every assignment in the destructuring should be const. In that case, it's safe * to apply the fix. */ nodesToReport.length === nodes.length; if (!isVarDecParentNull && varDeclParent.declarations && varDeclParent.declarations.length !== 1) { if (varDeclParent && varDeclParent.declarations && varDeclParent.declarations.length >= 1) { /* * Add nodesToReport.length to a count, then comparing the count to the length * of the declarations in the current block. */ reportCount += nodesToReport.length; shouldFix = shouldFix && reportCount === varDeclParent.declarations.length; } } nodesToReport.forEach(function (node) { context.report({ node: node, message: "'{{name}}' is never reassigned. Use 'const' instead.", data: node, fix: shouldFix ? function (fixer) { return fixer.replaceText(sourceCode.getFirstToken(varDeclParent), "const"); } : null }); }); } } return { "Program:exit": function ProgramExit() { groupByDestructuring(variables, ignoreReadBeforeAssign).forEach(checkGroup); }, VariableDeclaration: function VariableDeclaration(node) { if (node.kind === "let" && !isInitOfForStatement(node)) { variables.push.apply(variables, _toConsumableArray(context.getDeclaredVariables(node))); } } }; } }; },{"../util/ast-utils":405}],347:[function(require,module,exports){ /** * @fileoverview Prefer destructuring from arrays and objects * @author Alex LaFroscia */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require destructuring from arrays and/or objects", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-destructuring" }, schema: [{ /* * old support {array: Boolean, object: Boolean} * new support {VariableDeclarator: {}, AssignmentExpression: {}} */ oneOf: [{ type: "object", properties: { VariableDeclarator: { type: "object", properties: { array: { type: "boolean" }, object: { type: "boolean" } }, additionalProperties: false }, AssignmentExpression: { type: "object", properties: { array: { type: "boolean" }, object: { type: "boolean" } }, additionalProperties: false } }, additionalProperties: false }, { type: "object", properties: { array: { type: "boolean" }, object: { type: "boolean" } }, additionalProperties: false }] }, { type: "object", properties: { enforceForRenamedProperties: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var enabledTypes = context.options[0]; var enforceForRenamedProperties = context.options[1] && context.options[1].enforceForRenamedProperties; var normalizedOptions = { VariableDeclarator: { array: true, object: true }, AssignmentExpression: { array: true, object: true } }; if (enabledTypes) { normalizedOptions = typeof enabledTypes.array !== "undefined" || typeof enabledTypes.object !== "undefined" ? { VariableDeclarator: enabledTypes, AssignmentExpression: enabledTypes } : enabledTypes; } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * @param {string} nodeType "AssignmentExpression" or "VariableDeclarator" * @param {string} destructuringType "array" or "object" * @returns {boolean} `true` if the destructuring type should be checked for the given node */ function shouldCheck(nodeType, destructuringType) { return normalizedOptions && normalizedOptions[nodeType] && normalizedOptions[nodeType][destructuringType]; } /** * Determines if the given node is accessing an array index * * This is used to differentiate array index access from object property * access. * * @param {ASTNode} node the node to evaluate * @returns {boolean} whether or not the node is an integer */ function isArrayIndexAccess(node) { return Number.isInteger(node.property.value); } /** * Report that the given node should use destructuring * * @param {ASTNode} reportNode the node to report * @param {string} type the type of destructuring that should have been done * @returns {void} */ function report(reportNode, type) { context.report({ node: reportNode, message: "Use {{type}} destructuring.", data: { type: type } }); } /** * Check that the `prefer-destructuring` rules are followed based on the * given left- and right-hand side of the assignment. * * Pulled out into a separate method so that VariableDeclarators and * AssignmentExpressions can share the same verification logic. * * @param {ASTNode} leftNode the left-hand side of the assignment * @param {ASTNode} rightNode the right-hand side of the assignment * @param {ASTNode} reportNode the node to report the error on * @returns {void} */ function performCheck(leftNode, rightNode, reportNode) { if (rightNode.type !== "MemberExpression" || rightNode.object.type === "Super") { return; } if (isArrayIndexAccess(rightNode)) { if (shouldCheck(reportNode.type, "array")) { report(reportNode, "array"); } return; } if (shouldCheck(reportNode.type, "object") && enforceForRenamedProperties) { report(reportNode, "object"); return; } if (shouldCheck(reportNode.type, "object")) { var property = rightNode.property; if (property.type === "Literal" && leftNode.name === property.value || property.type === "Identifier" && leftNode.name === property.name && !rightNode.computed) { report(reportNode, "object"); } } } /** * Check if a given variable declarator is coming from an property access * that should be using destructuring instead * * @param {ASTNode} node the variable declarator to check * @returns {void} */ function checkVariableDeclarator(node) { // Skip if variable is declared without assignment if (!node.init) { return; } // We only care about member expressions past this point if (node.init.type !== "MemberExpression") { return; } performCheck(node.id, node.init, node); } /** * Run the `prefer-destructuring` check on an AssignmentExpression * * @param {ASTNode} node the AssignmentExpression node * @returns {void} */ function checkAssigmentExpression(node) { if (node.operator === "=") { performCheck(node.left, node.right, node); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { VariableDeclarator: checkVariableDeclarator, AssignmentExpression: checkAssigmentExpression }; } }; },{}],348:[function(require,module,exports){ /** * @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals * @author Annie Zhang, Henry Zhu */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks to see if a CallExpression's callee node is `parseInt` or * `Number.parseInt`. * @param {ASTNode} calleeNode The callee node to evaluate. * @returns {boolean} True if the callee is `parseInt` or `Number.parseInt`, * false otherwise. */ function isParseInt(calleeNode) { switch (calleeNode.type) { case "Identifier": return calleeNode.name === "parseInt"; case "MemberExpression": return calleeNode.object.type === "Identifier" && calleeNode.object.name === "Number" && calleeNode.property.type === "Identifier" && calleeNode.property.name === "parseInt"; // no default } return false; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-numeric-literals" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); var radixMap = { 2: "binary", 8: "octal", 16: "hexadecimal" }; var prefixMap = { 2: "0b", 8: "0o", 16: "0x" }; //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { CallExpression: function CallExpression(node) { // doesn't check parseInt() if it doesn't have a radix argument if (node.arguments.length !== 2) { return; } // only error if the radix is 2, 8, or 16 var radixName = radixMap[node.arguments[1].value]; if (isParseInt(node.callee) && radixName && node.arguments[0].type === "Literal") { context.report({ node: node, message: "Use {{radixName}} literals instead of {{functionName}}().", data: { radixName: radixName, functionName: sourceCode.getText(node.callee) }, fix: function fix(fixer) { var newPrefix = prefixMap[node.arguments[1].value]; if (+(newPrefix + node.arguments[0].value) !== parseInt(node.arguments[0].value, node.arguments[1].value)) { /* * If the newly-produced literal would be invalid, (e.g. 0b1234), * or it would yield an incorrect parseInt result for some other reason, don't make a fix. */ return null; } return fixer.replaceText(node, prefixMap[node.arguments[1].value] + node.arguments[0].value); } }); } } }; } }; },{}],349:[function(require,module,exports){ /** * @fileoverview Prefers object spread property over Object.assign * @author Sharmila Jesupaul * See LICENSE file in root directory for full license. */ "use strict"; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var _require = require("eslint-utils"), CALL = _require.CALL, ReferenceTracker = _require.ReferenceTracker; var _require2 = require("../util/ast-utils"), isCommaToken = _require2.isCommaToken, isOpeningParenToken = _require2.isOpeningParenToken, isClosingParenToken = _require2.isClosingParenToken, isParenthesised = _require2.isParenthesised; var ANY_SPACE = /\s/; /** * Helper that checks if the Object.assign call has array spread * @param {ASTNode} node - The node that the rule warns on * @returns {boolean} - Returns true if the Object.assign call has array spread */ function hasArraySpread(node) { return node.arguments.some(function (arg) { return arg.type === "SpreadElement"; }); } /** * Helper that checks if the node needs parentheses to be valid JS. * The default is to wrap the node in parentheses to avoid parsing errors. * @param {ASTNode} node - The node that the rule warns on * @param {Object} sourceCode - in context sourcecode object * @returns {boolean} - Returns true if the node needs parentheses */ function needsParens(node, sourceCode) { var parent = node.parent; switch (parent.type) { case "VariableDeclarator": case "ArrayExpression": case "ReturnStatement": case "CallExpression": case "Property": return false; case "AssignmentExpression": return parent.left === node && !isParenthesised(sourceCode, node); default: return !isParenthesised(sourceCode, node); } } /** * Determines if an argument needs parentheses. The default is to not add parens. * @param {ASTNode} node - The node to be checked. * @param {Object} sourceCode - in context sourcecode object * @returns {boolean} True if the node needs parentheses */ function argNeedsParens(node, sourceCode) { switch (node.type) { case "AssignmentExpression": case "ArrowFunctionExpression": case "ConditionalExpression": return !isParenthesised(sourceCode, node); default: return false; } } /** * Get the parenthesis tokens of a given ObjectExpression node. * This incldues the braces of the object literal and enclosing parentheses. * @param {ASTNode} node The node to get. * @param {Token} leftArgumentListParen The opening paren token of the argument list. * @param {SourceCode} sourceCode The source code object to get tokens. * @returns {Token[]} The parenthesis tokens of the node. This is sorted by the location. */ function getParenTokens(node, leftArgumentListParen, sourceCode) { var parens = [sourceCode.getFirstToken(node), sourceCode.getLastToken(node)]; var leftNext = sourceCode.getTokenBefore(node); var rightNext = sourceCode.getTokenAfter(node); // Note: don't include the parens of the argument list. while (leftNext && rightNext && leftNext.range[0] > leftArgumentListParen.range[0] && isOpeningParenToken(leftNext) && isClosingParenToken(rightNext)) { parens.push(leftNext, rightNext); leftNext = sourceCode.getTokenBefore(leftNext); rightNext = sourceCode.getTokenAfter(rightNext); } return parens.sort(function (a, b) { return a.range[0] - b.range[0]; }); } /** * Get the range of a given token and around whitespaces. * @param {Token} token The token to get range. * @param {SourceCode} sourceCode The source code object to get tokens. * @returns {number} The end of the range of the token and around whitespaces. */ function getStartWithSpaces(token, sourceCode) { var text = sourceCode.text; var start = token.range[0]; // If the previous token is a line comment then skip this step to avoid commenting this token out. { var prevToken = sourceCode.getTokenBefore(token, { includeComments: true }); if (prevToken && prevToken.type === "Line") { return start; } } // Detect spaces before the token. while (ANY_SPACE.test(text[start - 1] || "")) { start -= 1; } return start; } /** * Get the range of a given token and around whitespaces. * @param {Token} token The token to get range. * @param {SourceCode} sourceCode The source code object to get tokens. * @returns {number} The start of the range of the token and around whitespaces. */ function getEndWithSpaces(token, sourceCode) { var text = sourceCode.text; var end = token.range[1]; // Detect spaces after the token. while (ANY_SPACE.test(text[end] || "")) { end += 1; } return end; } /** * Autofixes the Object.assign call to use an object spread instead. * @param {ASTNode|null} node - The node that the rule warns on, i.e. the Object.assign call * @param {string} sourceCode - sourceCode of the Object.assign call * @returns {Function} autofixer - replaces the Object.assign with a spread object. */ function defineFixer(node, sourceCode) { return (/*#__PURE__*/regeneratorRuntime.mark(function _callee(fixer) { var leftParen, rightParen, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, argNode, innerParens, left, right, maybeTrailingComma, maybeArgumentComma, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, innerParen, leftRange, rightRange; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: leftParen = sourceCode.getTokenAfter(node.callee, isOpeningParenToken); rightParen = sourceCode.getLastToken(node); // Remove the callee `Object.assign` _context.next = 4; return fixer.remove(node.callee); case 4: if (!needsParens(node, sourceCode)) { _context.next = 11; break; } _context.next = 7; return fixer.replaceText(leftParen, "({"); case 7: _context.next = 9; return fixer.replaceText(rightParen, "})"); case 9: _context.next = 15; break; case 11: _context.next = 13; return fixer.replaceText(leftParen, "{"); case 13: _context.next = 15; return fixer.replaceText(rightParen, "}"); case 15: // Process arguments. _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context.prev = 18; _iterator = node.arguments[Symbol.iterator](); case 20: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context.next = 77; break; } argNode = _step.value; innerParens = getParenTokens(argNode, leftParen, sourceCode); left = innerParens.shift(); right = innerParens.pop(); if (!(argNode.type === "ObjectExpression")) { _context.next = 65; break; } maybeTrailingComma = sourceCode.getLastToken(argNode, 1); maybeArgumentComma = sourceCode.getTokenAfter(right); /* * Make bare this object literal. * And remove spaces inside of the braces for better formatting. */ _iteratorNormalCompletion2 = true; _didIteratorError2 = false; _iteratorError2 = undefined; _context.prev = 31; _iterator2 = innerParens[Symbol.iterator](); case 33: if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) { _context.next = 40; break; } innerParen = _step2.value; _context.next = 37; return fixer.remove(innerParen); case 37: _iteratorNormalCompletion2 = true; _context.next = 33; break; case 40: _context.next = 46; break; case 42: _context.prev = 42; _context.t0 = _context["catch"](31); _didIteratorError2 = true; _iteratorError2 = _context.t0; case 46: _context.prev = 46; _context.prev = 47; if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } case 49: _context.prev = 49; if (!_didIteratorError2) { _context.next = 52; break; } throw _iteratorError2; case 52: return _context.finish(49); case 53: return _context.finish(46); case 54: leftRange = [left.range[0], getEndWithSpaces(left, sourceCode)]; rightRange = [Math.max(getStartWithSpaces(right, sourceCode), leftRange[1]), // Ensure ranges don't overlap right.range[1]]; _context.next = 58; return fixer.removeRange(leftRange); case 58: _context.next = 60; return fixer.removeRange(rightRange); case 60: if (!((argNode.properties.length === 0 || isCommaToken(maybeTrailingComma)) && isCommaToken(maybeArgumentComma))) { _context.next = 63; break; } _context.next = 63; return fixer.remove(maybeArgumentComma); case 63: _context.next = 74; break; case 65: if (!argNeedsParens(argNode, sourceCode)) { _context.next = 72; break; } _context.next = 68; return fixer.insertTextBefore(left, "...("); case 68: _context.next = 70; return fixer.insertTextAfter(right, ")"); case 70: _context.next = 74; break; case 72: _context.next = 74; return fixer.insertTextBefore(left, "..."); case 74: _iteratorNormalCompletion = true; _context.next = 20; break; case 77: _context.next = 83; break; case 79: _context.prev = 79; _context.t1 = _context["catch"](18); _didIteratorError = true; _iteratorError = _context.t1; case 83: _context.prev = 83; _context.prev = 84; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 86: _context.prev = 86; if (!_didIteratorError) { _context.next = 89; break; } throw _iteratorError; case 89: return _context.finish(86); case 90: return _context.finish(83); case 91: case "end": return _context.stop(); } } }, _callee, this, [[18, 79, 83, 91], [31, 42, 46, 54], [47,, 49, 53], [84,, 86, 90]]); }) ); } module.exports = { meta: { type: "suggestion", docs: { description: "disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/prefer-object-spread" }, schema: [], fixable: "code", messages: { useSpreadMessage: "Use an object spread instead of `Object.assign` eg: `{ ...foo }`", useLiteralMessage: "Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`" } }, create: function create(context) { var sourceCode = context.getSourceCode(); return { Program: function Program() { var scope = context.getScope(); var tracker = new ReferenceTracker(scope); var trackMap = { Object: { assign: _defineProperty({}, CALL, true) } }; // Iterate all calls of `Object.assign` (only of the global variable `Object`). var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = tracker.iterateGlobalReferences(trackMap)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var node = _step3.value.node; if (node.arguments.length >= 1 && node.arguments[0].type === "ObjectExpression" && !hasArraySpread(node)) { var messageId = node.arguments.length === 1 ? "useLiteralMessage" : "useSpreadMessage"; var fix = defineFixer(node, sourceCode); context.report({ node: node, messageId: messageId, fix: fix }); } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } }; } }; },{"../util/ast-utils":405,"eslint-utils":68}],350:[function(require,module,exports){ /** * @fileoverview restrict values that can be used as Promise rejection reasons * @author Teddy Katz */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require using Error objects as Promise rejection reasons", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/prefer-promise-reject-errors" }, fixable: null, schema: [{ type: "object", properties: { allowEmptyReject: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var ALLOW_EMPTY_REJECT = context.options.length && context.options[0].allowEmptyReject; //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Checks the argument of a reject() or Promise.reject() CallExpression, and reports it if it can't be an Error * @param {ASTNode} callExpression A CallExpression node which is used to reject a Promise * @returns {void} */ function checkRejectCall(callExpression) { if (!callExpression.arguments.length && ALLOW_EMPTY_REJECT) { return; } if (!callExpression.arguments.length || !astUtils.couldBeError(callExpression.arguments[0]) || callExpression.arguments[0].type === "Identifier" && callExpression.arguments[0].name === "undefined") { context.report({ node: callExpression, message: "Expected the Promise rejection reason to be an Error." }); } } /** * Determines whether a function call is a Promise.reject() call * @param {ASTNode} node A CallExpression node * @returns {boolean} `true` if the call is a Promise.reject() call */ function isPromiseRejectCall(node) { return node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "Promise" && node.callee.property.type === "Identifier" && node.callee.property.name === "reject"; } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { // Check `Promise.reject(value)` calls. CallExpression: function CallExpression(node) { if (isPromiseRejectCall(node)) { checkRejectCall(node); } }, /* * Check for `new Promise((resolve, reject) => {})`, and check for reject() calls. * This function is run on "NewExpression:exit" instead of "NewExpression" to ensure that * the nodes in the expression already have the `parent` property. */ "NewExpression:exit": function NewExpressionExit(node) { if (node.callee.type === "Identifier" && node.callee.name === "Promise" && node.arguments.length && astUtils.isFunction(node.arguments[0]) && node.arguments[0].params.length > 1 && node.arguments[0].params[1].type === "Identifier") { context.getDeclaredVariables(node.arguments[0]) /* * Find the first variable that matches the second parameter's name. * If the first parameter has the same name as the second parameter, then the variable will actually * be "declared" when the first parameter is evaluated, but then it will be immediately overwritten * by the second parameter. It's not possible for an expression with the variable to be evaluated before * the variable is overwritten, because functions with duplicate parameters cannot have destructuring or * default assignments in their parameter lists. Therefore, it's not necessary to explicitly account for * this case. */ .find(function (variable) { return variable.name === node.arguments[0].params[1].name; }) // Get the references to that variable. .references // Only check the references that read the parameter's value. .filter(function (ref) { return ref.isRead(); }) // Only check the references that are used as the callee in a function call, e.g. `reject(foo)`. .filter(function (ref) { return ref.identifier.parent.type === "CallExpression" && ref.identifier === ref.identifier.parent.callee; }) // Check the argument of the function call to determine whether it's an Error. .forEach(function (ref) { return checkRejectCall(ref.identifier.parent); }); } } }; } }; },{"../util/ast-utils":405}],351:[function(require,module,exports){ /** * @fileoverview Rule to suggest using "Reflect" api over Function/Object methods * @author Keith Cirkel * @deprecated in ESLint v3.9.0 */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `Reflect` methods where applicable", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-reflect" }, deprecated: true, replacedBy: [], schema: [{ type: "object", properties: { exceptions: { type: "array", items: { enum: ["apply", "call", "delete", "defineProperty", "getOwnPropertyDescriptor", "getPrototypeOf", "setPrototypeOf", "isExtensible", "getOwnPropertyNames", "preventExtensions"] }, uniqueItems: true } }, additionalProperties: false }] }, create: function create(context) { var existingNames = { apply: "Function.prototype.apply", call: "Function.prototype.call", defineProperty: "Object.defineProperty", getOwnPropertyDescriptor: "Object.getOwnPropertyDescriptor", getPrototypeOf: "Object.getPrototypeOf", setPrototypeOf: "Object.setPrototypeOf", isExtensible: "Object.isExtensible", getOwnPropertyNames: "Object.getOwnPropertyNames", preventExtensions: "Object.preventExtensions" }; var reflectSubsitutes = { apply: "Reflect.apply", call: "Reflect.apply", defineProperty: "Reflect.defineProperty", getOwnPropertyDescriptor: "Reflect.getOwnPropertyDescriptor", getPrototypeOf: "Reflect.getPrototypeOf", setPrototypeOf: "Reflect.setPrototypeOf", isExtensible: "Reflect.isExtensible", getOwnPropertyNames: "Reflect.getOwnPropertyNames", preventExtensions: "Reflect.preventExtensions" }; var exceptions = (context.options[0] || {}).exceptions || []; /** * Reports the Reflect violation based on the `existing` and `substitute` * @param {Object} node The node that violates the rule. * @param {string} existing The existing method name that has been used. * @param {string} substitute The Reflect substitute that should be used. * @returns {void} */ function report(node, existing, substitute) { context.report({ node: node, message: "Avoid using {{existing}}, instead use {{substitute}}.", data: { existing: existing, substitute: substitute } }); } return { CallExpression: function CallExpression(node) { var methodName = (node.callee.property || {}).name; var isReflectCall = (node.callee.object || {}).name === "Reflect"; var hasReflectSubsitute = Object.prototype.hasOwnProperty.call(reflectSubsitutes, methodName); var userConfiguredException = exceptions.indexOf(methodName) !== -1; if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) { report(node, existingNames[methodName], reflectSubsitutes[methodName]); } }, UnaryExpression: function UnaryExpression(node) { var isDeleteOperator = node.operator === "delete"; var targetsIdentifier = node.argument.type === "Identifier"; var userConfiguredException = exceptions.indexOf("delete") !== -1; if (isDeleteOperator && !targetsIdentifier && !userConfiguredException) { report(node, "the delete keyword", "Reflect.deleteProperty"); } } }; } }; },{}],352:[function(require,module,exports){ /** * @fileoverview Rule to * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets the variable object of `arguments` which is defined implicitly. * @param {eslint-scope.Scope} scope - A scope to get. * @returns {eslint-scope.Variable} The found variable object. */ function getVariableOfArguments(scope) { var variables = scope.variables; for (var i = 0; i < variables.length; ++i) { var variable = variables[i]; if (variable.name === "arguments") { /* * If there was a parameter which is named "arguments", the implicit "arguments" is not defined. * So does fast return with null. */ return variable.identifiers.length === 0 ? variable : null; } } /* istanbul ignore next : unreachable */ return null; } /** * Checks if the given reference is not normal member access. * * - arguments .... true // not member access * - arguments[i] .... true // computed member access * - arguments[0] .... true // computed member access * - arguments.length .... false // normal member access * * @param {eslint-scope.Reference} reference - The reference to check. * @returns {boolean} `true` if the reference is not normal member access. */ function isNotNormalMemberAccess(reference) { var id = reference.identifier; var parent = id.parent; return !(parent.type === "MemberExpression" && parent.object === id && !parent.computed); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require rest parameters instead of `arguments`", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-rest-params" }, schema: [] }, create: function create(context) { /** * Reports a given reference. * * @param {eslint-scope.Reference} reference - A reference to report. * @returns {void} */ function report(reference) { context.report({ node: reference.identifier, loc: reference.identifier.loc, message: "Use the rest parameters instead of 'arguments'." }); } /** * Reports references of the implicit `arguments` variable if exist. * * @returns {void} */ function checkForArguments() { var argumentsVar = getVariableOfArguments(context.getScope()); if (argumentsVar) { argumentsVar.references.filter(isNotNormalMemberAccess).forEach(report); } } return { "FunctionDeclaration:exit": checkForArguments, "FunctionExpression:exit": checkForArguments }; } }; },{}],353:[function(require,module,exports){ /** * @fileoverview A rule to suggest using of the spread operator instead of `.apply()`. * @author Toru Nagashima */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a node is a `.apply()` for variadic. * @param {ASTNode} node - A CallExpression node to check. * @returns {boolean} Whether or not the node is a `.apply()` for variadic. */ function isVariadicApplyCalling(node) { return node.callee.type === "MemberExpression" && node.callee.property.type === "Identifier" && node.callee.property.name === "apply" && node.callee.computed === false && node.arguments.length === 2 && node.arguments[1].type !== "ArrayExpression" && node.arguments[1].type !== "SpreadElement"; } /** * Checks whether or not `thisArg` is not changed by `.apply()`. * @param {ASTNode|null} expectedThis - The node that is the owner of the applied function. * @param {ASTNode} thisArg - The node that is given to the first argument of the `.apply()`. * @param {RuleContext} context - The ESLint rule context object. * @returns {boolean} Whether or not `thisArg` is not changed by `.apply()`. */ function isValidThisArg(expectedThis, thisArg, context) { if (!expectedThis) { return astUtils.isNullOrUndefined(thisArg); } return astUtils.equalTokens(expectedThis, thisArg, context); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require spread operators instead of `.apply()`", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-spread" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); return { CallExpression: function CallExpression(node) { if (!isVariadicApplyCalling(node)) { return; } var applied = node.callee.object; var expectedThis = applied.type === "MemberExpression" ? applied.object : null; var thisArg = node.arguments[0]; if (isValidThisArg(expectedThis, thisArg, sourceCode)) { context.report({ node: node, message: "Use the spread operator instead of '.apply()'.", fix: function fix(fixer) { if (expectedThis && expectedThis.type !== "Identifier") { // Don't fix cases where the `this` value could be a computed expression. return null; } var propertyDot = sourceCode.getFirstTokenBetween(applied, node.callee.property, function (token) { return token.value === "."; }); return fixer.replaceTextRange([propertyDot.range[0], node.range[1]], "(..." + sourceCode.getText(node.arguments[1]) + ")"); } }); } } }; } }; },{"../util/ast-utils":405}],354:[function(require,module,exports){ /** * @fileoverview A rule to suggest using template literals instead of string concatenation. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Checks whether or not a given node is a concatenation. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a concatenation. */ function isConcatenation(node) { return node.type === "BinaryExpression" && node.operator === "+"; } /** * Gets the top binary expression node for concatenation in parents of a given node. * @param {ASTNode} node - A node to get. * @returns {ASTNode} the top binary expression node in parents of a given node. */ function getTopConcatBinaryExpression(node) { var currentNode = node; while (isConcatenation(currentNode.parent)) { currentNode = currentNode.parent; } return currentNode; } /** * Determines whether a given node is a octal escape sequence * @param {ASTNode} node A node to check * @returns {boolean} `true` if the node is an octal escape sequence */ function isOctalEscapeSequence(node) { // No need to check TemplateLiterals – would throw error with octal escape var isStringLiteral = node.type === "Literal" && typeof node.value === "string"; if (!isStringLiteral) { return false; } var match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7]{1,3})/); if (match) { // \0 is actually not considered an octal if (match[2] !== "0" || typeof match[3] !== "undefined") { return true; } } return false; } /** * Checks whether or not a node contains a octal escape sequence * @param {ASTNode} node A node to check * @returns {boolean} `true` if the node contains an octal escape sequence */ function hasOctalEscapeSequence(node) { if (isConcatenation(node)) { return hasOctalEscapeSequence(node.left) || hasOctalEscapeSequence(node.right); } return isOctalEscapeSequence(node); } /** * Checks whether or not a given binary expression has string literals. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node has string literals. */ function hasStringLiteral(node) { if (isConcatenation(node)) { // `left` is deeper than `right` normally. return hasStringLiteral(node.right) || hasStringLiteral(node.left); } return astUtils.isStringLiteral(node); } /** * Checks whether or not a given binary expression has non string literals. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node has non string literals. */ function hasNonStringLiteral(node) { if (isConcatenation(node)) { // `left` is deeper than `right` normally. return hasNonStringLiteral(node.right) || hasNonStringLiteral(node.left); } return !astUtils.isStringLiteral(node); } /** * Determines whether a given node will start with a template curly expression (`${}`) when being converted to a template literal. * @param {ASTNode} node The node that will be fixed to a template literal * @returns {boolean} `true` if the node will start with a template curly. */ function startsWithTemplateCurly(node) { if (node.type === "BinaryExpression") { return startsWithTemplateCurly(node.left); } if (node.type === "TemplateLiteral") { return node.expressions.length && node.quasis.length && node.quasis[0].range[0] === node.quasis[0].range[1]; } return node.type !== "Literal" || typeof node.value !== "string"; } /** * Determines whether a given node end with a template curly expression (`${}`) when being converted to a template literal. * @param {ASTNode} node The node that will be fixed to a template literal * @returns {boolean} `true` if the node will end with a template curly. */ function endsWithTemplateCurly(node) { if (node.type === "BinaryExpression") { return startsWithTemplateCurly(node.right); } if (node.type === "TemplateLiteral") { return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].range[0] === node.quasis[node.quasis.length - 1].range[1]; } return node.type !== "Literal" || typeof node.value !== "string"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require template literals instead of string concatenation", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/prefer-template" }, schema: [], fixable: "code" }, create: function create(context) { var sourceCode = context.getSourceCode(); var done = Object.create(null); /** * Gets the non-token text between two nodes, ignoring any other tokens that appear between the two tokens. * @param {ASTNode} node1 The first node * @param {ASTNode} node2 The second node * @returns {string} The text between the nodes, excluding other tokens */ function getTextBetween(node1, node2) { var allTokens = [node1].concat(sourceCode.getTokensBetween(node1, node2)).concat(node2); var sourceText = sourceCode.getText(); return allTokens.slice(0, -1).reduce(function (accumulator, token, index) { return accumulator + sourceText.slice(token.range[1], allTokens[index + 1].range[0]); }, ""); } /** * Returns a template literal form of the given node. * @param {ASTNode} currentNode A node that should be converted to a template literal * @param {string} textBeforeNode Text that should appear before the node * @param {string} textAfterNode Text that should appear after the node * @returns {string} A string form of this node, represented as a template literal */ function getTemplateLiteral(currentNode, textBeforeNode, textAfterNode) { if (currentNode.type === "Literal" && typeof currentNode.value === "string") { /* * If the current node is a string literal, escape any instances of ${ or ` to prevent them from being interpreted * as a template placeholder. However, if the code already contains a backslash before the ${ or ` * for some reason, don't add another backslash, because that would change the meaning of the code (it would cause * an actual backslash character to appear before the dollar sign). */ return "`" + currentNode.raw.slice(1, -1).replace(/\\*(\${|`)/g, function (matched) { if (matched.lastIndexOf("\\") % 2) { return "\\" + matched; } return matched; // Unescape any quotes that appear in the original Literal that no longer need to be escaped. }).replace(new RegExp("\\\\" + currentNode.raw[0], "g"), currentNode.raw[0]) + "`"; } if (currentNode.type === "TemplateLiteral") { return sourceCode.getText(currentNode); } if (isConcatenation(currentNode) && hasStringLiteral(currentNode) && hasNonStringLiteral(currentNode)) { var plusSign = sourceCode.getFirstTokenBetween(currentNode.left, currentNode.right, function (token) { return token.value === "+"; }); var textBeforePlus = getTextBetween(currentNode.left, plusSign); var textAfterPlus = getTextBetween(plusSign, currentNode.right); var leftEndsWithCurly = endsWithTemplateCurly(currentNode.left); var rightStartsWithCurly = startsWithTemplateCurly(currentNode.right); if (leftEndsWithCurly) { // If the left side of the expression ends with a template curly, add the extra text to the end of the curly bracket. // `foo${bar}` /* comment */ + 'baz' --> `foo${bar /* comment */ }${baz}` return getTemplateLiteral(currentNode.left, textBeforeNode, textBeforePlus + textAfterPlus).slice(0, -1) + getTemplateLiteral(currentNode.right, null, textAfterNode).slice(1); } if (rightStartsWithCurly) { // Otherwise, if the right side of the expression starts with a template curly, add the text there. // 'foo' /* comment */ + `${bar}baz` --> `foo${ /* comment */ bar}baz` return getTemplateLiteral(currentNode.left, textBeforeNode, null).slice(0, -1) + getTemplateLiteral(currentNode.right, textBeforePlus + textAfterPlus, textAfterNode).slice(1); } /* * Otherwise, these nodes should not be combined into a template curly, since there is nowhere to put * the text between them. */ return "" + getTemplateLiteral(currentNode.left, textBeforeNode, null) + textBeforePlus + "+" + textAfterPlus + getTemplateLiteral(currentNode.right, textAfterNode, null); } return "`${" + (textBeforeNode || "") + sourceCode.getText(currentNode) + (textAfterNode || "") + "}`"; } /** * Returns a fixer object that converts a non-string binary expression to a template literal * @param {SourceCodeFixer} fixer The fixer object * @param {ASTNode} node A node that should be converted to a template literal * @returns {Object} A fix for this binary expression */ function fixNonStringBinaryExpression(fixer, node) { var topBinaryExpr = getTopConcatBinaryExpression(node.parent); if (hasOctalEscapeSequence(topBinaryExpr)) { return null; } return fixer.replaceText(topBinaryExpr, getTemplateLiteral(topBinaryExpr, null, null)); } /** * Reports if a given node is string concatenation with non string literals. * * @param {ASTNode} node - A node to check. * @returns {void} */ function checkForStringConcat(node) { if (!astUtils.isStringLiteral(node) || !isConcatenation(node.parent)) { return; } var topBinaryExpr = getTopConcatBinaryExpression(node.parent); // Checks whether or not this node had been checked already. if (done[topBinaryExpr.range[0]]) { return; } done[topBinaryExpr.range[0]] = true; if (hasNonStringLiteral(topBinaryExpr)) { context.report({ node: topBinaryExpr, message: "Unexpected string concatenation.", fix: function fix(fixer) { return fixNonStringBinaryExpression(fixer, node); } }); } } return { Program: function Program() { done = Object.create(null); }, Literal: checkForStringConcat, TemplateLiteral: checkForStringConcat }; } }; },{"../util/ast-utils":405}],355:[function(require,module,exports){ /** * @fileoverview Rule to flag non-quoted property names in object literals. * @author Mathias Bynens */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var espree = require("espree"), keywords = require("../util/keywords"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require quotes around object literal property names", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/quote-props" }, schema: { anyOf: [{ type: "array", items: [{ enum: ["always", "as-needed", "consistent", "consistent-as-needed"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ enum: ["always", "as-needed", "consistent", "consistent-as-needed"] }, { type: "object", properties: { keywords: { type: "boolean" }, unnecessary: { type: "boolean" }, numbers: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] }, fixable: "code" }, create: function create(context) { var MODE = context.options[0], KEYWORDS = context.options[1] && context.options[1].keywords, CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false, NUMBERS = context.options[1] && context.options[1].numbers, MESSAGE_UNNECESSARY = "Unnecessarily quoted property '{{property}}' found.", MESSAGE_UNQUOTED = "Unquoted property '{{property}}' found.", MESSAGE_NUMERIC = "Unquoted number literal '{{property}}' used as key.", MESSAGE_RESERVED = "Unquoted reserved word '{{property}}' used as key.", sourceCode = context.getSourceCode(); /** * Checks whether a certain string constitutes an ES3 token * @param {string} tokenStr - The string to be checked. * @returns {boolean} `true` if it is an ES3 token. */ function isKeyword(tokenStr) { return keywords.indexOf(tokenStr) >= 0; } /** * Checks if an espree-tokenized key has redundant quotes (i.e. whether quotes are unnecessary) * @param {string} rawKey The raw key value from the source * @param {espreeTokens} tokens The espree-tokenized node key * @param {boolean} [skipNumberLiterals=false] Indicates whether number literals should be checked * @returns {boolean} Whether or not a key has redundant quotes. * @private */ function areQuotesRedundant(rawKey, tokens, skipNumberLiterals) { return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length && (["Identifier", "Keyword", "Null", "Boolean"].indexOf(tokens[0].type) >= 0 || tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value); } /** * Returns a string representation of a property node with quotes removed * @param {ASTNode} key Key AST Node, which may or may not be quoted * @returns {string} A replacement string for this property */ function getUnquotedKey(key) { return key.type === "Identifier" ? key.name : key.value; } /** * Returns a string representation of a property node with quotes added * @param {ASTNode} key Key AST Node, which may or may not be quoted * @returns {string} A replacement string for this property */ function getQuotedKey(key) { if (key.type === "Literal" && typeof key.value === "string") { // If the key is already a string literal, don't replace the quotes with double quotes. return sourceCode.getText(key); } // Otherwise, the key is either an identifier or a number literal. return "\"" + (key.type === "Identifier" ? key.name : key.value) + "\""; } /** * Ensures that a property's key is quoted only when necessary * @param {ASTNode} node Property AST node * @returns {void} */ function checkUnnecessaryQuotes(node) { var key = node.key; if (node.method || node.computed || node.shorthand) { return; } if (key.type === "Literal" && typeof key.value === "string") { var tokens = void 0; try { tokens = espree.tokenize(key.value); } catch (e) { return; } if (tokens.length !== 1) { return; } var isKeywordToken = isKeyword(tokens[0].value); if (isKeywordToken && KEYWORDS) { return; } if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) { context.report({ node: node, message: MESSAGE_UNNECESSARY, data: { property: key.value }, fix: function fix(fixer) { return fixer.replaceText(key, getUnquotedKey(key)); } }); } } else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) { context.report({ node: node, message: MESSAGE_RESERVED, data: { property: key.name }, fix: function fix(fixer) { return fixer.replaceText(key, getQuotedKey(key)); } }); } else if (NUMBERS && key.type === "Literal" && typeof key.value === "number") { context.report({ node: node, message: MESSAGE_NUMERIC, data: { property: key.value }, fix: function fix(fixer) { return fixer.replaceText(key, getQuotedKey(key)); } }); } } /** * Ensures that a property's key is quoted * @param {ASTNode} node Property AST node * @returns {void} */ function checkOmittedQuotes(node) { var key = node.key; if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) { context.report({ node: node, message: MESSAGE_UNQUOTED, data: { property: key.name || key.value }, fix: function fix(fixer) { return fixer.replaceText(key, getQuotedKey(key)); } }); } } /** * Ensures that an object's keys are consistently quoted, optionally checks for redundancy of quotes * @param {ASTNode} node Property AST node * @param {boolean} checkQuotesRedundancy Whether to check quotes' redundancy * @returns {void} */ function checkConsistency(node, checkQuotesRedundancy) { var quotedProps = [], unquotedProps = []; var keywordKeyName = null, necessaryQuotes = false; node.properties.forEach(function (property) { var key = property.key; if (!key || property.method || property.computed || property.shorthand) { return; } if (key.type === "Literal" && typeof key.value === "string") { quotedProps.push(property); if (checkQuotesRedundancy) { var tokens = void 0; try { tokens = espree.tokenize(key.value); } catch (e) { necessaryQuotes = true; return; } necessaryQuotes = necessaryQuotes || !areQuotesRedundant(key.value, tokens) || KEYWORDS && isKeyword(tokens[0].value); } } else if (KEYWORDS && checkQuotesRedundancy && key.type === "Identifier" && isKeyword(key.name)) { unquotedProps.push(property); necessaryQuotes = true; keywordKeyName = key.name; } else { unquotedProps.push(property); } }); if (checkQuotesRedundancy && quotedProps.length && !necessaryQuotes) { quotedProps.forEach(function (property) { context.report({ node: property, message: "Properties shouldn't be quoted as all quotes are redundant.", fix: function fix(fixer) { return fixer.replaceText(property.key, getUnquotedKey(property.key)); } }); }); } else if (unquotedProps.length && keywordKeyName) { unquotedProps.forEach(function (property) { context.report({ node: property, message: "Properties should be quoted as '{{property}}' is a reserved word.", data: { property: keywordKeyName }, fix: function fix(fixer) { return fixer.replaceText(property.key, getQuotedKey(property.key)); } }); }); } else if (quotedProps.length && unquotedProps.length) { unquotedProps.forEach(function (property) { context.report({ node: property, message: "Inconsistently quoted property '{{key}}' found.", data: { key: property.key.name || property.key.value }, fix: function fix(fixer) { return fixer.replaceText(property.key, getQuotedKey(property.key)); } }); }); } } return { Property: function Property(node) { if (MODE === "always" || !MODE) { checkOmittedQuotes(node); } if (MODE === "as-needed") { checkUnnecessaryQuotes(node); } }, ObjectExpression: function ObjectExpression(node) { if (MODE === "consistent") { checkConsistency(node, false); } if (MODE === "consistent-as-needed") { checkConsistency(node, true); } } }; } }; },{"../util/keywords":409,"espree":"espree"}],356:[function(require,module,exports){ /** * @fileoverview A rule to choose between single and double quote marks * @author Matt DuVall , Brandon Payton */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _templateObject = _taggedTemplateLiteral(["(^|[^\\])(\\\\)*[", "]"], ["(^|[^\\\\])(\\\\\\\\)*[", "]"]); function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ var QUOTE_SETTINGS = { double: { quote: "\"", alternateQuote: "'", description: "doublequote" }, single: { quote: "'", alternateQuote: "\"", description: "singlequote" }, backtick: { quote: "`", alternateQuote: "\"", description: "backtick" } }; // An unescaped newline is a newline preceded by an even number of backslashes. var UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw(_templateObject, Array.from(astUtils.LINEBREAKS).join(""))); /** * Switches quoting of javascript string between ' " and ` * escaping and unescaping as necessary. * Only escaping of the minimal set of characters is changed. * Note: escaping of newlines when switching from backtick to other quotes is not handled. * @param {string} str - A string to convert. * @returns {string} The string with changed quotes. * @private */ QUOTE_SETTINGS.double.convert = QUOTE_SETTINGS.single.convert = QUOTE_SETTINGS.backtick.convert = function (str) { var newQuote = this.quote; var oldQuote = str[0]; if (newQuote === oldQuote) { return str; } return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, function (match, escaped, newline) { if (escaped === oldQuote || oldQuote === "`" && escaped === "${") { return escaped; // unescape } if (match === newQuote || newQuote === "`" && match === "${") { return "\\" + match; // escape } if (newline && oldQuote === "`") { return "\\n"; // escape newlines } return match; }) + newQuote; }; var AVOID_ESCAPE = "avoid-escape"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce the consistent use of either backticks, double, or single quotes", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/quotes" }, fixable: "code", schema: [{ enum: ["single", "double", "backtick"] }, { anyOf: [{ enum: ["avoid-escape"] }, { type: "object", properties: { avoidEscape: { type: "boolean" }, allowTemplateLiterals: { type: "boolean" } }, additionalProperties: false }] }] }, create: function create(context) { var quoteOption = context.options[0], settings = QUOTE_SETTINGS[quoteOption || "double"], options = context.options[1], allowTemplateLiterals = options && options.allowTemplateLiterals === true, sourceCode = context.getSourceCode(); var avoidEscape = options && options.avoidEscape === true; // deprecated if (options === AVOID_ESCAPE) { avoidEscape = true; } /** * Determines if a given node is part of JSX syntax. * * This function returns `true` in the following cases: * * - `
` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`. * - `
foo
` ... If the literal is a text content, the parent of the literal is `JSXElement`. * - `<>foo` ... If the literal is a text content, the parent of the literal is `JSXFragment`. * * In particular, this function returns `false` in the following cases: * * - `
` * - `
{"foo"}
` * * In both cases, inside of the braces is handled as normal JavaScript. * The braces are `JSXExpressionContainer` nodes. * * @param {ASTNode} node The Literal node to check. * @returns {boolean} True if the node is a part of JSX, false if not. * @private */ function isJSXLiteral(node) { return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment"; } /** * Checks whether or not a given node is a directive. * The directive is a `ExpressionStatement` which has only a string literal. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is a directive. * @private */ function isDirective(node) { return node.type === "ExpressionStatement" && node.expression.type === "Literal" && typeof node.expression.value === "string"; } /** * Checks whether or not a given node is a part of directive prologues. * See also: http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is a part of directive prologues. * @private */ function isPartOfDirectivePrologue(node) { var block = node.parent.parent; if (block.type !== "Program" && (block.type !== "BlockStatement" || !astUtils.isFunction(block.parent))) { return false; } // Check the node is at a prologue. for (var i = 0; i < block.body.length; ++i) { var statement = block.body[i]; if (statement === node.parent) { return true; } if (!isDirective(statement)) { break; } } return false; } /** * Checks whether or not a given node is allowed as non backtick. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is allowed as non backtick. * @private */ function isAllowedAsNonBacktick(node) { var parent = node.parent; switch (parent.type) { // Directive Prologues. case "ExpressionStatement": return isPartOfDirectivePrologue(node); // LiteralPropertyName. case "Property": case "MethodDefinition": return parent.key === node && !parent.computed; // ModuleSpecifier. case "ImportDeclaration": case "ExportNamedDeclaration": case "ExportAllDeclaration": return parent.source === node; // Others don't allow. default: return false; } } /** * Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings. * @param {ASTNode} node - A TemplateLiteral node to check. * @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings. * @private */ function isUsingFeatureOfTemplateLiteral(node) { var hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi; if (hasTag) { return true; } var hasStringInterpolation = node.expressions.length > 0; if (hasStringInterpolation) { return true; } var isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw); if (isMultilineString) { return true; } return false; } return { Literal: function Literal(node) { var val = node.value, rawVal = node.raw; if (settings && typeof val === "string") { var isValid = quoteOption === "backtick" && isAllowedAsNonBacktick(node) || isJSXLiteral(node) || astUtils.isSurroundedBy(rawVal, settings.quote); if (!isValid && avoidEscape) { isValid = astUtils.isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.indexOf(settings.quote) >= 0; } if (!isValid) { context.report({ node: node, message: "Strings must use {{description}}.", data: { description: settings.description }, fix: function fix(fixer) { return fixer.replaceText(node, settings.convert(node.raw)); } }); } } }, TemplateLiteral: function TemplateLiteral(node) { // Don't throw an error if backticks are expected or a template literal feature is in use. if (allowTemplateLiterals || quoteOption === "backtick" || isUsingFeatureOfTemplateLiteral(node)) { return; } context.report({ node: node, message: "Strings must use {{description}}.", data: { description: settings.description }, fix: function fix(fixer) { if (isPartOfDirectivePrologue(node)) { /* * TemplateLiterals in a directive prologue aren't actually directives, but if they're * in the directive prologue, then fixing them might turn them into directives and change * the behavior of the code. */ return null; } return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); } }); } }; } }; },{"../util/ast-utils":405}],357:[function(require,module,exports){ /** * @fileoverview Rule to flag use of parseInt without a radix argument * @author James Allardice */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var MODE_ALWAYS = "always", MODE_AS_NEEDED = "as-needed"; /** * Checks whether a given variable is shadowed or not. * * @param {eslint-scope.Variable} variable - A variable to check. * @returns {boolean} `true` if the variable is shadowed. */ function isShadowed(variable) { return variable.defs.length >= 1; } /** * Checks whether a given node is a MemberExpression of `parseInt` method or not. * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a MemberExpression of `parseInt` * method. */ function isParseIntMethod(node) { return node.type === "MemberExpression" && !node.computed && node.property.type === "Identifier" && node.property.name === "parseInt"; } /** * Checks whether a given node is a valid value of radix or not. * * The following values are invalid. * * - A literal except numbers. * - undefined. * * @param {ASTNode} radix - A node of radix to check. * @returns {boolean} `true` if the node is valid. */ function isValidRadix(radix) { return !(radix.type === "Literal" && typeof radix.value !== "number" || radix.type === "Identifier" && radix.name === "undefined"); } /** * Checks whether a given node is a default value of radix or not. * * @param {ASTNode} radix - A node of radix to check. * @returns {boolean} `true` if the node is the literal node of `10`. */ function isDefaultRadix(radix) { return radix.type === "Literal" && radix.value === 10; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce the consistent use of the radix argument when using `parseInt()`", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/radix" }, schema: [{ enum: ["always", "as-needed"] }] }, create: function create(context) { var mode = context.options[0] || MODE_ALWAYS; /** * Checks the arguments of a given CallExpression node and reports it if it * offends this rule. * * @param {ASTNode} node - A CallExpression node to check. * @returns {void} */ function checkArguments(node) { var args = node.arguments; switch (args.length) { case 0: context.report({ node: node, message: "Missing parameters." }); break; case 1: if (mode === MODE_ALWAYS) { context.report({ node: node, message: "Missing radix parameter." }); } break; default: if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) { context.report({ node: node, message: "Redundant radix parameter." }); } else if (!isValidRadix(args[1])) { context.report({ node: node, message: "Invalid radix parameter." }); } break; } } return { "Program:exit": function ProgramExit() { var scope = context.getScope(); var variable = void 0; // Check `parseInt()` variable = astUtils.getVariableByName(scope, "parseInt"); if (!isShadowed(variable)) { variable.references.forEach(function (reference) { var node = reference.identifier; if (astUtils.isCallee(node)) { checkArguments(node.parent); } }); } // Check `Number.parseInt()` variable = astUtils.getVariableByName(scope, "Number"); if (!isShadowed(variable)) { variable.references.forEach(function (reference) { var node = reference.identifier.parent; if (isParseIntMethod(node) && astUtils.isCallee(node)) { checkArguments(node.parent); } }); } } }; } }; },{"../util/ast-utils":405}],358:[function(require,module,exports){ /** * @fileoverview disallow assignments that can lead to race conditions due to usage of `await` or `yield` * @author Teddy Katz */ "use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "disallow assignments that can lead to race conditions due to usage of `await` or `yield`", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/require-atomic-updates" }, fixable: null, schema: [], messages: { nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`." } }, create: function create(context) { var sourceCode = context.getSourceCode(); var identifierToSurroundingFunctionMap = new WeakMap(); var expressionsByCodePathSegment = new Map(); //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- var resolvedVariableCache = new WeakMap(); /** * Gets the variable scope around this variable reference * @param {ASTNode} identifier An `Identifier` AST node * @returns {Scope|null} An escope Scope */ function getScope(identifier) { for (var currentNode = identifier; currentNode; currentNode = currentNode.parent) { var scope = sourceCode.scopeManager.acquire(currentNode, true); if (scope) { return scope; } } return null; } /** * Resolves a given identifier to a given scope * @param {ASTNode} identifier An `Identifier` AST node * @param {Scope} scope An escope Scope * @returns {Variable|null} An escope Variable corresponding to the given identifier */ function resolveVariableInScope(identifier, scope) { return scope.variables.find(function (variable) { return variable.name === identifier.name; }) || (scope.upper ? resolveVariableInScope(identifier, scope.upper) : null); } /** * Resolves an identifier to a variable * @param {ASTNode} identifier An identifier node * @returns {Variable|null} The escope Variable that uses this identifier */ function resolveVariable(identifier) { if (!resolvedVariableCache.has(identifier)) { var surroundingScope = getScope(identifier); if (surroundingScope) { resolvedVariableCache.set(identifier, resolveVariableInScope(identifier, surroundingScope)); } else { resolvedVariableCache.set(identifier, null); } } return resolvedVariableCache.get(identifier); } /** * Checks if an expression is a variable that can only be observed within the given function. * @param {ASTNode} expression The expression to check * @param {ASTNode} surroundingFunction The function node * @returns {boolean} `true` if the expression is a variable which is local to the given function, and is never * referenced in a closure. */ function isLocalVariableWithoutEscape(expression, surroundingFunction) { if (expression.type !== "Identifier") { return false; } var variable = resolveVariable(expression); if (!variable) { return false; } return variable.references.every(function (reference) { return identifierToSurroundingFunctionMap.get(reference.identifier) === surroundingFunction; }) && variable.defs.every(function (def) { return identifierToSurroundingFunctionMap.get(def.name) === surroundingFunction; }); } /** * Reports an AssignmentExpression node that has a non-atomic update * @param {ASTNode} assignmentExpression The assignment that is potentially unsafe * @returns {void} */ function reportAssignment(assignmentExpression) { context.report({ node: assignmentExpression, messageId: "nonAtomicUpdate", data: { value: sourceCode.getText(assignmentExpression.left) } }); } var alreadyReportedAssignments = new WeakSet(); var AssignmentTrackerState = function () { function AssignmentTrackerState() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$openAssignmentsW = _ref.openAssignmentsWithoutReads, openAssignmentsWithoutReads = _ref$openAssignmentsW === undefined ? new Set() : _ref$openAssignmentsW, _ref$openAssignmentsW2 = _ref.openAssignmentsWithReads, openAssignmentsWithReads = _ref$openAssignmentsW2 === undefined ? new Set() : _ref$openAssignmentsW2; _classCallCheck(this, AssignmentTrackerState); this.openAssignmentsWithoutReads = openAssignmentsWithoutReads; this.openAssignmentsWithReads = openAssignmentsWithReads; } _createClass(AssignmentTrackerState, [{ key: "copy", value: function copy() { return new AssignmentTrackerState({ openAssignmentsWithoutReads: new Set(this.openAssignmentsWithoutReads), openAssignmentsWithReads: new Set(this.openAssignmentsWithReads) }); } }, { key: "merge", value: function merge(other) { var _this = this; var initialAssignmentsWithoutReadsCount = this.openAssignmentsWithoutReads.size; var initialAssignmentsWithReadsCount = this.openAssignmentsWithReads.size; other.openAssignmentsWithoutReads.forEach(function (assignment) { return _this.openAssignmentsWithoutReads.add(assignment); }); other.openAssignmentsWithReads.forEach(function (assignment) { return _this.openAssignmentsWithReads.add(assignment); }); return this.openAssignmentsWithoutReads.size > initialAssignmentsWithoutReadsCount || this.openAssignmentsWithReads.size > initialAssignmentsWithReadsCount; } }, { key: "enterAssignment", value: function enterAssignment(assignmentExpression) { (assignmentExpression.operator === "=" ? this.openAssignmentsWithoutReads : this.openAssignmentsWithReads).add(assignmentExpression); } }, { key: "exitAssignment", value: function exitAssignment(assignmentExpression) { this.openAssignmentsWithoutReads.delete(assignmentExpression); this.openAssignmentsWithReads.delete(assignmentExpression); } }, { key: "exitAwaitOrYield", value: function exitAwaitOrYield(node, surroundingFunction) { return [].concat(_toConsumableArray(this.openAssignmentsWithReads)).filter(function (assignment) { return !isLocalVariableWithoutEscape(assignment.left, surroundingFunction); }).forEach(function (assignment) { if (!alreadyReportedAssignments.has(assignment)) { reportAssignment(assignment); alreadyReportedAssignments.add(assignment); } }); } }, { key: "exitIdentifierOrMemberExpression", value: function exitIdentifierOrMemberExpression(node) { var _this2 = this; [].concat(_toConsumableArray(this.openAssignmentsWithoutReads)).filter(function (assignment) { return assignment.left !== node && assignment.left.type === node.type && astUtils.equalTokens(assignment.left, node, sourceCode); }).forEach(function (assignment) { _this2.openAssignmentsWithoutReads.delete(assignment); _this2.openAssignmentsWithReads.add(assignment); }); } }]); return AssignmentTrackerState; }(); /** * If the control flow graph of a function enters an assignment expression, then does the * both of the following steps in order (possibly with other steps in between) before exiting the * assignment expression, then the assignment might be using an outdated value. * 1. Enters a read of the variable or property assigned in the expression (not necessary if operator assignment is used) * 2. Exits an `await` or `yield` expression * * This function checks for the outdated values and reports them. * @param {CodePathSegment} codePathSegment The current code path segment to traverse * @param {ASTNode} surroundingFunction The function node containing the code path segment * @returns {void} */ function findOutdatedReads(codePathSegment, surroundingFunction) { var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, _ref2$stateBySegmentS = _ref2.stateBySegmentStart, stateBySegmentStart = _ref2$stateBySegmentS === undefined ? new WeakMap() : _ref2$stateBySegmentS, _ref2$stateBySegmentE = _ref2.stateBySegmentEnd, stateBySegmentEnd = _ref2$stateBySegmentE === undefined ? new WeakMap() : _ref2$stateBySegmentE; if (!stateBySegmentStart.has(codePathSegment)) { stateBySegmentStart.set(codePathSegment, new AssignmentTrackerState()); } var currentState = stateBySegmentStart.get(codePathSegment).copy(); expressionsByCodePathSegment.get(codePathSegment).forEach(function (_ref3) { var entering = _ref3.entering, node = _ref3.node; if (node.type === "AssignmentExpression") { if (entering) { currentState.enterAssignment(node); } else { currentState.exitAssignment(node); } } else if (!entering && (node.type === "AwaitExpression" || node.type === "YieldExpression")) { currentState.exitAwaitOrYield(node, surroundingFunction); } else if (!entering && (node.type === "Identifier" || node.type === "MemberExpression")) { currentState.exitIdentifierOrMemberExpression(node); } }); stateBySegmentEnd.set(codePathSegment, currentState); codePathSegment.nextSegments.forEach(function (nextSegment) { if (stateBySegmentStart.has(nextSegment)) { if (!stateBySegmentStart.get(nextSegment).merge(currentState)) { /* * This segment has already been processed with the given set of inputs; * no need to do it again. After no new state is available to process * for any control flow segment in the graph, the analysis reaches a fixpoint and * traversal stops. */ return; } } else { stateBySegmentStart.set(nextSegment, currentState.copy()); } findOutdatedReads(nextSegment, surroundingFunction, { stateBySegmentStart: stateBySegmentStart, stateBySegmentEnd: stateBySegmentEnd }); }); } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- var currentCodePathSegmentStack = []; var currentCodePathSegment = null; var functionStack = []; return { onCodePathStart: function onCodePathStart() { currentCodePathSegmentStack.push(currentCodePathSegment); }, onCodePathEnd: function onCodePathEnd(codePath, node) { currentCodePathSegment = currentCodePathSegmentStack.pop(); if (astUtils.isFunction(node) && (node.async || node.generator)) { findOutdatedReads(codePath.initialSegment, node); } }, onCodePathSegmentStart: function onCodePathSegmentStart(segment) { currentCodePathSegment = segment; expressionsByCodePathSegment.set(segment, []); }, "AssignmentExpression, Identifier, MemberExpression, AwaitExpression, YieldExpression": function AssignmentExpressionIdentifierMemberExpressionAwaitExpressionYieldExpression(node) { expressionsByCodePathSegment.get(currentCodePathSegment).push({ entering: true, node: node }); }, "AssignmentExpression, Identifier, MemberExpression, AwaitExpression, YieldExpression:exit": function AssignmentExpressionIdentifierMemberExpressionAwaitExpressionYieldExpressionExit(node) { expressionsByCodePathSegment.get(currentCodePathSegment).push({ entering: false, node: node }); }, ":function": function _function(node) { functionStack.push(node); }, ":function:exit": function functionExit() { functionStack.pop(); }, Identifier: function Identifier(node) { if (functionStack.length) { identifierToSurroundingFunctionMap.set(node, functionStack[functionStack.length - 1]); } } }; } }; },{"../util/ast-utils":405}],359:[function(require,module,exports){ /** * @fileoverview Rule to disallow async functions which have no `await` expression. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Capitalize the 1st letter of the given text. * * @param {string} text - The text to capitalize. * @returns {string} The text that the 1st letter was capitalized. */ function capitalizeFirstLetter(text) { return text[0].toUpperCase() + text.slice(1); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "disallow async functions which have no `await` expression", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/require-await" }, schema: [] }, create: function create(context) { var sourceCode = context.getSourceCode(); var scopeInfo = null; /** * Push the scope info object to the stack. * * @returns {void} */ function enterFunction() { scopeInfo = { upper: scopeInfo, hasAwait: false }; } /** * Pop the top scope info object from the stack. * Also, it reports the function if needed. * * @param {ASTNode} node - The node to report. * @returns {void} */ function exitFunction(node) { if (node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) { context.report({ node: node, loc: astUtils.getFunctionHeadLoc(node, sourceCode), message: "{{name}} has no 'await' expression.", data: { name: capitalizeFirstLetter(astUtils.getFunctionNameWithKind(node)) } }); } scopeInfo = scopeInfo.upper; } return { FunctionDeclaration: enterFunction, FunctionExpression: enterFunction, ArrowFunctionExpression: enterFunction, "FunctionDeclaration:exit": exitFunction, "FunctionExpression:exit": exitFunction, "ArrowFunctionExpression:exit": exitFunction, AwaitExpression: function AwaitExpression() { scopeInfo.hasAwait = true; }, ForOfStatement: function ForOfStatement(node) { if (node.await) { scopeInfo.hasAwait = true; } } }; } }; },{"../util/ast-utils":405}],360:[function(require,module,exports){ /** * @fileoverview Rule to check for jsdoc presence. * @author Gyandeep Singh */ "use strict"; module.exports = { meta: { type: "suggestion", docs: { description: "require JSDoc comments", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/require-jsdoc" }, schema: [{ type: "object", properties: { require: { type: "object", properties: { ClassDeclaration: { type: "boolean" }, MethodDefinition: { type: "boolean" }, FunctionDeclaration: { type: "boolean" }, ArrowFunctionExpression: { type: "boolean" }, FunctionExpression: { type: "boolean" } }, additionalProperties: false } }, additionalProperties: false }], deprecated: true, replacedBy: [] }, create: function create(context) { var source = context.getSourceCode(); var DEFAULT_OPTIONS = { FunctionDeclaration: true, MethodDefinition: false, ClassDeclaration: false, ArrowFunctionExpression: false, FunctionExpression: false }; var options = Object.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require || {}); /** * Report the error message * @param {ASTNode} node node to report * @returns {void} */ function report(node) { context.report({ node: node, message: "Missing JSDoc comment." }); } /** * Check if the jsdoc comment is present or not. * @param {ASTNode} node node to examine * @returns {void} */ function checkJsDoc(node) { var jsdocComment = source.getJSDocComment(node); if (!jsdocComment) { report(node); } } return { FunctionDeclaration: function FunctionDeclaration(node) { if (options.FunctionDeclaration) { checkJsDoc(node); } }, FunctionExpression: function FunctionExpression(node) { if (options.MethodDefinition && node.parent.type === "MethodDefinition" || options.FunctionExpression && (node.parent.type === "VariableDeclarator" || node.parent.type === "Property" && node === node.parent.value)) { checkJsDoc(node); } }, ClassDeclaration: function ClassDeclaration(node) { if (options.ClassDeclaration) { checkJsDoc(node); } }, ArrowFunctionExpression: function ArrowFunctionExpression(node) { if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") { checkJsDoc(node); } } }; } }; },{}],361:[function(require,module,exports){ /** * @fileoverview Rule to enforce the use of `u` flag on RegExp. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var _require = require("eslint-utils"), CALL = _require.CALL, CONSTRUCT = _require.CONSTRUCT, ReferenceTracker = _require.ReferenceTracker, getStringIfConstant = _require.getStringIfConstant; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce the use of `u` flag on RegExp", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/require-unicode-regexp" }, messages: { requireUFlag: "Use the 'u' flag." }, schema: [] }, create: function create(context) { return { "Literal[regex]": function LiteralRegex(node) { var flags = node.regex.flags || ""; if (!flags.includes("u")) { context.report({ node: node, messageId: "requireUFlag" }); } }, Program: function Program() { var _RegExp; var scope = context.getScope(); var tracker = new ReferenceTracker(scope); var trackMap = { RegExp: (_RegExp = {}, _defineProperty(_RegExp, CALL, true), _defineProperty(_RegExp, CONSTRUCT, true), _RegExp) }; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = tracker.iterateGlobalReferences(trackMap)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var node = _step.value.node; var flagsNode = node.arguments[1]; var flags = getStringIfConstant(flagsNode, scope); if (!flagsNode || typeof flags === "string" && !flags.includes("u")) { context.report({ node: node, messageId: "requireUFlag" }); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }; } }; },{"eslint-utils":68}],362:[function(require,module,exports){ /** * @fileoverview Rule to flag the generator functions that does not have yield. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require generator functions to contain `yield`", category: "ECMAScript 6", recommended: true, url: "https://eslint.org/docs/rules/require-yield" }, schema: [] }, create: function create(context) { var stack = []; /** * If the node is a generator function, start counting `yield` keywords. * @param {Node} node - A function node to check. * @returns {void} */ function beginChecking(node) { if (node.generator) { stack.push(0); } } /** * If the node is a generator function, end counting `yield` keywords, then * reports result. * @param {Node} node - A function node to check. * @returns {void} */ function endChecking(node) { if (!node.generator) { return; } var countYield = stack.pop(); if (countYield === 0 && node.body.body.length > 0) { context.report({ node: node, message: "This generator function does not have 'yield'." }); } } return { FunctionDeclaration: beginChecking, "FunctionDeclaration:exit": endChecking, FunctionExpression: beginChecking, "FunctionExpression:exit": endChecking, // Increases the count of `yield` keyword. YieldExpression: function YieldExpression() { /* istanbul ignore else */ if (stack.length > 0) { stack[stack.length - 1] += 1; } } }; } }; },{}],363:[function(require,module,exports){ /** * @fileoverview Enforce spacing between rest and spread operators and their expressions. * @author Kai Cataldo */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce spacing between rest and spread operators and their expressions", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/rest-spread-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }] }, create: function create(context) { var sourceCode = context.getSourceCode(), alwaysSpace = context.options[0] === "always"; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Checks whitespace between rest/spread operators and their expressions * @param {ASTNode} node - The node to check * @returns {void} */ function checkWhiteSpace(node) { var operator = sourceCode.getFirstToken(node), nextToken = sourceCode.getTokenAfter(operator), hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken); var type = void 0; switch (node.type) { case "SpreadElement": type = "spread"; if (node.parent.type === "ObjectExpression") { type += " property"; } break; case "RestElement": type = "rest"; if (node.parent.type === "ObjectPattern") { type += " property"; } break; case "ExperimentalSpreadProperty": type = "spread property"; break; case "ExperimentalRestProperty": type = "rest property"; break; default: return; } if (alwaysSpace && !hasWhitespace) { context.report({ node: node, loc: { line: operator.loc.end.line, column: operator.loc.end.column }, message: "Expected whitespace after {{type}} operator.", data: { type: type }, fix: function fix(fixer) { return fixer.replaceTextRange([operator.range[1], nextToken.range[0]], " "); } }); } else if (!alwaysSpace && hasWhitespace) { context.report({ node: node, loc: { line: operator.loc.end.line, column: operator.loc.end.column }, message: "Unexpected whitespace after {{type}} operator.", data: { type: type }, fix: function fix(fixer) { return fixer.removeRange([operator.range[1], nextToken.range[0]]); } }); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { SpreadElement: checkWhiteSpace, RestElement: checkWhiteSpace, ExperimentalSpreadProperty: checkWhiteSpace, ExperimentalRestProperty: checkWhiteSpace }; } }; },{}],364:[function(require,module,exports){ /** * @fileoverview Validates spacing before and after semicolon * @author Mathias Schreck */ "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before and after semicolons", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/semi-spacing" }, fixable: "whitespace", schema: [{ type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var config = context.options[0], sourceCode = context.getSourceCode(); var requireSpaceBefore = false, requireSpaceAfter = true; if ((typeof config === "undefined" ? "undefined" : _typeof(config)) === "object") { if (Object.prototype.hasOwnProperty.call(config, "before")) { requireSpaceBefore = config.before; } if (Object.prototype.hasOwnProperty.call(config, "after")) { requireSpaceAfter = config.after; } } /** * Checks if a given token has leading whitespace. * @param {Object} token The token to check. * @returns {boolean} True if the given token has leading space, false if not. */ function hasLeadingSpace(token) { var tokenBefore = sourceCode.getTokenBefore(token); return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token); } /** * Checks if a given token has trailing whitespace. * @param {Object} token The token to check. * @returns {boolean} True if the given token has trailing space, false if not. */ function hasTrailingSpace(token) { var tokenAfter = sourceCode.getTokenAfter(token); return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter); } /** * Checks if the given token is the last token in its line. * @param {Token} token The token to check. * @returns {boolean} Whether or not the token is the last in its line. */ function isLastTokenInCurrentLine(token) { var tokenAfter = sourceCode.getTokenAfter(token); return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter)); } /** * Checks if the given token is the first token in its line * @param {Token} token The token to check. * @returns {boolean} Whether or not the token is the first in its line. */ function isFirstTokenInCurrentLine(token) { var tokenBefore = sourceCode.getTokenBefore(token); return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore)); } /** * Checks if the next token of a given token is a closing parenthesis. * @param {Token} token The token to check. * @returns {boolean} Whether or not the next token of a given token is a closing parenthesis. */ function isBeforeClosingParen(token) { var nextToken = sourceCode.getTokenAfter(token); return nextToken && astUtils.isClosingBraceToken(nextToken) || astUtils.isClosingParenToken(nextToken); } /** * Reports if the given token has invalid spacing. * @param {Token} token The semicolon token to check. * @param {ASTNode} node The corresponding node of the token. * @returns {void} */ function checkSemicolonSpacing(token, node) { if (astUtils.isSemicolonToken(token)) { var location = token.loc.start; if (hasLeadingSpace(token)) { if (!requireSpaceBefore) { context.report({ node: node, loc: location, message: "Unexpected whitespace before semicolon.", fix: function fix(fixer) { var tokenBefore = sourceCode.getTokenBefore(token); return fixer.removeRange([tokenBefore.range[1], token.range[0]]); } }); } } else { if (requireSpaceBefore) { context.report({ node: node, loc: location, message: "Missing whitespace before semicolon.", fix: function fix(fixer) { return fixer.insertTextBefore(token, " "); } }); } } if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) { if (hasTrailingSpace(token)) { if (!requireSpaceAfter) { context.report({ node: node, loc: location, message: "Unexpected whitespace after semicolon.", fix: function fix(fixer) { var tokenAfter = sourceCode.getTokenAfter(token); return fixer.removeRange([token.range[1], tokenAfter.range[0]]); } }); } } else { if (requireSpaceAfter) { context.report({ node: node, loc: location, message: "Missing whitespace after semicolon.", fix: function fix(fixer) { return fixer.insertTextAfter(token, " "); } }); } } } } } /** * Checks the spacing of the semicolon with the assumption that the last token is the semicolon. * @param {ASTNode} node The node to check. * @returns {void} */ function checkNode(node) { var token = sourceCode.getLastToken(node); checkSemicolonSpacing(token, node); } return { VariableDeclaration: checkNode, ExpressionStatement: checkNode, BreakStatement: checkNode, ContinueStatement: checkNode, DebuggerStatement: checkNode, ReturnStatement: checkNode, ThrowStatement: checkNode, ImportDeclaration: checkNode, ExportNamedDeclaration: checkNode, ExportAllDeclaration: checkNode, ExportDefaultDeclaration: checkNode, ForStatement: function ForStatement(node) { if (node.init) { checkSemicolonSpacing(sourceCode.getTokenAfter(node.init), node); } if (node.test) { checkSemicolonSpacing(sourceCode.getTokenAfter(node.test), node); } } }; } }; },{"../util/ast-utils":405}],365:[function(require,module,exports){ /** * @fileoverview Rule to enforce location of semicolons. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ var SELECTOR = ":matches(" + ["BreakStatement", "ContinueStatement", "DebuggerStatement", "DoWhileStatement", "ExportAllDeclaration", "ExportDefaultDeclaration", "ExportNamedDeclaration", "ExpressionStatement", "ImportDeclaration", "ReturnStatement", "ThrowStatement", "VariableDeclaration"].join(",") + ")"; /** * Get the child node list of a given node. * This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`. * This is used to check whether a node is the first/last child. * @param {Node} node A node to get child node list. * @returns {Node[]|null} The child node list. */ function getChildren(node) { var t = node.type; if (t === "BlockStatement" || t === "Program") { return node.body; } if (t === "SwitchCase") { return node.consequent; } return null; } /** * Check whether a given node is the last statement in the parent block. * @param {Node} node A node to check. * @returns {boolean} `true` if the node is the last statement in the parent block. */ function isLastChild(node) { var t = node.parent.type; if (t === "IfStatement" && node.parent.consequent === node && node.parent.alternate) { // before `else` keyword. return true; } if (t === "DoWhileStatement") { // before `while` keyword. return true; } var nodeList = getChildren(node.parent); return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc. } module.exports = { meta: { type: "layout", docs: { description: "enforce location of semicolons", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/semi-style" }, schema: [{ enum: ["last", "first"] }], fixable: "whitespace" }, create: function create(context) { var _ref; var sourceCode = context.getSourceCode(); var option = context.options[0] || "last"; /** * Check the given semicolon token. * @param {Token} semiToken The semicolon token to check. * @param {"first"|"last"} expected The expected location to check. * @returns {void} */ function check(semiToken, expected) { var prevToken = sourceCode.getTokenBefore(semiToken); var nextToken = sourceCode.getTokenAfter(semiToken); var prevIsSameLine = !prevToken || astUtils.isTokenOnSameLine(prevToken, semiToken); var nextIsSameLine = !nextToken || astUtils.isTokenOnSameLine(semiToken, nextToken); if (expected === "last" && !prevIsSameLine || expected === "first" && !nextIsSameLine) { context.report({ loc: semiToken.loc, message: "Expected this semicolon to be at {{pos}}.", data: { pos: expected === "last" ? "the end of the previous line" : "the beginning of the next line" }, fix: function fix(fixer) { if (prevToken && nextToken && sourceCode.commentsExistBetween(prevToken, nextToken)) { return null; } var start = prevToken ? prevToken.range[1] : semiToken.range[0]; var end = nextToken ? nextToken.range[0] : semiToken.range[1]; var text = expected === "last" ? ";\n" : "\n;"; return fixer.replaceTextRange([start, end], text); } }); } } return _ref = {}, _defineProperty(_ref, SELECTOR, function (node) { if (option === "first" && isLastChild(node)) { return; } var lastToken = sourceCode.getLastToken(node); if (astUtils.isSemicolonToken(lastToken)) { check(lastToken, option); } }), _defineProperty(_ref, "ForStatement", function ForStatement(node) { var firstSemi = node.init && sourceCode.getTokenAfter(node.init, astUtils.isSemicolonToken); var secondSemi = node.test && sourceCode.getTokenAfter(node.test, astUtils.isSemicolonToken); if (firstSemi) { check(firstSemi, "last"); } if (secondSemi) { check(secondSemi, "last"); } }), _ref; } }; },{"../util/ast-utils":405}],366:[function(require,module,exports){ /** * @fileoverview Rule to flag missing semicolons. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var FixTracker = require("../util/fix-tracker"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow semicolons instead of ASI", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/semi" }, fixable: "code", schema: { anyOf: [{ type: "array", items: [{ enum: ["never"] }, { type: "object", properties: { beforeStatementContinuationChars: { enum: ["always", "any", "never"] } }, additionalProperties: false }], minItems: 0, maxItems: 2 }, { type: "array", items: [{ enum: ["always"] }, { type: "object", properties: { omitLastInOneLineBlock: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] } }, create: function create(context) { var OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-` var options = context.options[1]; var never = context.options[0] === "never"; var exceptOneLine = Boolean(options && options.omitLastInOneLineBlock); var beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any"; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Reports a semicolon error with appropriate location and message. * @param {ASTNode} node The node with an extra or missing semicolon. * @param {boolean} missing True if the semicolon is missing. * @returns {void} */ function report(node, missing) { var lastToken = sourceCode.getLastToken(node); var message = void 0, fix = void 0, loc = lastToken.loc; if (!missing) { message = "Missing semicolon."; loc = loc.end; fix = function fix(fixer) { return fixer.insertTextAfter(lastToken, ";"); }; } else { message = "Extra semicolon."; loc = loc.start; fix = function fix(fixer) { /* * Expand the replacement range to include the surrounding * tokens to avoid conflicting with no-extra-semi. * https://github.com/eslint/eslint/issues/7928 */ return new FixTracker(fixer, sourceCode).retainSurroundingTokens(lastToken).remove(lastToken); }; } context.report({ node: node, loc: loc, message: message, fix: fix }); } /** * Check whether a given semicolon token is redandant. * @param {Token} semiToken A semicolon token to check. * @returns {boolean} `true` if the next token is `;` or `}`. */ function isRedundantSemi(semiToken) { var nextToken = sourceCode.getTokenAfter(semiToken); return !nextToken || astUtils.isClosingBraceToken(nextToken) || astUtils.isSemicolonToken(nextToken); } /** * Check whether a given token is the closing brace of an arrow function. * @param {Token} lastToken A token to check. * @returns {boolean} `true` if the token is the closing brace of an arrow function. */ function isEndOfArrowBlock(lastToken) { if (!astUtils.isClosingBraceToken(lastToken)) { return false; } var node = sourceCode.getNodeByRangeIndex(lastToken.range[0]); return node.type === "BlockStatement" && node.parent.type === "ArrowFunctionExpression"; } /** * Check whether a given node is on the same line with the next token. * @param {Node} node A statement node to check. * @returns {boolean} `true` if the node is on the same line with the next token. */ function isOnSameLineWithNextToken(node) { var prevToken = sourceCode.getLastToken(node, 1); var nextToken = sourceCode.getTokenAfter(node); return !!nextToken && astUtils.isTokenOnSameLine(prevToken, nextToken); } /** * Check whether a given node can connect the next line if the next line is unreliable. * @param {Node} node A statement node to check. * @returns {boolean} `true` if the node can connect the next line. */ function maybeAsiHazardAfter(node) { var t = node.type; if (t === "DoWhileStatement" || t === "BreakStatement" || t === "ContinueStatement" || t === "DebuggerStatement" || t === "ImportDeclaration" || t === "ExportAllDeclaration") { return false; } if (t === "ReturnStatement") { return Boolean(node.argument); } if (t === "ExportNamedDeclaration") { return Boolean(node.declaration); } if (isEndOfArrowBlock(sourceCode.getLastToken(node, 1))) { return false; } return true; } /** * Check whether a given token can connect the previous statement. * @param {Token} token A token to check. * @returns {boolean} `true` if the token is one of `[`, `(`, `/`, `+`, `-`, ```, `++`, and `--`. */ function maybeAsiHazardBefore(token) { return Boolean(token) && OPT_OUT_PATTERN.test(token.value) && token.value !== "++" && token.value !== "--"; } /** * Check if the semicolon of a given node is unnecessary, only true if: * - next token is a valid statement divider (`;` or `}`). * - next token is on a new line and the node is not connectable to the new line. * @param {Node} node A statement node to check. * @returns {boolean} whether the semicolon is unnecessary. */ function canRemoveSemicolon(node) { if (isRedundantSemi(sourceCode.getLastToken(node))) { return true; // `;;` or `;}` } if (isOnSameLineWithNextToken(node)) { return false; // One liner. } if (beforeStatementContinuationChars === "never" && !maybeAsiHazardAfter(node)) { return true; // ASI works. This statement doesn't connect to the next. } if (!maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { return true; // ASI works. The next token doesn't connect to this statement. } return false; } /** * Checks a node to see if it's in a one-liner block statement. * @param {ASTNode} node The node to check. * @returns {boolean} whether the node is in a one-liner block statement. */ function isOneLinerBlock(node) { var parent = node.parent; var nextToken = sourceCode.getTokenAfter(node); if (!nextToken || nextToken.value !== "}") { return false; } return !!parent && parent.type === "BlockStatement" && parent.loc.start.line === parent.loc.end.line; } /** * Checks a node to see if it's followed by a semicolon. * @param {ASTNode} node The node to check. * @returns {void} */ function checkForSemicolon(node) { var isSemi = astUtils.isSemicolonToken(sourceCode.getLastToken(node)); if (never) { if (isSemi && canRemoveSemicolon(node)) { report(node, true); } else if (!isSemi && beforeStatementContinuationChars === "always" && maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { report(node); } } else { var oneLinerBlock = exceptOneLine && isOneLinerBlock(node); if (isSemi && oneLinerBlock) { report(node, true); } else if (!isSemi && !oneLinerBlock) { report(node); } } } /** * Checks to see if there's a semicolon after a variable declaration. * @param {ASTNode} node The node to check. * @returns {void} */ function checkForSemicolonForVariableDeclaration(node) { var parent = node.parent; if ((parent.type !== "ForStatement" || parent.init !== node) && (!/^For(?:In|Of)Statement/.test(parent.type) || parent.left !== node)) { checkForSemicolon(node); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { VariableDeclaration: checkForSemicolonForVariableDeclaration, ExpressionStatement: checkForSemicolon, ReturnStatement: checkForSemicolon, ThrowStatement: checkForSemicolon, DoWhileStatement: checkForSemicolon, DebuggerStatement: checkForSemicolon, BreakStatement: checkForSemicolon, ContinueStatement: checkForSemicolon, ImportDeclaration: checkForSemicolon, ExportAllDeclaration: checkForSemicolon, ExportNamedDeclaration: function ExportNamedDeclaration(node) { if (!node.declaration) { checkForSemicolon(node); } }, ExportDefaultDeclaration: function ExportDefaultDeclaration(node) { if (!/(?:Class|Function)Declaration/.test(node.declaration.type)) { checkForSemicolon(node); } } }; } }; },{"../util/ast-utils":405,"../util/fix-tracker":407}],367:[function(require,module,exports){ /** * @fileoverview Rule to require sorting of import declarations * @author Christian Schuller */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce sorted import declarations within modules", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/sort-imports" }, schema: [{ type: "object", properties: { ignoreCase: { type: "boolean" }, memberSyntaxSortOrder: { type: "array", items: { enum: ["none", "all", "multiple", "single"] }, uniqueItems: true, minItems: 4, maxItems: 4 }, ignoreMemberSort: { type: "boolean" } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { var configuration = context.options[0] || {}, ignoreCase = configuration.ignoreCase || false, ignoreMemberSort = configuration.ignoreMemberSort || false, memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"], sourceCode = context.getSourceCode(); var previousDeclaration = null; /** * Gets the used member syntax style. * * import "my-module.js" --> none * import * as myModule from "my-module.js" --> all * import {myMember} from "my-module.js" --> single * import {foo, bar} from "my-module.js" --> multiple * * @param {ASTNode} node - the ImportDeclaration node. * @returns {string} used member parameter style, ["all", "multiple", "single"] */ function usedMemberSyntax(node) { if (node.specifiers.length === 0) { return "none"; } if (node.specifiers[0].type === "ImportNamespaceSpecifier") { return "all"; } if (node.specifiers.length === 1) { return "single"; } return "multiple"; } /** * Gets the group by member parameter index for given declaration. * @param {ASTNode} node - the ImportDeclaration node. * @returns {number} the declaration group by member index. */ function getMemberParameterGroupIndex(node) { return memberSyntaxSortOrder.indexOf(usedMemberSyntax(node)); } /** * Gets the local name of the first imported module. * @param {ASTNode} node - the ImportDeclaration node. * @returns {?string} the local name of the first imported module. */ function getFirstLocalMemberName(node) { if (node.specifiers[0]) { return node.specifiers[0].local.name; } return null; } return { ImportDeclaration: function ImportDeclaration(node) { if (previousDeclaration) { var currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node), previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration); var currentLocalMemberName = getFirstLocalMemberName(node), previousLocalMemberName = getFirstLocalMemberName(previousDeclaration); if (ignoreCase) { previousLocalMemberName = previousLocalMemberName && previousLocalMemberName.toLowerCase(); currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase(); } /* * When the current declaration uses a different member syntax, * then check if the ordering is correct. * Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name. */ if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) { if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) { context.report({ node: node, message: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax.", data: { syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex], syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex] } }); } } else { if (previousLocalMemberName && currentLocalMemberName && currentLocalMemberName < previousLocalMemberName) { context.report({ node: node, message: "Imports should be sorted alphabetically." }); } } } if (!ignoreMemberSort) { var importSpecifiers = node.specifiers.filter(function (specifier) { return specifier.type === "ImportSpecifier"; }); var getSortableName = ignoreCase ? function (specifier) { return specifier.local.name.toLowerCase(); } : function (specifier) { return specifier.local.name; }; var firstUnsortedIndex = importSpecifiers.map(getSortableName).findIndex(function (name, index, array) { return array[index - 1] > name; }); if (firstUnsortedIndex !== -1) { context.report({ node: importSpecifiers[firstUnsortedIndex], message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.", data: { memberName: importSpecifiers[firstUnsortedIndex].local.name }, fix: function fix(fixer) { if (importSpecifiers.some(function (specifier) { return sourceCode.getCommentsBefore(specifier).length || sourceCode.getCommentsAfter(specifier).length; })) { // If there are comments in the ImportSpecifier list, don't rearrange the specifiers. return null; } return fixer.replaceTextRange([importSpecifiers[0].range[0], importSpecifiers[importSpecifiers.length - 1].range[1]], importSpecifiers // Clone the importSpecifiers array to avoid mutating it .slice() // Sort the array into the desired order .sort(function (specifierA, specifierB) { var aName = getSortableName(specifierA); var bName = getSortableName(specifierB); return aName > bName ? 1 : -1; }) // Build a string out of the sorted list of import specifiers and the text between the originals .reduce(function (sourceText, specifier, index) { var textAfterSpecifier = index === importSpecifiers.length - 1 ? "" : sourceCode.getText().slice(importSpecifiers[index].range[1], importSpecifiers[index + 1].range[0]); return sourceText + sourceCode.getText(specifier) + textAfterSpecifier; }, "")); } }); } } previousDeclaration = node; } }; } }; },{}],368:[function(require,module,exports){ /** * @fileoverview Rule to require object keys to be sorted * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"), naturalCompare = require("natural-compare"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets the property name of the given `Property` node. * * - If the property's key is an `Identifier` node, this returns the key's name * whether it's a computed property or not. * - If the property has a static name, this returns the static name. * - Otherwise, this returns null. * * @param {ASTNode} node - The `Property` node to get. * @returns {string|null} The property name or null. * @private */ function getPropertyName(node) { return astUtils.getStaticPropertyName(node) || node.key.name || null; } /** * Functions which check that the given 2 names are in specific order. * * Postfix `I` is meant insensitive. * Postfix `N` is meant natual. * * @private */ var isValidOrders = { asc: function asc(a, b) { return a <= b; }, ascI: function ascI(a, b) { return a.toLowerCase() <= b.toLowerCase(); }, ascN: function ascN(a, b) { return naturalCompare(a, b) <= 0; }, ascIN: function ascIN(a, b) { return naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0; }, desc: function desc(a, b) { return isValidOrders.asc(b, a); }, descI: function descI(a, b) { return isValidOrders.ascI(b, a); }, descN: function descN(a, b) { return isValidOrders.ascN(b, a); }, descIN: function descIN(a, b) { return isValidOrders.ascIN(b, a); } }; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require object keys to be sorted", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/sort-keys" }, schema: [{ enum: ["asc", "desc"] }, { type: "object", properties: { caseSensitive: { type: "boolean" }, natural: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { // Parse options. var order = context.options[0] || "asc"; var options = context.options[1]; var insensitive = (options && options.caseSensitive) === false; var natual = Boolean(options && options.natural); var isValidOrder = isValidOrders[order + (insensitive ? "I" : "") + (natual ? "N" : "")]; // The stack to save the previous property's name for each object literals. var stack = null; return { ObjectExpression: function ObjectExpression() { stack = { upper: stack, prevName: null }; }, "ObjectExpression:exit": function ObjectExpressionExit() { stack = stack.upper; }, Property: function Property(node) { if (node.parent.type === "ObjectPattern" || node.parent.properties.some(function (n) { return n.type === "SpreadElement"; })) { return; } var prevName = stack.prevName; var thisName = getPropertyName(node); stack.prevName = thisName || prevName; if (!prevName || !thisName) { return; } if (!isValidOrder(prevName, thisName)) { context.report({ node: node, loc: node.key.loc, message: "Expected object keys to be in {{natual}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'.", data: { thisName: thisName, prevName: prevName, order: order, insensitive: insensitive ? "insensitive " : "", natual: natual ? "natural " : "" } }); } } }; } }; },{"../util/ast-utils":405,"natural-compare":95}],369:[function(require,module,exports){ /** * @fileoverview Rule to require sorting of variables within a single Variable Declaration block * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require variables within the same declaration block to be sorted", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/sort-vars" }, schema: [{ type: "object", properties: { ignoreCase: { type: "boolean" } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { var configuration = context.options[0] || {}, ignoreCase = configuration.ignoreCase || false, sourceCode = context.getSourceCode(); return { VariableDeclaration: function VariableDeclaration(node) { var idDeclarations = node.declarations.filter(function (decl) { return decl.id.type === "Identifier"; }); var getSortableName = ignoreCase ? function (decl) { return decl.id.name.toLowerCase(); } : function (decl) { return decl.id.name; }; var unfixable = idDeclarations.some(function (decl) { return decl.init !== null && decl.init.type !== "Literal"; }); var fixed = false; idDeclarations.slice(1).reduce(function (memo, decl) { var lastVariableName = getSortableName(memo), currentVariableName = getSortableName(decl); if (currentVariableName < lastVariableName) { context.report({ node: decl, message: "Variables within the same declaration block should be sorted alphabetically.", fix: function fix(fixer) { if (unfixable || fixed) { return null; } return fixer.replaceTextRange([idDeclarations[0].range[0], idDeclarations[idDeclarations.length - 1].range[1]], idDeclarations // Clone the idDeclarations array to avoid mutating it .slice() // Sort the array into the desired order .sort(function (declA, declB) { var aName = getSortableName(declA); var bName = getSortableName(declB); return aName > bName ? 1 : -1; }) // Build a string out of the sorted list of identifier declarations and the text between the originals .reduce(function (sourceText, identifier, index) { var textAfterIdentifier = index === idDeclarations.length - 1 ? "" : sourceCode.getText().slice(idDeclarations[index].range[1], idDeclarations[index + 1].range[0]); return sourceText + sourceCode.getText(identifier) + textAfterIdentifier; }, "")); } }); fixed = true; return memo; } return decl; }, idDeclarations[0]); } }; } }; },{}],370:[function(require,module,exports){ /** * @fileoverview A rule to ensure whitespace before blocks. * @author Mathias Schreck */ "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before blocks", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/space-before-blocks" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["always", "never"] }, { type: "object", properties: { keywords: { enum: ["always", "never", "off"] }, functions: { enum: ["always", "never", "off"] }, classes: { enum: ["always", "never", "off"] } }, additionalProperties: false }] }] }, create: function create(context) { var config = context.options[0], sourceCode = context.getSourceCode(); var alwaysFunctions = true, alwaysKeywords = true, alwaysClasses = true, neverFunctions = false, neverKeywords = false, neverClasses = false; if ((typeof config === "undefined" ? "undefined" : _typeof(config)) === "object") { alwaysFunctions = config.functions === "always"; alwaysKeywords = config.keywords === "always"; alwaysClasses = config.classes === "always"; neverFunctions = config.functions === "never"; neverKeywords = config.keywords === "never"; neverClasses = config.classes === "never"; } else if (config === "never") { alwaysFunctions = false; alwaysKeywords = false; alwaysClasses = false; neverFunctions = true; neverKeywords = true; neverClasses = true; } /** * Checks whether or not a given token is an arrow operator (=>) or a keyword * in order to avoid to conflict with `arrow-spacing` and `keyword-spacing`. * * @param {Token} token - A token to check. * @returns {boolean} `true` if the token is an arrow operator. */ function isConflicted(token) { return token.type === "Punctuator" && token.value === "=>" || token.type === "Keyword"; } /** * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line. * @param {ASTNode|Token} node The AST node of a BlockStatement. * @returns {void} undefined. */ function checkPrecedingSpace(node) { var precedingToken = sourceCode.getTokenBefore(node); if (precedingToken && !isConflicted(precedingToken) && astUtils.isTokenOnSameLine(precedingToken, node)) { var hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node); var parent = context.getAncestors().pop(); var requireSpace = void 0; var requireNoSpace = void 0; if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") { requireSpace = alwaysFunctions; requireNoSpace = neverFunctions; } else if (node.type === "ClassBody") { requireSpace = alwaysClasses; requireNoSpace = neverClasses; } else { requireSpace = alwaysKeywords; requireNoSpace = neverKeywords; } if (requireSpace && !hasSpace) { context.report({ node: node, message: "Missing space before opening brace.", fix: function fix(fixer) { return fixer.insertTextBefore(node, " "); } }); } else if (requireNoSpace && hasSpace) { context.report({ node: node, message: "Unexpected space before opening brace.", fix: function fix(fixer) { return fixer.removeRange([precedingToken.range[1], node.range[0]]); } }); } } } /** * Checks if the CaseBlock of an given SwitchStatement node has a preceding space. * @param {ASTNode} node The node of a SwitchStatement. * @returns {void} undefined. */ function checkSpaceBeforeCaseBlock(node) { var cases = node.cases; var openingBrace = void 0; if (cases.length > 0) { openingBrace = sourceCode.getTokenBefore(cases[0]); } else { openingBrace = sourceCode.getLastToken(node, 1); } checkPrecedingSpace(openingBrace); } return { BlockStatement: checkPrecedingSpace, ClassBody: checkPrecedingSpace, SwitchStatement: checkSpaceBeforeCaseBlock }; } }; },{"../util/ast-utils":405}],371:[function(require,module,exports){ /** * @fileoverview Rule to validate spacing before function paren. * @author Mathias Schreck */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before `function` definition opening parenthesis", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/space-before-function-paren" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["always", "never"] }, { type: "object", properties: { anonymous: { enum: ["always", "never", "ignore"] }, named: { enum: ["always", "never", "ignore"] }, asyncArrow: { enum: ["always", "never", "ignore"] } }, additionalProperties: false }] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var baseConfig = typeof context.options[0] === "string" ? context.options[0] : "always"; var overrideConfig = _typeof(context.options[0]) === "object" ? context.options[0] : {}; /** * Determines whether a function has a name. * @param {ASTNode} node The function node. * @returns {boolean} Whether the function has a name. */ function isNamedFunction(node) { if (node.id) { return true; } var parent = node.parent; return parent.type === "MethodDefinition" || parent.type === "Property" && (parent.kind === "get" || parent.kind === "set" || parent.method); } /** * Gets the config for a given function * @param {ASTNode} node The function node * @returns {string} "always", "never", or "ignore" */ function getConfigForFunction(node) { if (node.type === "ArrowFunctionExpression") { // Always ignore non-async functions and arrow functions without parens, e.g. async foo => bar if (node.async && astUtils.isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 }))) { return overrideConfig.asyncArrow || baseConfig; } } else if (isNamedFunction(node)) { return overrideConfig.named || baseConfig; // `generator-star-spacing` should warn anonymous generators. E.g. `function* () {}` } else if (!node.generator) { return overrideConfig.anonymous || baseConfig; } return "ignore"; } /** * Checks the parens of a function node * @param {ASTNode} node A function node * @returns {void} */ function checkFunction(node) { var functionConfig = getConfigForFunction(node); if (functionConfig === "ignore") { return; } var rightToken = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); var leftToken = sourceCode.getTokenBefore(rightToken); var hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken); if (hasSpacing && functionConfig === "never") { context.report({ node: node, loc: leftToken.loc.end, message: "Unexpected space before function parentheses.", fix: function fix(fixer) { return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); } }); } else if (!hasSpacing && functionConfig === "always") { context.report({ node: node, loc: leftToken.loc.end, message: "Missing space before function parentheses.", fix: function fix(fixer) { return fixer.insertTextAfter(leftToken, " "); } }); } } return { ArrowFunctionExpression: checkFunction, FunctionDeclaration: checkFunction, FunctionExpression: checkFunction }; } }; },{"../util/ast-utils":405}],372:[function(require,module,exports){ /** * @fileoverview Disallows or enforces spaces inside of parentheses. * @author Jonathan Rajavuori */ "use strict"; var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing inside parentheses", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/space-in-parens" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }, { type: "object", properties: { exceptions: { type: "array", items: { enum: ["{}", "[]", "()", "empty"] }, uniqueItems: true } }, additionalProperties: false }] }, create: function create(context) { var MISSING_SPACE_MESSAGE = "There must be a space inside this paren.", REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.", ALWAYS = context.options[0] === "always", exceptionsArrayOptions = context.options[1] && context.options[1].exceptions || [], options = {}; var exceptions = void 0; if (exceptionsArrayOptions.length) { options.braceException = exceptionsArrayOptions.indexOf("{}") !== -1; options.bracketException = exceptionsArrayOptions.indexOf("[]") !== -1; options.parenException = exceptionsArrayOptions.indexOf("()") !== -1; options.empty = exceptionsArrayOptions.indexOf("empty") !== -1; } /** * Produces an object with the opener and closer exception values * @returns {Object} `openers` and `closers` exception values * @private */ function getExceptions() { var openers = [], closers = []; if (options.braceException) { openers.push("{"); closers.push("}"); } if (options.bracketException) { openers.push("["); closers.push("]"); } if (options.parenException) { openers.push("("); closers.push(")"); } if (options.empty) { openers.push(")"); closers.push("("); } return { openers: openers, closers: closers }; } //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- var sourceCode = context.getSourceCode(); /** * Determines if a token is one of the exceptions for the opener paren * @param {Object} token The token to check * @returns {boolean} True if the token is one of the exceptions for the opener paren */ function isOpenerException(token) { return token.type === "Punctuator" && exceptions.openers.indexOf(token.value) >= 0; } /** * Determines if a token is one of the exceptions for the closer paren * @param {Object} token The token to check * @returns {boolean} True if the token is one of the exceptions for the closer paren */ function isCloserException(token) { return token.type === "Punctuator" && exceptions.closers.indexOf(token.value) >= 0; } /** * Determines if an opener paren should have a missing space after it * @param {Object} left The paren token * @param {Object} right The token after it * @returns {boolean} True if the paren should have a space */ function shouldOpenerHaveSpace(left, right) { if (sourceCode.isSpaceBetweenTokens(left, right)) { return false; } if (ALWAYS) { if (astUtils.isClosingParenToken(right)) { return false; } return !isOpenerException(right); } return isOpenerException(right); } /** * Determines if an closer paren should have a missing space after it * @param {Object} left The token before the paren * @param {Object} right The paren token * @returns {boolean} True if the paren should have a space */ function shouldCloserHaveSpace(left, right) { if (astUtils.isOpeningParenToken(left)) { return false; } if (sourceCode.isSpaceBetweenTokens(left, right)) { return false; } if (ALWAYS) { return !isCloserException(left); } return isCloserException(left); } /** * Determines if an opener paren should not have an existing space after it * @param {Object} left The paren token * @param {Object} right The token after it * @returns {boolean} True if the paren should reject the space */ function shouldOpenerRejectSpace(left, right) { if (right.type === "Line") { return false; } if (!astUtils.isTokenOnSameLine(left, right)) { return false; } if (!sourceCode.isSpaceBetweenTokens(left, right)) { return false; } if (ALWAYS) { return isOpenerException(right); } return !isOpenerException(right); } /** * Determines if an closer paren should not have an existing space after it * @param {Object} left The token before the paren * @param {Object} right The paren token * @returns {boolean} True if the paren should reject the space */ function shouldCloserRejectSpace(left, right) { if (astUtils.isOpeningParenToken(left)) { return false; } if (!astUtils.isTokenOnSameLine(left, right)) { return false; } if (!sourceCode.isSpaceBetweenTokens(left, right)) { return false; } if (ALWAYS) { return isCloserException(left); } return !isCloserException(left); } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function checkParenSpaces(node) { exceptions = getExceptions(); var tokens = sourceCode.tokensAndComments; tokens.forEach(function (token, i) { var prevToken = tokens[i - 1]; var nextToken = tokens[i + 1]; if (!astUtils.isOpeningParenToken(token) && !astUtils.isClosingParenToken(token)) { return; } if (token.value === "(" && shouldOpenerHaveSpace(token, nextToken)) { context.report({ node: node, loc: token.loc.start, message: MISSING_SPACE_MESSAGE, fix: function fix(fixer) { return fixer.insertTextAfter(token, " "); } }); } else if (token.value === "(" && shouldOpenerRejectSpace(token, nextToken)) { context.report({ node: node, loc: token.loc.start, message: REJECTED_SPACE_MESSAGE, fix: function fix(fixer) { return fixer.removeRange([token.range[1], nextToken.range[0]]); } }); } else if (token.value === ")" && shouldCloserHaveSpace(prevToken, token)) { // context.report(node, token.loc.start, MISSING_SPACE_MESSAGE); context.report({ node: node, loc: token.loc.start, message: MISSING_SPACE_MESSAGE, fix: function fix(fixer) { return fixer.insertTextBefore(token, " "); } }); } else if (token.value === ")" && shouldCloserRejectSpace(prevToken, token)) { context.report({ node: node, loc: token.loc.start, message: REJECTED_SPACE_MESSAGE, fix: function fix(fixer) { return fixer.removeRange([prevToken.range[1], token.range[0]]); } }); } }); } }; } }; },{"../util/ast-utils":405}],373:[function(require,module,exports){ /** * @fileoverview Require spaces around infix operators * @author Michael Ficarra */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require spacing around infix operators", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/space-infix-ops" }, fixable: "whitespace", schema: [{ type: "object", properties: { int32Hint: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var int32Hint = context.options[0] ? context.options[0].int32Hint === true : false; var sourceCode = context.getSourceCode(); /** * Returns the first token which violates the rule * @param {ASTNode} left - The left node of the main node * @param {ASTNode} right - The right node of the main node * @param {string} op - The operator of the main node * @returns {Object} The violator token or null * @private */ function getFirstNonSpacedToken(left, right, op) { var operator = sourceCode.getFirstTokenBetween(left, right, function (token) { return token.value === op; }); var prev = sourceCode.getTokenBefore(operator); var next = sourceCode.getTokenAfter(operator); if (!sourceCode.isSpaceBetweenTokens(prev, operator) || !sourceCode.isSpaceBetweenTokens(operator, next)) { return operator; } return null; } /** * Reports an AST node as a rule violation * @param {ASTNode} mainNode - The node to report * @param {Object} culpritToken - The token which has a problem * @returns {void} * @private */ function report(mainNode, culpritToken) { context.report({ node: mainNode, loc: culpritToken.loc.start, message: "Operator '{{operator}}' must be spaced.", data: { operator: culpritToken.value }, fix: function fix(fixer) { var previousToken = sourceCode.getTokenBefore(culpritToken); var afterToken = sourceCode.getTokenAfter(culpritToken); var fixString = ""; if (culpritToken.range[0] - previousToken.range[1] === 0) { fixString = " "; } fixString += culpritToken.value; if (afterToken.range[0] - culpritToken.range[1] === 0) { fixString += " "; } return fixer.replaceText(culpritToken, fixString); } }); } /** * Check if the node is binary then report * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkBinary(node) { var leftNode = node.left.typeAnnotation ? node.left.typeAnnotation : node.left; var rightNode = node.right; // search for = in AssignmentPattern nodes var operator = node.operator || "="; var nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, operator); if (nonSpacedNode) { if (!(int32Hint && sourceCode.getText(node).endsWith("|0"))) { report(node, nonSpacedNode); } } } /** * Check if the node is conditional * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkConditional(node) { var nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent, "?"); var nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate, ":"); if (nonSpacedConsequesntNode) { report(node, nonSpacedConsequesntNode); } else if (nonSpacedAlternateNode) { report(node, nonSpacedAlternateNode); } } /** * Check if the node is a variable * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkVar(node) { var leftNode = node.id.typeAnnotation ? node.id.typeAnnotation : node.id; var rightNode = node.init; if (rightNode) { var nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, "="); if (nonSpacedNode) { report(node, nonSpacedNode); } } } return { AssignmentExpression: checkBinary, AssignmentPattern: checkBinary, BinaryExpression: checkBinary, LogicalExpression: checkBinary, ConditionalExpression: checkConditional, VariableDeclarator: checkVar }; } }; },{}],374:[function(require,module,exports){ /** * @fileoverview This rule shoud require or disallow spaces before or after unary operations. * @author Marcin Kumorek */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce consistent spacing before or after unary operators", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/space-unary-ops" }, fixable: "whitespace", schema: [{ type: "object", properties: { words: { type: "boolean" }, nonwords: { type: "boolean" }, overrides: { type: "object", additionalProperties: { type: "boolean" } } }, additionalProperties: false }] }, create: function create(context) { var options = context.options && Array.isArray(context.options) && context.options[0] || { words: true, nonwords: false }; var sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Check if the node is the first "!" in a "!!" convert to Boolean expression * @param {ASTnode} node AST node * @returns {boolean} Whether or not the node is first "!" in "!!" */ function isFirstBangInBangBangExpression(node) { return node && node.type === "UnaryExpression" && node.argument.operator === "!" && node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!"; } /** * Checks if an override exists for a given operator. * @param {string} operator Operator * @returns {boolean} Whether or not an override has been provided for the operator */ function overrideExistsForOperator(operator) { return options.overrides && Object.prototype.hasOwnProperty.call(options.overrides, operator); } /** * Gets the value that the override was set to for this operator * @param {string} operator Operator * @returns {boolean} Whether or not an override enforces a space with this operator */ function overrideEnforcesSpaces(operator) { return options.overrides[operator]; } /** * Verify Unary Word Operator has spaces after the word operator * @param {ASTnode} node AST node * @param {Object} firstToken first token from the AST node * @param {Object} secondToken second token from the AST node * @param {string} word The word to be used for reporting * @returns {void} */ function verifyWordHasSpaces(node, firstToken, secondToken, word) { if (secondToken.range[0] === firstToken.range[1]) { context.report({ node: node, message: "Unary word operator '{{word}}' must be followed by whitespace.", data: { word: word }, fix: function fix(fixer) { return fixer.insertTextAfter(firstToken, " "); } }); } } /** * Verify Unary Word Operator doesn't have spaces after the word operator * @param {ASTnode} node AST node * @param {Object} firstToken first token from the AST node * @param {Object} secondToken second token from the AST node * @param {string} word The word to be used for reporting * @returns {void} */ function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) { if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) { if (secondToken.range[0] > firstToken.range[1]) { context.report({ node: node, message: "Unexpected space after unary word operator '{{word}}'.", data: { word: word }, fix: function fix(fixer) { return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); } }); } } } /** * Check Unary Word Operators for spaces after the word operator * @param {ASTnode} node AST node * @param {Object} firstToken first token from the AST node * @param {Object} secondToken second token from the AST node * @param {string} word The word to be used for reporting * @returns {void} */ function checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, word) { if (overrideExistsForOperator(word)) { if (overrideEnforcesSpaces(word)) { verifyWordHasSpaces(node, firstToken, secondToken, word); } else { verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); } } else if (options.words) { verifyWordHasSpaces(node, firstToken, secondToken, word); } else { verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); } } /** * Verifies YieldExpressions satisfy spacing requirements * @param {ASTnode} node AST node * @returns {void} */ function checkForSpacesAfterYield(node) { var tokens = sourceCode.getFirstTokens(node, 3), word = "yield"; if (!node.argument || node.delegate) { return; } checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], word); } /** * Verifies AwaitExpressions satisfy spacing requirements * @param {ASTNode} node AwaitExpression AST node * @returns {void} */ function checkForSpacesAfterAwait(node) { var tokens = sourceCode.getFirstTokens(node, 3); checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], "await"); } /** * Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator * @param {ASTnode} node AST node * @param {Object} firstToken First token in the expression * @param {Object} secondToken Second token in the expression * @returns {void} */ function verifyNonWordsHaveSpaces(node, firstToken, secondToken) { if (node.prefix) { if (isFirstBangInBangBangExpression(node)) { return; } if (firstToken.range[1] === secondToken.range[0]) { context.report({ node: node, message: "Unary operator '{{operator}}' must be followed by whitespace.", data: { operator: firstToken.value }, fix: function fix(fixer) { return fixer.insertTextAfter(firstToken, " "); } }); } } else { if (firstToken.range[1] === secondToken.range[0]) { context.report({ node: node, message: "Space is required before unary expressions '{{token}}'.", data: { token: secondToken.value }, fix: function fix(fixer) { return fixer.insertTextBefore(secondToken, " "); } }); } } } /** * Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator * @param {ASTnode} node AST node * @param {Object} firstToken First token in the expression * @param {Object} secondToken Second token in the expression * @returns {void} */ function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) { if (node.prefix) { if (secondToken.range[0] > firstToken.range[1]) { context.report({ node: node, message: "Unexpected space after unary operator '{{operator}}'.", data: { operator: firstToken.value }, fix: function fix(fixer) { if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) { return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); } return null; } }); } } else { if (secondToken.range[0] > firstToken.range[1]) { context.report({ node: node, message: "Unexpected space before unary operator '{{operator}}'.", data: { operator: secondToken.value }, fix: function fix(fixer) { return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); } }); } } } /** * Verifies UnaryExpression, UpdateExpression and NewExpression satisfy spacing requirements * @param {ASTnode} node AST node * @returns {void} */ function checkForSpaces(node) { var tokens = node.type === "UpdateExpression" && !node.prefix ? sourceCode.getLastTokens(node, 2) : sourceCode.getFirstTokens(node, 2); var firstToken = tokens[0]; var secondToken = tokens[1]; if ((node.type === "NewExpression" || node.prefix) && firstToken.type === "Keyword") { checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, firstToken.value); return; } var operator = node.prefix ? tokens[0].value : tokens[1].value; if (overrideExistsForOperator(operator)) { if (overrideEnforcesSpaces(operator)) { verifyNonWordsHaveSpaces(node, firstToken, secondToken); } else { verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); } } else if (options.nonwords) { verifyNonWordsHaveSpaces(node, firstToken, secondToken); } else { verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { UnaryExpression: checkForSpaces, UpdateExpression: checkForSpaces, NewExpression: checkForSpaces, YieldExpression: checkForSpacesAfterYield, AwaitExpression: checkForSpacesAfterAwait }; } }; },{"../util/ast-utils":405}],375:[function(require,module,exports){ /** * @fileoverview Source code for spaced-comments rule * @author Gyandeep Singh */ "use strict"; var lodash = require("lodash"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Escapes the control characters of a given string. * @param {string} s - A string to escape. * @returns {string} An escaped string. */ function escape(s) { return "(?:" + lodash.escapeRegExp(s) + ")"; } /** * Escapes the control characters of a given string. * And adds a repeat flag. * @param {string} s - A string to escape. * @returns {string} An escaped string. */ function escapeAndRepeat(s) { return escape(s) + "+"; } /** * Parses `markers` option. * If markers don't include `"*"`, this adds `"*"` to allow JSDoc comments. * @param {string[]} [markers] - A marker list. * @returns {string[]} A marker list. */ function parseMarkersOption(markers) { // `*` is a marker for JSDoc comments. if (markers.indexOf("*") === -1) { return markers.concat("*"); } return markers; } /** * Creates string pattern for exceptions. * Generated pattern: * * 1. A space or an exception pattern sequence. * * @param {string[]} exceptions - An exception pattern list. * @returns {string} A regular expression string for exceptions. */ function createExceptionsPattern(exceptions) { var pattern = ""; /* * A space or an exception pattern sequence. * [] ==> "\s" * ["-"] ==> "(?:\s|\-+$)" * ["-", "="] ==> "(?:\s|(?:\-+|=+)$)" * ["-", "=", "--=="] ==> "(?:\s|(?:\-+|=+|(?:\-\-==)+)$)" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5Cs%7C(%3F%3A%5C-%2B%7C%3D%2B%7C(%3F%3A%5C-%5C-%3D%3D)%2B)%24) */ if (exceptions.length === 0) { // a space. pattern += "\\s"; } else { // a space or... pattern += "(?:\\s|"; if (exceptions.length === 1) { // a sequence of the exception pattern. pattern += escapeAndRepeat(exceptions[0]); } else { // a sequence of one of the exception patterns. pattern += "(?:"; pattern += exceptions.map(escapeAndRepeat).join("|"); pattern += ")"; } pattern += "(?:$|[" + Array.from(astUtils.LINEBREAKS).join("") + "]))"; } return pattern; } /** * Creates RegExp object for `always` mode. * Generated pattern for beginning of comment: * * 1. First, a marker or nothing. * 2. Next, a space or an exception pattern sequence. * * @param {string[]} markers - A marker list. * @param {string[]} exceptions - An exception pattern list. * @returns {RegExp} A RegExp object for the beginning of a comment in `always` mode. */ function createAlwaysStylePattern(markers, exceptions) { var pattern = "^"; /* * A marker or nothing. * ["*"] ==> "\*?" * ["*", "!"] ==> "(?:\*|!)?" * ["*", "/", "!<"] ==> "(?:\*|\/|(?:!<))?" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5C*%7C%5C%2F%7C(%3F%3A!%3C))%3F */ if (markers.length === 1) { // the marker. pattern += escape(markers[0]); } else { // one of markers. pattern += "(?:"; pattern += markers.map(escape).join("|"); pattern += ")"; } pattern += "?"; // or nothing. pattern += createExceptionsPattern(exceptions); return new RegExp(pattern); } /** * Creates RegExp object for `never` mode. * Generated pattern for beginning of comment: * * 1. First, a marker or nothing (captured). * 2. Next, a space or a tab. * * @param {string[]} markers - A marker list. * @returns {RegExp} A RegExp object for `never` mode. */ function createNeverStylePattern(markers) { var pattern = "^(" + markers.map(escape).join("|") + ")?[ \t]+"; return new RegExp(pattern); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce consistent spacing after the `//` or `/*` in a comment", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/spaced-comment" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }, { type: "object", properties: { exceptions: { type: "array", items: { type: "string" } }, markers: { type: "array", items: { type: "string" } }, line: { type: "object", properties: { exceptions: { type: "array", items: { type: "string" } }, markers: { type: "array", items: { type: "string" } } }, additionalProperties: false }, block: { type: "object", properties: { exceptions: { type: "array", items: { type: "string" } }, markers: { type: "array", items: { type: "string" } }, balanced: { type: "boolean" } }, additionalProperties: false } }, additionalProperties: false }] }, create: function create(context) { var sourceCode = context.getSourceCode(); // Unless the first option is never, require a space var requireSpace = context.options[0] !== "never"; /* * Parse the second options. * If markers don't include `"*"`, it's added automatically for JSDoc * comments. */ var config = context.options[1] || {}; var balanced = config.block && config.block.balanced; var styleRules = ["block", "line"].reduce(function (rule, type) { var markers = parseMarkersOption(config[type] && config[type].markers || config.markers || []); var exceptions = config[type] && config[type].exceptions || config.exceptions || []; var endNeverPattern = "[ \t]+$"; // Create RegExp object for valid patterns. rule[type] = { beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers), endRegex: balanced && requireSpace ? new RegExp(createExceptionsPattern(exceptions) + "$") : new RegExp(endNeverPattern), hasExceptions: exceptions.length > 0, markers: new RegExp("^(" + markers.map(escape).join("|") + ")") }; return rule; }, {}); /** * Reports a beginning spacing error with an appropriate message. * @param {ASTNode} node - A comment node to check. * @param {string} message - An error message to report. * @param {Array} match - An array of match results for markers. * @param {string} refChar - Character used for reference in the error message. * @returns {void} */ function reportBegin(node, message, match, refChar) { var type = node.type.toLowerCase(), commentIdentifier = type === "block" ? "/*" : "//"; context.report({ node: node, fix: function fix(fixer) { var start = node.range[0]; var end = start + 2; if (requireSpace) { if (match) { end += match[0].length; } return fixer.insertTextAfterRange([start, end], " "); } end += match[0].length; return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : "")); }, message: message, data: { refChar: refChar } }); } /** * Reports an ending spacing error with an appropriate message. * @param {ASTNode} node - A comment node to check. * @param {string} message - An error message to report. * @param {string} match - An array of the matched whitespace characters. * @returns {void} */ function reportEnd(node, message, match) { context.report({ node: node, fix: function fix(fixer) { if (requireSpace) { return fixer.insertTextAfterRange([node.range[0], node.range[1] - 2], " "); } var end = node.range[1] - 2, start = end - match[0].length; return fixer.replaceTextRange([start, end], ""); }, message: message }); } /** * Reports a given comment if it's invalid. * @param {ASTNode} node - a comment node to check. * @returns {void} */ function checkCommentForSpace(node) { var type = node.type.toLowerCase(), rule = styleRules[type], commentIdentifier = type === "block" ? "/*" : "//"; // Ignores empty comments. if (node.value.length === 0) { return; } var beginMatch = rule.beginRegex.exec(node.value); var endMatch = rule.endRegex.exec(node.value); // Checks. if (requireSpace) { if (!beginMatch) { var hasMarker = rule.markers.exec(node.value); var marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier; if (rule.hasExceptions) { reportBegin(node, "Expected exception block, space or tab after '{{refChar}}' in comment.", hasMarker, marker); } else { reportBegin(node, "Expected space or tab after '{{refChar}}' in comment.", hasMarker, marker); } } if (balanced && type === "block" && !endMatch) { reportEnd(node, "Expected space or tab before '*/' in comment."); } } else { if (beginMatch) { if (!beginMatch[1]) { reportBegin(node, "Unexpected space or tab after '{{refChar}}' in comment.", beginMatch, commentIdentifier); } else { reportBegin(node, "Unexpected space or tab after marker ({{refChar}}) in comment.", beginMatch, beginMatch[1]); } } if (balanced && type === "block" && endMatch) { reportEnd(node, "Unexpected space or tab before '*/' in comment.", endMatch); } } } return { Program: function Program() { var comments = sourceCode.getAllComments(); comments.filter(function (token) { return token.type !== "Shebang"; }).forEach(checkCommentForSpace); } }; } }; },{"../util/ast-utils":405,"lodash":92}],376:[function(require,module,exports){ /** * @fileoverview Rule to control usage of strict mode directives. * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var messages = { function: "Use the function form of 'use strict'.", global: "Use the global form of 'use strict'.", multiple: "Multiple 'use strict' directives.", never: "Strict mode is not permitted.", unnecessary: "Unnecessary 'use strict' directive.", module: "'use strict' is unnecessary inside of modules.", implied: "'use strict' is unnecessary when implied strict mode is enabled.", unnecessaryInClasses: "'use strict' is unnecessary inside of classes.", nonSimpleParameterList: "'use strict' directive inside a function with non-simple parameter list throws a syntax error since ES2016.", wrap: "Wrap {{name}} in a function with 'use strict' directive." }; /** * Gets all of the Use Strict Directives in the Directive Prologue of a group of * statements. * @param {ASTNode[]} statements Statements in the program or function body. * @returns {ASTNode[]} All of the Use Strict Directives. */ function getUseStrictDirectives(statements) { var directives = []; for (var i = 0; i < statements.length; i++) { var statement = statements[i]; if (statement.type === "ExpressionStatement" && statement.expression.type === "Literal" && statement.expression.value === "use strict") { directives[i] = statement; } else { break; } } return directives; } /** * Checks whether a given parameter is a simple parameter. * * @param {ASTNode} node - A pattern node to check. * @returns {boolean} `true` if the node is an Identifier node. */ function isSimpleParameter(node) { return node.type === "Identifier"; } /** * Checks whether a given parameter list is a simple parameter list. * * @param {ASTNode[]} params - A parameter list to check. * @returns {boolean} `true` if the every parameter is an Identifier node. */ function isSimpleParameterList(params) { return params.every(isSimpleParameter); } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow strict mode directives", category: "Strict Mode", recommended: false, url: "https://eslint.org/docs/rules/strict" }, schema: [{ enum: ["never", "global", "function", "safe"] }], fixable: "code" }, create: function create(context) { var ecmaFeatures = context.parserOptions.ecmaFeatures || {}, scopes = [], classScopes = []; var mode = context.options[0] || "safe"; if (ecmaFeatures.impliedStrict) { mode = "implied"; } else if (mode === "safe") { mode = ecmaFeatures.globalReturn ? "global" : "function"; } /** * Determines whether a reported error should be fixed, depending on the error type. * @param {string} errorType The type of error * @returns {boolean} `true` if the reported error should be fixed */ function shouldFix(errorType) { return errorType === "multiple" || errorType === "unnecessary" || errorType === "module" || errorType === "implied" || errorType === "unnecessaryInClasses"; } /** * Gets a fixer function to remove a given 'use strict' directive. * @param {ASTNode} node The directive that should be removed * @returns {Function} A fixer function */ function getFixFunction(node) { return function (fixer) { return fixer.remove(node); }; } /** * Report a slice of an array of nodes with a given message. * @param {ASTNode[]} nodes Nodes. * @param {string} start Index to start from. * @param {string} end Index to end before. * @param {string} message Message to display. * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) * @returns {void} */ function reportSlice(nodes, start, end, message, fix) { nodes.slice(start, end).forEach(function (node) { context.report({ node: node, message: message, fix: fix ? getFixFunction(node) : null }); }); } /** * Report all nodes in an array with a given message. * @param {ASTNode[]} nodes Nodes. * @param {string} message Message to display. * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) * @returns {void} */ function reportAll(nodes, message, fix) { reportSlice(nodes, 0, nodes.length, message, fix); } /** * Report all nodes in an array, except the first, with a given message. * @param {ASTNode[]} nodes Nodes. * @param {string} message Message to display. * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) * @returns {void} */ function reportAllExceptFirst(nodes, message, fix) { reportSlice(nodes, 1, nodes.length, message, fix); } /** * Entering a function in 'function' mode pushes a new nested scope onto the * stack. The new scope is true if the nested function is strict mode code. * @param {ASTNode} node The function declaration or expression. * @param {ASTNode[]} useStrictDirectives The Use Strict Directives of the node. * @returns {void} */ function enterFunctionInFunctionMode(node, useStrictDirectives) { var isInClass = classScopes.length > 0, isParentGlobal = scopes.length === 0 && classScopes.length === 0, isParentStrict = scopes.length > 0 && scopes[scopes.length - 1], isStrict = useStrictDirectives.length > 0; if (isStrict) { if (!isSimpleParameterList(node.params)) { context.report({ node: useStrictDirectives[0], message: messages.nonSimpleParameterList }); } else if (isParentStrict) { context.report({ node: useStrictDirectives[0], message: messages.unnecessary, fix: getFixFunction(useStrictDirectives[0]) }); } else if (isInClass) { context.report({ node: useStrictDirectives[0], message: messages.unnecessaryInClasses, fix: getFixFunction(useStrictDirectives[0]) }); } reportAllExceptFirst(useStrictDirectives, messages.multiple, true); } else if (isParentGlobal) { if (isSimpleParameterList(node.params)) { context.report({ node: node, message: messages.function }); } else { context.report({ node: node, message: messages.wrap, data: { name: astUtils.getFunctionNameWithKind(node) } }); } } scopes.push(isParentStrict || isStrict); } /** * Exiting a function in 'function' mode pops its scope off the stack. * @returns {void} */ function exitFunctionInFunctionMode() { scopes.pop(); } /** * Enter a function and either: * - Push a new nested scope onto the stack (in 'function' mode). * - Report all the Use Strict Directives (in the other modes). * @param {ASTNode} node The function declaration or expression. * @returns {void} */ function enterFunction(node) { var isBlock = node.body.type === "BlockStatement", useStrictDirectives = isBlock ? getUseStrictDirectives(node.body.body) : []; if (mode === "function") { enterFunctionInFunctionMode(node, useStrictDirectives); } else if (useStrictDirectives.length > 0) { if (isSimpleParameterList(node.params)) { reportAll(useStrictDirectives, messages[mode], shouldFix(mode)); } else { context.report({ node: useStrictDirectives[0], message: messages.nonSimpleParameterList }); reportAllExceptFirst(useStrictDirectives, messages.multiple, true); } } } var rule = { Program: function Program(node) { var useStrictDirectives = getUseStrictDirectives(node.body); if (node.sourceType === "module") { mode = "module"; } if (mode === "global") { if (node.body.length > 0 && useStrictDirectives.length === 0) { context.report({ node: node, message: messages.global }); } reportAllExceptFirst(useStrictDirectives, messages.multiple, true); } else { reportAll(useStrictDirectives, messages[mode], shouldFix(mode)); } }, FunctionDeclaration: enterFunction, FunctionExpression: enterFunction, ArrowFunctionExpression: enterFunction }; if (mode === "function") { Object.assign(rule, { // Inside of class bodies are always strict mode. ClassBody: function ClassBody() { classScopes.push(true); }, "ClassBody:exit": function ClassBodyExit() { classScopes.pop(); }, "FunctionDeclaration:exit": exitFunctionInFunctionMode, "FunctionExpression:exit": exitFunctionInFunctionMode, "ArrowFunctionExpression:exit": exitFunctionInFunctionMode }); } return rule; } }; },{"../util/ast-utils":405}],377:[function(require,module,exports){ /** * @fileoverview Rule to enforce spacing around colons of switch statements. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "enforce spacing around colons of switch statements", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/switch-colon-spacing" }, schema: [{ type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }], fixable: "whitespace" }, create: function create(context) { var sourceCode = context.getSourceCode(); var options = context.options[0] || {}; var beforeSpacing = options.before === true; // false by default var afterSpacing = options.after !== false; // true by default /** * Get the colon token of the given SwitchCase node. * @param {ASTNode} node The SwitchCase node to get. * @returns {Token} The colon token of the node. */ function getColonToken(node) { if (node.test) { return sourceCode.getTokenAfter(node.test, astUtils.isColonToken); } return sourceCode.getFirstToken(node, 1); } /** * Check whether the spacing between the given 2 tokens is valid or not. * @param {Token} left The left token to check. * @param {Token} right The right token to check. * @param {boolean} expected The expected spacing to check. `true` if there should be a space. * @returns {boolean} `true` if the spacing between the tokens is valid. */ function isValidSpacing(left, right, expected) { return astUtils.isClosingBraceToken(right) || !astUtils.isTokenOnSameLine(left, right) || sourceCode.isSpaceBetweenTokens(left, right) === expected; } /** * Check whether comments exist between the given 2 tokens. * @param {Token} left The left token to check. * @param {Token} right The right token to check. * @returns {boolean} `true` if comments exist between the given 2 tokens. */ function commentsExistBetween(left, right) { return sourceCode.getFirstTokenBetween(left, right, { includeComments: true, filter: astUtils.isCommentToken }) !== null; } /** * Fix the spacing between the given 2 tokens. * @param {RuleFixer} fixer The fixer to fix. * @param {Token} left The left token of fix range. * @param {Token} right The right token of fix range. * @param {boolean} spacing The spacing style. `true` if there should be a space. * @returns {Fix|null} The fix object. */ function _fix(fixer, left, right, spacing) { if (commentsExistBetween(left, right)) { return null; } if (spacing) { return fixer.insertTextAfter(left, " "); } return fixer.removeRange([left.range[1], right.range[0]]); } return { SwitchCase: function SwitchCase(node) { var colonToken = getColonToken(node); var beforeToken = sourceCode.getTokenBefore(colonToken); var afterToken = sourceCode.getTokenAfter(colonToken); if (!isValidSpacing(beforeToken, colonToken, beforeSpacing)) { context.report({ node: node, loc: colonToken.loc, message: "{{verb}} space(s) before this colon.", data: { verb: beforeSpacing ? "Expected" : "Unexpected" }, fix: function fix(fixer) { return _fix(fixer, beforeToken, colonToken, beforeSpacing); } }); } if (!isValidSpacing(colonToken, afterToken, afterSpacing)) { context.report({ node: node, loc: colonToken.loc, message: "{{verb}} space(s) after this colon.", data: { verb: afterSpacing ? "Expected" : "Unexpected" }, fix: function fix(fixer) { return _fix(fixer, colonToken, afterToken, afterSpacing); } }); } } }; } }; },{"../util/ast-utils":405}],378:[function(require,module,exports){ /** * @fileoverview Rule to enforce description with the `Symbol` object * @author Jarek Rencz */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require symbol descriptions", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/symbol-description" }, schema: [] }, create: function create(context) { /** * Reports if node does not conform the rule in case rule is set to * report missing description * * @param {ASTNode} node - A CallExpression node to check. * @returns {void} */ function checkArgument(node) { if (node.arguments.length === 0) { context.report({ node: node, message: "Expected Symbol to have a description." }); } } return { "Program:exit": function ProgramExit() { var scope = context.getScope(); var variable = astUtils.getVariableByName(scope, "Symbol"); if (variable && variable.defs.length === 0) { variable.references.forEach(function (reference) { var node = reference.identifier; if (astUtils.isCallee(node)) { checkArgument(node.parent); } }); } } }; } }; },{"../util/ast-utils":405}],379:[function(require,module,exports){ /** * @fileoverview Rule to enforce spacing around embedded expressions of template strings * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var OPEN_PAREN = /\$\{$/; var CLOSE_PAREN = /^\}/; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow spacing around embedded expressions of template strings", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/template-curly-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var always = context.options[0] === "always"; var prefix = always ? "Expected" : "Unexpected"; /** * Checks spacing before `}` of a given token. * @param {Token} token - A token to check. This is a Template token. * @returns {void} */ function checkSpacingBefore(token) { var prevToken = sourceCode.getTokenBefore(token); if (prevToken && CLOSE_PAREN.test(token.value) && astUtils.isTokenOnSameLine(prevToken, token) && sourceCode.isSpaceBetweenTokens(prevToken, token) !== always) { context.report({ loc: token.loc.start, message: "{{prefix}} space(s) before '}'.", data: { prefix: prefix }, fix: function fix(fixer) { if (always) { return fixer.insertTextBefore(token, " "); } return fixer.removeRange([prevToken.range[1], token.range[0]]); } }); } } /** * Checks spacing after `${` of a given token. * @param {Token} token - A token to check. This is a Template token. * @returns {void} */ function checkSpacingAfter(token) { var nextToken = sourceCode.getTokenAfter(token); if (nextToken && OPEN_PAREN.test(token.value) && astUtils.isTokenOnSameLine(token, nextToken) && sourceCode.isSpaceBetweenTokens(token, nextToken) !== always) { context.report({ loc: { line: token.loc.end.line, column: token.loc.end.column - 2 }, message: "{{prefix}} space(s) after '${'.", data: { prefix: prefix }, fix: function fix(fixer) { if (always) { return fixer.insertTextAfter(token, " "); } return fixer.removeRange([token.range[1], nextToken.range[0]]); } }); } } return { TemplateElement: function TemplateElement(node) { var token = sourceCode.getFirstToken(node); checkSpacingBefore(token); checkSpacingAfter(token); } }; } }; },{"../util/ast-utils":405}],380:[function(require,module,exports){ /** * @fileoverview Rule to check spacing between template tags and their literals * @author Jonathan Wilsson */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow spacing between template tags and their literals", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/template-tag-spacing" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }] }, create: function create(context) { var never = context.options[0] !== "always"; var sourceCode = context.getSourceCode(); /** * Check if a space is present between a template tag and its literal * @param {ASTNode} node node to evaluate * @returns {void} * @private */ function checkSpacing(node) { var tagToken = sourceCode.getTokenBefore(node.quasi); var literalToken = sourceCode.getFirstToken(node.quasi); var hasWhitespace = sourceCode.isSpaceBetweenTokens(tagToken, literalToken); if (never && hasWhitespace) { context.report({ node: node, loc: tagToken.loc.start, message: "Unexpected space between template tag and template literal.", fix: function fix(fixer) { var comments = sourceCode.getCommentsBefore(node.quasi); // Don't fix anything if there's a single line comment after the template tag if (comments.some(function (comment) { return comment.type === "Line"; })) { return null; } return fixer.replaceTextRange([tagToken.range[1], literalToken.range[0]], comments.reduce(function (text, comment) { return text + sourceCode.getText(comment); }, "")); } }); } else if (!never && !hasWhitespace) { context.report({ node: node, loc: tagToken.loc.start, message: "Missing space between template tag and template literal.", fix: function fix(fixer) { return fixer.insertTextAfter(tagToken, " "); } }); } } return { TaggedTemplateExpression: checkSpacing }; } }; },{}],381:[function(require,module,exports){ /** * @fileoverview Require or disallow Unicode BOM * @author Andrew Johnston */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow Unicode byte order mark (BOM)", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/unicode-bom" }, fixable: "whitespace", schema: [{ enum: ["always", "never"] }] }, create: function create(context) { //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { Program: function checkUnicodeBOM(node) { var sourceCode = context.getSourceCode(), location = { column: 0, line: 1 }, requireBOM = context.options[0] || "never"; if (!sourceCode.hasBOM && requireBOM === "always") { context.report({ node: node, loc: location, message: "Expected Unicode BOM (Byte Order Mark).", fix: function fix(fixer) { return fixer.insertTextBeforeRange([0, 1], "\uFEFF"); } }); } else if (sourceCode.hasBOM && requireBOM === "never") { context.report({ node: node, loc: location, message: "Unexpected Unicode BOM (Byte Order Mark).", fix: function fix(fixer) { return fixer.removeRange([-1, 0]); } }); } } }; } }; },{}],382:[function(require,module,exports){ /** * @fileoverview Rule to flag comparisons to the value NaN * @author James Allardice */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "require calls to `isNaN()` when checking for `NaN`", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/use-isnan" }, schema: [] }, create: function create(context) { return { BinaryExpression: function BinaryExpression(node) { if (/^(?:[<>]|[!=]=)=?$/.test(node.operator) && (node.left.name === "NaN" || node.right.name === "NaN")) { context.report({ node: node, message: "Use the isNaN function to compare with NaN." }); } } }; } }; },{}],383:[function(require,module,exports){ /** * @fileoverview Validates JSDoc comments are syntactically correct * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var doctrine = require("doctrine"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "enforce valid JSDoc comments", category: "Possible Errors", recommended: false, url: "https://eslint.org/docs/rules/valid-jsdoc" }, schema: [{ type: "object", properties: { prefer: { type: "object", additionalProperties: { type: "string" } }, preferType: { type: "object", additionalProperties: { type: "string" } }, requireReturn: { type: "boolean" }, requireParamDescription: { type: "boolean" }, requireReturnDescription: { type: "boolean" }, matchDescription: { type: "string" }, requireReturnType: { type: "boolean" }, requireParamType: { type: "boolean" } }, additionalProperties: false }], fixable: "code", deprecated: true, replacedBy: [] }, create: function create(context) { var options = context.options[0] || {}, prefer = options.prefer || {}, sourceCode = context.getSourceCode(), // these both default to true, so you have to explicitly make them false requireReturn = options.requireReturn !== false, requireParamDescription = options.requireParamDescription !== false, requireReturnDescription = options.requireReturnDescription !== false, requireReturnType = options.requireReturnType !== false, requireParamType = options.requireParamType !== false, preferType = options.preferType || {}, checkPreferType = Object.keys(preferType).length !== 0; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- // Using a stack to store if a function returns or not (handling nested functions) var fns = []; /** * Check if node type is a Class * @param {ASTNode} node node to check. * @returns {boolean} True is its a class * @private */ function isTypeClass(node) { return node.type === "ClassExpression" || node.type === "ClassDeclaration"; } /** * When parsing a new function, store it in our function stack. * @param {ASTNode} node A function node to check. * @returns {void} * @private */ function startFunction(node) { fns.push({ returnPresent: node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement" || isTypeClass(node) || node.async }); } /** * Indicate that return has been found in the current function. * @param {ASTNode} node The return node. * @returns {void} * @private */ function addReturn(node) { var functionState = fns[fns.length - 1]; if (functionState && node.argument !== null) { functionState.returnPresent = true; } } /** * Check if return tag type is void or undefined * @param {Object} tag JSDoc tag * @returns {boolean} True if its of type void or undefined * @private */ function isValidReturnType(tag) { return tag.type === null || tag.type.name === "void" || tag.type.type === "UndefinedLiteral"; } /** * Check if type should be validated based on some exceptions * @param {Object} type JSDoc tag * @returns {boolean} True if it can be validated * @private */ function canTypeBeValidated(type) { return type !== "UndefinedLiteral" && // {undefined} as there is no name property available. type !== "NullLiteral" && // {null} type !== "NullableLiteral" && // {?} type !== "FunctionType" && // {function(a)} type !== "AllLiteral"; // {*} } /** * Extract the current and expected type based on the input type object * @param {Object} type JSDoc tag * @returns {{currentType: Doctrine.Type, expectedTypeName: string}} The current type annotation and * the expected name of the annotation * @private */ function getCurrentExpectedTypes(type) { var currentType = void 0; if (type.name) { currentType = type; } else if (type.expression) { currentType = type.expression; } return { currentType: currentType, expectedTypeName: currentType && preferType[currentType.name] }; } /** * Gets the location of a JSDoc node in a file * @param {Token} jsdocComment The comment that this node is parsed from * @param {{range: number[]}} parsedJsdocNode A tag or other node which was parsed from this comment * @returns {{start: SourceLocation, end: SourceLocation}} The 0-based source location for the tag */ function getAbsoluteRange(jsdocComment, parsedJsdocNode) { return { start: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[0]), end: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[1]) }; } /** * Validate type for a given JSDoc node * @param {Object} jsdocNode JSDoc node * @param {Object} type JSDoc tag * @returns {void} * @private */ function validateType(jsdocNode, type) { if (!type || !canTypeBeValidated(type.type)) { return; } var typesToCheck = []; var elements = []; switch (type.type) { case "TypeApplication": // {Array.} elements = type.applications[0].type === "UnionType" ? type.applications[0].elements : type.applications; typesToCheck.push(getCurrentExpectedTypes(type)); break; case "RecordType": // {{20:String}} elements = type.fields; break; case "UnionType": // {String|number|Test} case "ArrayType": // {[String, number, Test]} elements = type.elements; break; case "FieldType": // Array.<{count: number, votes: number}> if (type.value) { typesToCheck.push(getCurrentExpectedTypes(type.value)); } break; default: typesToCheck.push(getCurrentExpectedTypes(type)); } elements.forEach(validateType.bind(null, jsdocNode)); typesToCheck.forEach(function (typeToCheck) { if (typeToCheck.expectedTypeName && typeToCheck.expectedTypeName !== typeToCheck.currentType.name) { context.report({ node: jsdocNode, message: "Use '{{expectedTypeName}}' instead of '{{currentTypeName}}'.", loc: getAbsoluteRange(jsdocNode, typeToCheck.currentType), data: { currentTypeName: typeToCheck.currentType.name, expectedTypeName: typeToCheck.expectedTypeName }, fix: function fix(fixer) { return fixer.replaceTextRange(typeToCheck.currentType.range.map(function (indexInComment) { return jsdocNode.range[0] + 2 + indexInComment; }), typeToCheck.expectedTypeName); } }); } }); } /** * Validate the JSDoc node and output warnings if anything is wrong. * @param {ASTNode} node The AST node to check. * @returns {void} * @private */ function checkJSDoc(node) { var jsdocNode = sourceCode.getJSDocComment(node), functionData = fns.pop(), paramTagsByName = Object.create(null), paramTags = []; var hasReturns = false, returnsTag = void 0, hasConstructor = false, isInterface = false, isOverride = false, isAbstract = false; // make sure only to validate JSDoc comments if (jsdocNode) { var jsdoc = void 0; try { jsdoc = doctrine.parse(jsdocNode.value, { strict: true, unwrap: true, sloppy: true, range: true }); } catch (ex) { if (/braces/i.test(ex.message)) { context.report({ node: jsdocNode, message: "JSDoc type missing brace." }); } else { context.report({ node: jsdocNode, message: "JSDoc syntax error." }); } return; } jsdoc.tags.forEach(function (tag) { switch (tag.title.toLowerCase()) { case "param": case "arg": case "argument": paramTags.push(tag); break; case "return": case "returns": hasReturns = true; returnsTag = tag; break; case "constructor": case "class": hasConstructor = true; break; case "override": case "inheritdoc": isOverride = true; break; case "abstract": case "virtual": isAbstract = true; break; case "interface": isInterface = true; break; // no default } // check tag preferences if (Object.prototype.hasOwnProperty.call(prefer, tag.title) && tag.title !== prefer[tag.title]) { var entireTagRange = getAbsoluteRange(jsdocNode, tag); context.report({ node: jsdocNode, message: "Use @{{name}} instead.", loc: { start: entireTagRange.start, end: { line: entireTagRange.start.line, column: entireTagRange.start.column + ("@" + tag.title).length } }, data: { name: prefer[tag.title] }, fix: function fix(fixer) { return fixer.replaceTextRange([jsdocNode.range[0] + tag.range[0] + 3, jsdocNode.range[0] + tag.range[0] + tag.title.length + 3], prefer[tag.title]); } }); } // validate the types if (checkPreferType && tag.type) { validateType(jsdocNode, tag.type); } }); paramTags.forEach(function (param) { if (requireParamType && !param.type) { context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", loc: getAbsoluteRange(jsdocNode, param), data: { name: param.name } }); } if (!param.description && requireParamDescription) { context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", loc: getAbsoluteRange(jsdocNode, param), data: { name: param.name } }); } if (paramTagsByName[param.name]) { context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", loc: getAbsoluteRange(jsdocNode, param), data: { name: param.name } }); } else if (param.name.indexOf(".") === -1) { paramTagsByName[param.name] = param; } }); if (hasReturns) { if (!requireReturn && !functionData.returnPresent && (returnsTag.type === null || !isValidReturnType(returnsTag)) && !isAbstract) { context.report({ node: jsdocNode, message: "Unexpected @{{title}} tag; function has no return statement.", loc: getAbsoluteRange(jsdocNode, returnsTag), data: { title: returnsTag.title } }); } else { if (requireReturnType && !returnsTag.type) { context.report({ node: jsdocNode, message: "Missing JSDoc return type." }); } if (!isValidReturnType(returnsTag) && !returnsTag.description && requireReturnDescription) { context.report({ node: jsdocNode, message: "Missing JSDoc return description." }); } } } // check for functions missing @returns if (!isOverride && !hasReturns && !hasConstructor && !isInterface && node.parent.kind !== "get" && node.parent.kind !== "constructor" && node.parent.kind !== "set" && !isTypeClass(node)) { if (requireReturn || functionData.returnPresent && !node.async) { context.report({ node: jsdocNode, message: "Missing JSDoc @{{returns}} for function.", data: { returns: prefer.returns || "returns" } }); } } // check the parameters var jsdocParamNames = Object.keys(paramTagsByName); if (node.params) { node.params.forEach(function (param, paramsIndex) { var bindingParam = param.type === "AssignmentPattern" ? param.left : param; // TODO(nzakas): Figure out logical things to do with destructured, default, rest params if (bindingParam.type === "Identifier") { var name = bindingParam.name; if (jsdocParamNames[paramsIndex] && name !== jsdocParamNames[paramsIndex]) { context.report({ node: jsdocNode, message: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", loc: getAbsoluteRange(jsdocNode, paramTagsByName[jsdocParamNames[paramsIndex]]), data: { name: name, jsdocName: jsdocParamNames[paramsIndex] } }); } else if (!paramTagsByName[name] && !isOverride) { context.report({ node: jsdocNode, message: "Missing JSDoc for parameter '{{name}}'.", data: { name: name } }); } } }); } if (options.matchDescription) { var regex = new RegExp(options.matchDescription); if (!regex.test(jsdoc.description)) { context.report({ node: jsdocNode, message: "JSDoc description does not satisfy the regex pattern." }); } } } } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { ArrowFunctionExpression: startFunction, FunctionExpression: startFunction, FunctionDeclaration: startFunction, ClassExpression: startFunction, ClassDeclaration: startFunction, "ArrowFunctionExpression:exit": checkJSDoc, "FunctionExpression:exit": checkJSDoc, "FunctionDeclaration:exit": checkJSDoc, "ClassExpression:exit": checkJSDoc, "ClassDeclaration:exit": checkJSDoc, ReturnStatement: addReturn }; } }; },{"doctrine":55}],384:[function(require,module,exports){ /** * @fileoverview Ensures that the results of typeof are compared against a valid string * @author Ian Christian Myers */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "problem", docs: { description: "enforce comparing `typeof` expressions against valid strings", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/valid-typeof" }, schema: [{ type: "object", properties: { requireStringLiterals: { type: "boolean" } }, additionalProperties: false }] }, create: function create(context) { var VALID_TYPES = ["symbol", "undefined", "object", "boolean", "number", "string", "function"], OPERATORS = ["==", "===", "!=", "!=="]; var requireStringLiterals = context.options[0] && context.options[0].requireStringLiterals; /** * Determines whether a node is a typeof expression. * @param {ASTNode} node The node * @returns {boolean} `true` if the node is a typeof expression */ function isTypeofExpression(node) { return node.type === "UnaryExpression" && node.operator === "typeof"; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { UnaryExpression: function UnaryExpression(node) { if (isTypeofExpression(node)) { var parent = context.getAncestors().pop(); if (parent.type === "BinaryExpression" && OPERATORS.indexOf(parent.operator) !== -1) { var sibling = parent.left === node ? parent.right : parent.left; if (sibling.type === "Literal" || sibling.type === "TemplateLiteral" && !sibling.expressions.length) { var value = sibling.type === "Literal" ? sibling.value : sibling.quasis[0].value.cooked; if (VALID_TYPES.indexOf(value) === -1) { context.report({ node: sibling, message: "Invalid typeof comparison value." }); } } else if (requireStringLiterals && !isTypeofExpression(sibling)) { context.report({ node: sibling, message: "Typeof comparisons should be to string literals." }); } } } } }; } }; },{}],385:[function(require,module,exports){ /** * @fileoverview Rule to enforce var declarations are only at the top of a function. * @author Danny Fritz * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require `var` declarations be placed at the top of their containing scope", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/vars-on-top" }, schema: [] }, create: function create(context) { var errorMessage = "All 'var' declarations must be at the top of the function scope."; //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * @param {ASTNode} node - any node * @returns {boolean} whether the given node structurally represents a directive */ function looksLikeDirective(node) { return node.type === "ExpressionStatement" && node.expression.type === "Literal" && typeof node.expression.value === "string"; } /** * Check to see if its a ES6 import declaration * @param {ASTNode} node - any node * @returns {boolean} whether the given node represents a import declaration */ function looksLikeImport(node) { return node.type === "ImportDeclaration" || node.type === "ImportSpecifier" || node.type === "ImportDefaultSpecifier" || node.type === "ImportNamespaceSpecifier"; } /** * Checks whether a given node is a variable declaration or not. * * @param {ASTNode} node - any node * @returns {boolean} `true` if the node is a variable declaration. */ function isVariableDeclaration(node) { return node.type === "VariableDeclaration" || node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration"; } /** * Checks whether this variable is on top of the block body * @param {ASTNode} node - The node to check * @param {ASTNode[]} statements - collection of ASTNodes for the parent node block * @returns {boolean} True if var is on top otherwise false */ function isVarOnTop(node, statements) { var l = statements.length; var i = 0; // skip over directives for (; i < l; ++i) { if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) { break; } } for (; i < l; ++i) { if (!isVariableDeclaration(statements[i])) { return false; } if (statements[i] === node) { return true; } } return false; } /** * Checks whether variable is on top at the global level * @param {ASTNode} node - The node to check * @param {ASTNode} parent - Parent of the node * @returns {void} */ function globalVarCheck(node, parent) { if (!isVarOnTop(node, parent.body)) { context.report({ node: node, message: errorMessage }); } } /** * Checks whether variable is on top at functional block scope level * @param {ASTNode} node - The node to check * @param {ASTNode} parent - Parent of the node * @param {ASTNode} grandParent - Parent of the node's parent * @returns {void} */ function blockScopeVarCheck(node, parent, grandParent) { if (!(/Function/.test(grandParent.type) && parent.type === "BlockStatement" && isVarOnTop(node, parent.body))) { context.report({ node: node, message: errorMessage }); } } //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { "VariableDeclaration[kind='var']": function VariableDeclarationKindVar(node) { if (node.parent.type === "ExportNamedDeclaration") { globalVarCheck(node.parent, node.parent.parent); } else if (node.parent.type === "Program") { globalVarCheck(node, node.parent); } else { blockScopeVarCheck(node, node.parent, node.parent.parent); } } }; } }; },{}],386:[function(require,module,exports){ /** * @fileoverview Rule to flag when IIFE is not wrapped in parens * @author Ilya Volodin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require parentheses around immediate `function` invocations", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/wrap-iife" }, schema: [{ enum: ["outside", "inside", "any"] }, { type: "object", properties: { functionPrototypeMethods: { type: "boolean" } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { var style = context.options[0] || "outside"; var includeFunctionPrototypeMethods = context.options[1] && context.options[1].functionPrototypeMethods || false; var sourceCode = context.getSourceCode(); /** * Check if the node is wrapped in () * @param {ASTNode} node node to evaluate * @returns {boolean} True if it is wrapped * @private */ function wrapped(node) { return astUtils.isParenthesised(sourceCode, node); } /** * Get the function node from an IIFE * @param {ASTNode} node node to evaluate * @returns {ASTNode} node that is the function expression of the given IIFE, or null if none exist */ function getFunctionNodeFromIIFE(node) { var callee = node.callee; if (callee.type === "FunctionExpression") { return callee; } if (includeFunctionPrototypeMethods && callee.type === "MemberExpression" && callee.object.type === "FunctionExpression" && (astUtils.getStaticPropertyName(callee) === "call" || astUtils.getStaticPropertyName(callee) === "apply")) { return callee.object; } return null; } return { CallExpression: function CallExpression(node) { var innerNode = getFunctionNodeFromIIFE(node); if (!innerNode) { return; } var callExpressionWrapped = wrapped(node), functionExpressionWrapped = wrapped(innerNode); if (!callExpressionWrapped && !functionExpressionWrapped) { context.report({ node: node, message: "Wrap an immediate function invocation in parentheses.", fix: function fix(fixer) { var nodeToSurround = style === "inside" ? innerNode : node; return fixer.replaceText(nodeToSurround, "(" + sourceCode.getText(nodeToSurround) + ")"); } }); } else if (style === "inside" && !functionExpressionWrapped) { context.report({ node: node, message: "Wrap only the function expression in parens.", fix: function fix(fixer) { /* * The outer call expression will always be wrapped at this point. * Replace the range between the end of the function expression and the end of the call expression. * for example, in `(function(foo) {}(bar))`, the range `(bar))` should get replaced with `)(bar)`. * Replace the parens from the outer expression, and parenthesize the function expression. */ var parenAfter = sourceCode.getTokenAfter(node); return fixer.replaceTextRange([innerNode.range[1], parenAfter.range[1]], ")" + sourceCode.getText().slice(innerNode.range[1], parenAfter.range[0])); } }); } else if (style === "outside" && !callExpressionWrapped) { context.report({ node: node, message: "Move the invocation into the parens that contain the function.", fix: function fix(fixer) { /* * The inner function expression will always be wrapped at this point. * It's only necessary to replace the range between the end of the function expression * and the call expression. For example, in `(function(foo) {})(bar)`, the range `)(bar)` * should get replaced with `(bar))`. */ var parenAfter = sourceCode.getTokenAfter(innerNode); return fixer.replaceTextRange([parenAfter.range[0], node.range[1]], sourceCode.getText().slice(parenAfter.range[1], node.range[1]) + ")"); } }); } } }; } }; },{"../util/ast-utils":405}],387:[function(require,module,exports){ /** * @fileoverview Rule to flag when regex literals are not wrapped in parens * @author Matt DuVall */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require parenthesis around regex literals", category: "Stylistic Issues", recommended: false, url: "https://eslint.org/docs/rules/wrap-regex" }, schema: [], fixable: "code", messages: { requireParens: "Wrap the regexp literal in parens to disambiguate the slash." } }, create: function create(context) { var sourceCode = context.getSourceCode(); return { Literal: function Literal(node) { var token = sourceCode.getFirstToken(node), nodeType = token.type; if (nodeType === "RegularExpression") { var beforeToken = sourceCode.getTokenBefore(node); var afterToken = sourceCode.getTokenAfter(node); var ancestors = context.getAncestors(); var grandparent = ancestors[ancestors.length - 1]; if (grandparent.type === "MemberExpression" && grandparent.object === node && !(beforeToken && beforeToken.value === "(" && afterToken && afterToken.value === ")")) { context.report({ node: node, messageId: "requireParens", fix: function fix(fixer) { return fixer.replaceText(node, "(" + sourceCode.getText(node) + ")"); } }); } } } }; } }; },{}],388:[function(require,module,exports){ /** * @fileoverview Rule to check the spacing around the * in yield* expressions. * @author Bryan Smith */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "layout", docs: { description: "require or disallow spacing around the `*` in `yield*` expressions", category: "ECMAScript 6", recommended: false, url: "https://eslint.org/docs/rules/yield-star-spacing" }, fixable: "whitespace", schema: [{ oneOf: [{ enum: ["before", "after", "both", "neither"] }, { type: "object", properties: { before: { type: "boolean" }, after: { type: "boolean" } }, additionalProperties: false }] }] }, create: function create(context) { var sourceCode = context.getSourceCode(); var mode = function (option) { if (!option || typeof option === "string") { return { before: { before: true, after: false }, after: { before: false, after: true }, both: { before: true, after: true }, neither: { before: false, after: false } }[option || "after"]; } return option; }(context.options[0]); /** * Checks the spacing between two tokens before or after the star token. * @param {string} side Either "before" or "after". * @param {Token} leftToken `function` keyword token if side is "before", or * star token if side is "after". * @param {Token} rightToken Star token if side is "before", or identifier * token if side is "after". * @returns {void} */ function checkSpacing(side, leftToken, rightToken) { if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken) !== mode[side]) { var after = leftToken.value === "*"; var spaceRequired = mode[side]; var node = after ? leftToken : rightToken; var type = spaceRequired ? "Missing" : "Unexpected"; var message = "{{type}} space {{side}} *."; context.report({ node: node, message: message, data: { type: type, side: side }, fix: function fix(fixer) { if (spaceRequired) { if (after) { return fixer.insertTextAfter(node, " "); } return fixer.insertTextBefore(node, " "); } return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); } }); } } /** * Enforces the spacing around the star if node is a yield* expression. * @param {ASTNode} node A yield expression node. * @returns {void} */ function checkExpression(node) { if (!node.delegate) { return; } var tokens = sourceCode.getFirstTokens(node, 3); var yieldToken = tokens[0]; var starToken = tokens[1]; var nextToken = tokens[2]; checkSpacing("before", yieldToken, starToken); checkSpacing("after", starToken, nextToken); } return { YieldExpression: checkExpression }; } }; },{}],389:[function(require,module,exports){ /** * @fileoverview Rule to require or disallow yoda comparisons * @author Nicholas C. Zakas */ "use strict"; //-------------------------------------------------------------------------- // Requirements //-------------------------------------------------------------------------- var astUtils = require("../util/ast-utils"); //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- /** * Determines whether an operator is a comparison operator. * @param {string} operator The operator to check. * @returns {boolean} Whether or not it is a comparison operator. */ function isComparisonOperator(operator) { return (/^(==|===|!=|!==|<|>|<=|>=)$/.test(operator) ); } /** * Determines whether an operator is an equality operator. * @param {string} operator The operator to check. * @returns {boolean} Whether or not it is an equality operator. */ function isEqualityOperator(operator) { return (/^(==|===)$/.test(operator) ); } /** * Determines whether an operator is one used in a range test. * Allowed operators are `<` and `<=`. * @param {string} operator The operator to check. * @returns {boolean} Whether the operator is used in range tests. */ function isRangeTestOperator(operator) { return ["<", "<="].indexOf(operator) >= 0; } /** * Determines whether a non-Literal node is a negative number that should be * treated as if it were a single Literal node. * @param {ASTNode} node Node to test. * @returns {boolean} True if the node is a negative number that looks like a * real literal and should be treated as such. */ function looksLikeLiteral(node) { return node.type === "UnaryExpression" && node.operator === "-" && node.prefix && node.argument.type === "Literal" && typeof node.argument.value === "number"; } /** * Attempts to derive a Literal node from nodes that are treated like literals. * @param {ASTNode} node Node to normalize. * @param {number} [defaultValue] The default value to be returned if the node * is not a Literal. * @returns {ASTNode} One of the following options. * 1. The original node if the node is already a Literal * 2. A normalized Literal node with the negative number as the value if the * node represents a negative number literal. * 3. The Literal node which has the `defaultValue` argument if it exists. * 4. Otherwise `null`. */ function getNormalizedLiteral(node, defaultValue) { if (node.type === "Literal") { return node; } if (looksLikeLiteral(node)) { return { type: "Literal", value: -node.argument.value, raw: "-" + node.argument.value }; } if (defaultValue) { return { type: "Literal", value: defaultValue, raw: String(defaultValue) }; } return null; } /** * Checks whether two expressions reference the same value. For example: * a = a * a.b = a.b * a[0] = a[0] * a['b'] = a['b'] * @param {ASTNode} a Left side of the comparison. * @param {ASTNode} b Right side of the comparison. * @returns {boolean} True if both sides match and reference the same value. */ function same(a, b) { if (a.type !== b.type) { return false; } switch (a.type) { case "Identifier": return a.name === b.name; case "Literal": return a.value === b.value; case "MemberExpression": { var nameA = astUtils.getStaticPropertyName(a); // x.y = x["y"] if (nameA) { return same(a.object, b.object) && nameA === astUtils.getStaticPropertyName(b); } /* * x[0] = x[0] * x[y] = x[y] * x.y = x.y */ return a.computed === b.computed && same(a.object, b.object) && same(a.property, b.property); } case "ThisExpression": return true; default: return false; } } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { type: "suggestion", docs: { description: "require or disallow \"Yoda\" conditions", category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/yoda" }, schema: [{ enum: ["always", "never"] }, { type: "object", properties: { exceptRange: { type: "boolean" }, onlyEquality: { type: "boolean" } }, additionalProperties: false }], fixable: "code" }, create: function create(context) { // Default to "never" (!always) if no option var always = context.options[0] === "always"; var exceptRange = context.options[1] && context.options[1].exceptRange; var onlyEquality = context.options[1] && context.options[1].onlyEquality; var sourceCode = context.getSourceCode(); /** * Determines whether node represents a range test. * A range test is a "between" test like `(0 <= x && x < 1)` or an "outside" * test like `(x < 0 || 1 <= x)`. It must be wrapped in parentheses, and * both operators must be `<` or `<=`. Finally, the literal on the left side * must be less than or equal to the literal on the right side so that the * test makes any sense. * @param {ASTNode} node LogicalExpression node to test. * @returns {boolean} Whether node is a range test. */ function isRangeTest(node) { var left = node.left, right = node.right; /** * Determines whether node is of the form `0 <= x && x < 1`. * @returns {boolean} Whether node is a "between" range test. */ function isBetweenTest() { var leftLiteral = void 0, rightLiteral = void 0; return node.operator === "&&" && (leftLiteral = getNormalizedLiteral(left.left)) && (rightLiteral = getNormalizedLiteral(right.right, Number.POSITIVE_INFINITY)) && leftLiteral.value <= rightLiteral.value && same(left.right, right.left); } /** * Determines whether node is of the form `x < 0 || 1 <= x`. * @returns {boolean} Whether node is an "outside" range test. */ function isOutsideTest() { var leftLiteral = void 0, rightLiteral = void 0; return node.operator === "||" && (leftLiteral = getNormalizedLiteral(left.right, Number.NEGATIVE_INFINITY)) && (rightLiteral = getNormalizedLiteral(right.left)) && leftLiteral.value <= rightLiteral.value && same(left.left, right.right); } /** * Determines whether node is wrapped in parentheses. * @returns {boolean} Whether node is preceded immediately by an open * paren token and followed immediately by a close * paren token. */ function isParenWrapped() { return astUtils.isParenthesised(sourceCode, node); } return node.type === "LogicalExpression" && left.type === "BinaryExpression" && right.type === "BinaryExpression" && isRangeTestOperator(left.operator) && isRangeTestOperator(right.operator) && (isBetweenTest() || isOutsideTest()) && isParenWrapped(); } var OPERATOR_FLIP_MAP = { "===": "===", "!==": "!==", "==": "==", "!=": "!=", "<": ">", ">": "<", "<=": ">=", ">=": "<=" }; /** * Returns a string representation of a BinaryExpression node with its sides/operator flipped around. * @param {ASTNode} node The BinaryExpression node * @returns {string} A string representation of the node with the sides and operator flipped */ function getFlippedString(node) { var operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, function (token) { return token.value === node.operator; }); var textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]); var textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]); var leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]); var rightText = sourceCode.getText().slice(sourceCode.getTokenAfter(operatorToken).range[0], node.range[1]); return rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { BinaryExpression: function BinaryExpression(node) { var expectedLiteral = always ? node.left : node.right; var expectedNonLiteral = always ? node.right : node.left; // If `expectedLiteral` is not a literal, and `expectedNonLiteral` is a literal, raise an error. if ((expectedNonLiteral.type === "Literal" || looksLikeLiteral(expectedNonLiteral)) && !(expectedLiteral.type === "Literal" || looksLikeLiteral(expectedLiteral)) && !(!isEqualityOperator(node.operator) && onlyEquality) && isComparisonOperator(node.operator) && !(exceptRange && isRangeTest(context.getAncestors().pop()))) { context.report({ node: node, message: "Expected literal to be on the {{expectedSide}} side of {{operator}}.", data: { operator: node.operator, expectedSide: always ? "left" : "right" }, fix: function fix(fixer) { return fixer.replaceText(node, getFlippedString(node)); } }); } } }; } }; },{"../util/ast-utils":405}],390:[function(require,module,exports){ /** * @fileoverview Define the cursor which iterates tokens and comments in reverse. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Cursor = require("./cursor"); var utils = require("./utils"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The cursor which iterates tokens and comments in reverse. */ module.exports = function (_Cursor) { _inherits(BackwardTokenCommentCursor, _Cursor); /** * Initializes this cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. */ function BackwardTokenCommentCursor(tokens, comments, indexMap, startLoc, endLoc) { _classCallCheck(this, BackwardTokenCommentCursor); var _this = _possibleConstructorReturn(this, (BackwardTokenCommentCursor.__proto__ || Object.getPrototypeOf(BackwardTokenCommentCursor)).call(this)); _this.tokens = tokens; _this.comments = comments; _this.tokenIndex = utils.getLastIndex(tokens, indexMap, endLoc); _this.commentIndex = utils.search(comments, endLoc) - 1; _this.border = startLoc; return _this; } /** @inheritdoc */ _createClass(BackwardTokenCommentCursor, [{ key: "moveNext", value: function moveNext() { var token = this.tokenIndex >= 0 ? this.tokens[this.tokenIndex] : null; var comment = this.commentIndex >= 0 ? this.comments[this.commentIndex] : null; if (token && (!comment || token.range[1] > comment.range[1])) { this.current = token; this.tokenIndex -= 1; } else if (comment) { this.current = comment; this.commentIndex -= 1; } else { this.current = null; } return Boolean(this.current) && (this.border === -1 || this.current.range[0] >= this.border); } }]); return BackwardTokenCommentCursor; }(Cursor); },{"./cursor":392,"./utils":402}],391:[function(require,module,exports){ /** * @fileoverview Define the cursor which iterates tokens only in reverse. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Cursor = require("./cursor"); var utils = require("./utils"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The cursor which iterates tokens only in reverse. */ module.exports = function (_Cursor) { _inherits(BackwardTokenCursor, _Cursor); /** * Initializes this cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. */ function BackwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc) { _classCallCheck(this, BackwardTokenCursor); var _this = _possibleConstructorReturn(this, (BackwardTokenCursor.__proto__ || Object.getPrototypeOf(BackwardTokenCursor)).call(this)); _this.tokens = tokens; _this.index = utils.getLastIndex(tokens, indexMap, endLoc); _this.indexEnd = utils.getFirstIndex(tokens, indexMap, startLoc); return _this; } /** @inheritdoc */ _createClass(BackwardTokenCursor, [{ key: "moveNext", value: function moveNext() { if (this.index >= this.indexEnd) { this.current = this.tokens[this.index]; this.index -= 1; return true; } return false; } /* * * Shorthand for performance. * */ /** @inheritdoc */ }, { key: "getOneToken", value: function getOneToken() { return this.index >= this.indexEnd ? this.tokens[this.index] : null; } }]); return BackwardTokenCursor; }(Cursor); },{"./cursor":392,"./utils":402}],392:[function(require,module,exports){ /** * @fileoverview Define the abstract class about cursors which iterate tokens. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The abstract class about cursors which iterate tokens. * * This class has 2 abstract methods. * * - `current: Token | Comment | null` ... The current token. * - `moveNext(): boolean` ... Moves this cursor to the next token. If the next token didn't exist, it returns `false`. * * This is similar to ES2015 Iterators. * However, Iterators were slow (at 2017-01), so I created this class as similar to C# IEnumerable. * * There are the following known sub classes. * * - ForwardTokenCursor .......... The cursor which iterates tokens only. * - BackwardTokenCursor ......... The cursor which iterates tokens only in reverse. * - ForwardTokenCommentCursor ... The cursor which iterates tokens and comments. * - BackwardTokenCommentCursor .. The cursor which iterates tokens and comments in reverse. * - DecorativeCursor * - FilterCursor ............ The cursor which ignores the specified tokens. * - SkipCursor .............. The cursor which ignores the first few tokens. * - LimitCursor ............. The cursor which limits the count of tokens. * */ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } module.exports = function () { /** * Initializes this cursor. */ function Cursor() { _classCallCheck(this, Cursor); this.current = null; } /** * Gets the first token. * This consumes this cursor. * @returns {Token|Comment} The first token or null. */ _createClass(Cursor, [{ key: "getOneToken", value: function getOneToken() { return this.moveNext() ? this.current : null; } /** * Gets the first tokens. * This consumes this cursor. * @returns {(Token|Comment)[]} All tokens. */ }, { key: "getAllTokens", value: function getAllTokens() { var tokens = []; while (this.moveNext()) { tokens.push(this.current); } return tokens; } /** * Moves this cursor to the next token. * @returns {boolean} `true` if the next token exists. * @abstract */ /* istanbul ignore next */ }, { key: "moveNext", value: function moveNext() { // eslint-disable-line class-methods-use-this throw new Error("Not implemented."); } }]); return Cursor; }(); },{}],393:[function(require,module,exports){ /** * @fileoverview Define 2 token factories; forward and backward. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var BackwardTokenCommentCursor = require("./backward-token-comment-cursor"); var BackwardTokenCursor = require("./backward-token-cursor"); var FilterCursor = require("./filter-cursor"); var ForwardTokenCommentCursor = require("./forward-token-comment-cursor"); var ForwardTokenCursor = require("./forward-token-cursor"); var LimitCursor = require("./limit-cursor"); var SkipCursor = require("./skip-cursor"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * The cursor factory. * @private */ var CursorFactory = function () { /** * Initializes this cursor. * @param {Function} TokenCursor - The class of the cursor which iterates tokens only. * @param {Function} TokenCommentCursor - The class of the cursor which iterates the mix of tokens and comments. */ function CursorFactory(TokenCursor, TokenCommentCursor) { _classCallCheck(this, CursorFactory); this.TokenCursor = TokenCursor; this.TokenCommentCursor = TokenCommentCursor; } /** * Creates a base cursor instance that can be decorated by createCursor. * * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {boolean} includeComments - The flag to iterate comments as well. * @returns {Cursor} The created base cursor. */ _createClass(CursorFactory, [{ key: "createBaseCursor", value: function createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments) { var Cursor = includeComments ? this.TokenCommentCursor : this.TokenCursor; return new Cursor(tokens, comments, indexMap, startLoc, endLoc); } /** * Creates a cursor that iterates tokens with normalized options. * * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {boolean} includeComments - The flag to iterate comments as well. * @param {Function|null} filter - The predicate function to choose tokens. * @param {number} skip - The count of tokens the cursor skips. * @param {number} count - The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. * @returns {Cursor} The created cursor. */ }, { key: "createCursor", value: function createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, count) { var cursor = this.createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments); if (filter) { cursor = new FilterCursor(cursor, filter); } if (skip >= 1) { cursor = new SkipCursor(cursor, skip); } if (count >= 0) { cursor = new LimitCursor(cursor, count); } return cursor; } }]); return CursorFactory; }(); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ exports.forward = new CursorFactory(ForwardTokenCursor, ForwardTokenCommentCursor); exports.backward = new CursorFactory(BackwardTokenCursor, BackwardTokenCommentCursor); },{"./backward-token-comment-cursor":390,"./backward-token-cursor":391,"./filter-cursor":395,"./forward-token-comment-cursor":396,"./forward-token-cursor":397,"./limit-cursor":399,"./skip-cursor":401}],394:[function(require,module,exports){ /** * @fileoverview Define the abstract class about cursors which manipulate another cursor. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Cursor = require("./cursor"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The abstract class about cursors which manipulate another cursor. */ module.exports = function (_Cursor) { _inherits(DecorativeCursor, _Cursor); /** * Initializes this cursor. * @param {Cursor} cursor - The cursor to be decorated. */ function DecorativeCursor(cursor) { _classCallCheck(this, DecorativeCursor); var _this = _possibleConstructorReturn(this, (DecorativeCursor.__proto__ || Object.getPrototypeOf(DecorativeCursor)).call(this)); _this.cursor = cursor; return _this; } /** @inheritdoc */ _createClass(DecorativeCursor, [{ key: "moveNext", value: function moveNext() { var retv = this.cursor.moveNext(); this.current = this.cursor.current; return retv; } }]); return DecorativeCursor; }(Cursor); },{"./cursor":392}],395:[function(require,module,exports){ /** * @fileoverview Define the cursor which ignores specified tokens. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var DecorativeCursor = require("./decorative-cursor"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The decorative cursor which ignores specified tokens. */ module.exports = function (_DecorativeCursor) { _inherits(FilterCursor, _DecorativeCursor); /** * Initializes this cursor. * @param {Cursor} cursor - The cursor to be decorated. * @param {Function} predicate - The predicate function to decide tokens this cursor iterates. */ function FilterCursor(cursor, predicate) { _classCallCheck(this, FilterCursor); var _this = _possibleConstructorReturn(this, (FilterCursor.__proto__ || Object.getPrototypeOf(FilterCursor)).call(this, cursor)); _this.predicate = predicate; return _this; } /** @inheritdoc */ _createClass(FilterCursor, [{ key: "moveNext", value: function moveNext() { var predicate = this.predicate; while (_get(FilterCursor.prototype.__proto__ || Object.getPrototypeOf(FilterCursor.prototype), "moveNext", this).call(this)) { if (predicate(this.current)) { return true; } } return false; } }]); return FilterCursor; }(DecorativeCursor); },{"./decorative-cursor":394}],396:[function(require,module,exports){ /** * @fileoverview Define the cursor which iterates tokens and comments. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Cursor = require("./cursor"); var utils = require("./utils"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The cursor which iterates tokens and comments. */ module.exports = function (_Cursor) { _inherits(ForwardTokenCommentCursor, _Cursor); /** * Initializes this cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. */ function ForwardTokenCommentCursor(tokens, comments, indexMap, startLoc, endLoc) { _classCallCheck(this, ForwardTokenCommentCursor); var _this = _possibleConstructorReturn(this, (ForwardTokenCommentCursor.__proto__ || Object.getPrototypeOf(ForwardTokenCommentCursor)).call(this)); _this.tokens = tokens; _this.comments = comments; _this.tokenIndex = utils.getFirstIndex(tokens, indexMap, startLoc); _this.commentIndex = utils.search(comments, startLoc); _this.border = endLoc; return _this; } /** @inheritdoc */ _createClass(ForwardTokenCommentCursor, [{ key: "moveNext", value: function moveNext() { var token = this.tokenIndex < this.tokens.length ? this.tokens[this.tokenIndex] : null; var comment = this.commentIndex < this.comments.length ? this.comments[this.commentIndex] : null; if (token && (!comment || token.range[0] < comment.range[0])) { this.current = token; this.tokenIndex += 1; } else if (comment) { this.current = comment; this.commentIndex += 1; } else { this.current = null; } return Boolean(this.current) && (this.border === -1 || this.current.range[1] <= this.border); } }]); return ForwardTokenCommentCursor; }(Cursor); },{"./cursor":392,"./utils":402}],397:[function(require,module,exports){ /** * @fileoverview Define the cursor which iterates tokens only. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Cursor = require("./cursor"); var utils = require("./utils"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The cursor which iterates tokens only. */ module.exports = function (_Cursor) { _inherits(ForwardTokenCursor, _Cursor); /** * Initializes this cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. */ function ForwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc) { _classCallCheck(this, ForwardTokenCursor); var _this = _possibleConstructorReturn(this, (ForwardTokenCursor.__proto__ || Object.getPrototypeOf(ForwardTokenCursor)).call(this)); _this.tokens = tokens; _this.index = utils.getFirstIndex(tokens, indexMap, startLoc); _this.indexEnd = utils.getLastIndex(tokens, indexMap, endLoc); return _this; } /** @inheritdoc */ _createClass(ForwardTokenCursor, [{ key: "moveNext", value: function moveNext() { if (this.index <= this.indexEnd) { this.current = this.tokens[this.index]; this.index += 1; return true; } return false; } /* * * Shorthand for performance. * */ /** @inheritdoc */ }, { key: "getOneToken", value: function getOneToken() { return this.index <= this.indexEnd ? this.tokens[this.index] : null; } /** @inheritdoc */ }, { key: "getAllTokens", value: function getAllTokens() { return this.tokens.slice(this.index, this.indexEnd + 1); } }]); return ForwardTokenCursor; }(Cursor); },{"./cursor":392,"./utils":402}],398:[function(require,module,exports){ /** * @fileoverview Object to handle access and retrieval of tokens. * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var assert = require("assert"); var cursors = require("./cursors"); var ForwardTokenCursor = require("./forward-token-cursor"); var PaddedTokenCursor = require("./padded-token-cursor"); var utils = require("./utils"); var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var TOKENS = Symbol("tokens"); var COMMENTS = Symbol("comments"); var INDEX_MAP = Symbol("indexMap"); /** * Creates the map from locations to indices in `tokens`. * * The first/last location of tokens is mapped to the index of the token. * The first/last location of comments is mapped to the index of the next token of each comment. * * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @returns {Object} The map from locations to indices in `tokens`. * @private */ function createIndexMap(tokens, comments) { var map = Object.create(null); var tokenIndex = 0; var commentIndex = 0; var nextStart = 0; var range = null; while (tokenIndex < tokens.length || commentIndex < comments.length) { nextStart = commentIndex < comments.length ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER; while (tokenIndex < tokens.length && (range = tokens[tokenIndex].range)[0] < nextStart) { map[range[0]] = tokenIndex; map[range[1] - 1] = tokenIndex; tokenIndex += 1; } nextStart = tokenIndex < tokens.length ? tokens[tokenIndex].range[0] : Number.MAX_SAFE_INTEGER; while (commentIndex < comments.length && (range = comments[commentIndex].range)[0] < nextStart) { map[range[0]] = tokenIndex; map[range[1] - 1] = tokenIndex; commentIndex += 1; } } return map; } /** * Creates the cursor iterates tokens with options. * * @param {CursorFactory} factory - The cursor factory to initialize cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {number|Function|Object} [opts=0] - The option object. If this is a number then it's `opts.skip`. If this is a function then it's `opts.filter`. * @param {boolean} [opts.includeComments=false] - The flag to iterate comments as well. * @param {Function|null} [opts.filter=null] - The predicate function to choose tokens. * @param {number} [opts.skip=0] - The count of tokens the cursor skips. * @returns {Cursor} The created cursor. * @private */ function createCursorWithSkip(factory, tokens, comments, indexMap, startLoc, endLoc, opts) { var includeComments = false; var skip = 0; var filter = null; if (typeof opts === "number") { skip = opts | 0; } else if (typeof opts === "function") { filter = opts; } else if (opts) { includeComments = !!opts.includeComments; skip = opts.skip | 0; filter = opts.filter || null; } assert(skip >= 0, "options.skip should be zero or a positive integer."); assert(!filter || typeof filter === "function", "options.filter should be a function."); return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, -1); } /** * Creates the cursor iterates tokens with options. * * @param {CursorFactory} factory - The cursor factory to initialize cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {number|Function|Object} [opts=0] - The option object. If this is a number then it's `opts.count`. If this is a function then it's `opts.filter`. * @param {boolean} [opts.includeComments] - The flag to iterate comments as well. * @param {Function|null} [opts.filter=null] - The predicate function to choose tokens. * @param {number} [opts.count=0] - The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. * @returns {Cursor} The created cursor. * @private */ function createCursorWithCount(factory, tokens, comments, indexMap, startLoc, endLoc, opts) { var includeComments = false; var count = 0; var countExists = false; var filter = null; if (typeof opts === "number") { count = opts | 0; countExists = true; } else if (typeof opts === "function") { filter = opts; } else if (opts) { includeComments = !!opts.includeComments; count = opts.count | 0; countExists = typeof opts.count === "number"; filter = opts.filter || null; } assert(count >= 0, "options.count should be zero or a positive integer."); assert(!filter || typeof filter === "function", "options.filter should be a function."); return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, 0, countExists ? count : -1); } /** * Creates the cursor iterates tokens with options. * This is overload function of the below. * * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {Function|Object} opts - The option object. If this is a function then it's `opts.filter`. * @param {boolean} [opts.includeComments] - The flag to iterate comments as well. * @param {Function|null} [opts.filter=null] - The predicate function to choose tokens. * @param {number} [opts.count=0] - The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. * @returns {Cursor} The created cursor. * @private */ /** * Creates the cursor iterates tokens with options. * * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {number} [beforeCount=0] - The number of tokens before the node to retrieve. * @param {boolean} [afterCount=0] - The number of tokens after the node to retrieve. * @returns {Cursor} The created cursor. * @private */ function createCursorWithPadding(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) { if (typeof beforeCount === "undefined" && typeof afterCount === "undefined") { return new ForwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc); } if (typeof beforeCount === "number" || typeof beforeCount === "undefined") { return new PaddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount | 0, afterCount | 0); } return createCursorWithCount(cursors.forward, tokens, comments, indexMap, startLoc, endLoc, beforeCount); } /** * Gets comment tokens that are adjacent to the current cursor position. * @param {Cursor} cursor - A cursor instance. * @returns {Array} An array of comment tokens adjacent to the current cursor position. * @private */ function getAdjacentCommentTokensFromCursor(cursor) { var tokens = []; var currentToken = cursor.getOneToken(); while (currentToken && astUtils.isCommentToken(currentToken)) { tokens.push(currentToken); currentToken = cursor.getOneToken(); } return tokens; } //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The token store. * * This class provides methods to get tokens by locations as fast as possible. * The methods are a part of public API, so we should be careful if it changes this class. * * People can get tokens in O(1) by the hash map which is mapping from the location of tokens/comments to tokens. * Also people can get a mix of tokens and comments in O(log k), the k is the number of comments. * Assuming that comments to be much fewer than tokens, this does not make hash map from token's locations to comments to reduce memory cost. * This uses binary-searching instead for comments. */ module.exports = function () { /** * Initializes this token store. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. */ function TokenStore(tokens, comments) { _classCallCheck(this, TokenStore); this[TOKENS] = tokens; this[COMMENTS] = comments; this[INDEX_MAP] = createIndexMap(tokens, comments); } //-------------------------------------------------------------------------- // Gets single token. //-------------------------------------------------------------------------- /** * Gets the token starting at the specified index. * @param {number} offset - Index of the start of the token's range. * @param {Object} [options=0] - The option object. * @param {boolean} [options.includeComments=false] - The flag to iterate comments as well. * @returns {Token|null} The token starting at index, or null if no such token. */ _createClass(TokenStore, [{ key: "getTokenByRangeStart", value: function getTokenByRangeStart(offset, options) { var includeComments = options && options.includeComments; var token = cursors.forward.createBaseCursor(this[TOKENS], this[COMMENTS], this[INDEX_MAP], offset, -1, includeComments).getOneToken(); if (token && token.range[0] === offset) { return token; } return null; } /** * Gets the first token of the given node. * @param {ASTNode} node - The AST node. * @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`. * @param {boolean} [options.includeComments=false] - The flag to iterate comments as well. * @param {Function|null} [options.filter=null] - The predicate function to choose tokens. * @param {number} [options.skip=0] - The count of tokens the cursor skips. * @returns {Token|null} An object representing the token. */ }, { key: "getFirstToken", value: function getFirstToken(node, options) { return createCursorWithSkip(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[0], node.range[1], options).getOneToken(); } /** * Gets the last token of the given node. * @param {ASTNode} node - The AST node. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstToken() * @returns {Token|null} An object representing the token. */ }, { key: "getLastToken", value: function getLastToken(node, options) { return createCursorWithSkip(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[0], node.range[1], options).getOneToken(); } /** * Gets the token that precedes a given node or token. * @param {ASTNode|Token|Comment} node - The AST node or token. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstToken() * @returns {Token|null} An object representing the token. */ }, { key: "getTokenBefore", value: function getTokenBefore(node, options) { return createCursorWithSkip(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], -1, node.range[0], options).getOneToken(); } /** * Gets the token that follows a given node or token. * @param {ASTNode|Token|Comment} node - The AST node or token. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstToken() * @returns {Token|null} An object representing the token. */ }, { key: "getTokenAfter", value: function getTokenAfter(node, options) { return createCursorWithSkip(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[1], -1, options).getOneToken(); } /** * Gets the first token between two non-overlapping nodes. * @param {ASTNode|Token|Comment} left - Node before the desired token range. * @param {ASTNode|Token|Comment} right - Node after the desired token range. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstToken() * @returns {Token|null} An object representing the token. */ }, { key: "getFirstTokenBetween", value: function getFirstTokenBetween(left, right, options) { return createCursorWithSkip(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], left.range[1], right.range[0], options).getOneToken(); } /** * Gets the last token between two non-overlapping nodes. * @param {ASTNode|Token|Comment} left Node before the desired token range. * @param {ASTNode|Token|Comment} right Node after the desired token range. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstToken() * @returns {Token|null} An object representing the token. */ }, { key: "getLastTokenBetween", value: function getLastTokenBetween(left, right, options) { return createCursorWithSkip(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], left.range[1], right.range[0], options).getOneToken(); } /** * Gets the token that precedes a given node or token in the token stream. * This is defined for backward compatibility. Use `includeComments` option instead. * TODO: We have a plan to remove this in a future major version. * @param {ASTNode|Token|Comment} node The AST node or token. * @param {number} [skip=0] A number of tokens to skip. * @returns {Token|null} An object representing the token. * @deprecated */ }, { key: "getTokenOrCommentBefore", value: function getTokenOrCommentBefore(node, skip) { return this.getTokenBefore(node, { includeComments: true, skip: skip }); } /** * Gets the token that follows a given node or token in the token stream. * This is defined for backward compatibility. Use `includeComments` option instead. * TODO: We have a plan to remove this in a future major version. * @param {ASTNode|Token|Comment} node The AST node or token. * @param {number} [skip=0] A number of tokens to skip. * @returns {Token|null} An object representing the token. * @deprecated */ }, { key: "getTokenOrCommentAfter", value: function getTokenOrCommentAfter(node, skip) { return this.getTokenAfter(node, { includeComments: true, skip: skip }); } //-------------------------------------------------------------------------- // Gets multiple tokens. //-------------------------------------------------------------------------- /** * Gets the first `count` tokens of the given node. * @param {ASTNode} node - The AST node. * @param {number|Function|Object} [options=0] - The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`. * @param {boolean} [options.includeComments=false] - The flag to iterate comments as well. * @param {Function|null} [options.filter=null] - The predicate function to choose tokens. * @param {number} [options.count=0] - The maximum count of tokens the cursor iterates. * @returns {Token[]} Tokens. */ }, { key: "getFirstTokens", value: function getFirstTokens(node, options) { return createCursorWithCount(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[0], node.range[1], options).getAllTokens(); } /** * Gets the last `count` tokens of the given node. * @param {ASTNode} node - The AST node. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstTokens() * @returns {Token[]} Tokens. */ }, { key: "getLastTokens", value: function getLastTokens(node, options) { return createCursorWithCount(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[0], node.range[1], options).getAllTokens().reverse(); } /** * Gets the `count` tokens that precedes a given node or token. * @param {ASTNode|Token|Comment} node - The AST node or token. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstTokens() * @returns {Token[]} Tokens. */ }, { key: "getTokensBefore", value: function getTokensBefore(node, options) { return createCursorWithCount(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], -1, node.range[0], options).getAllTokens().reverse(); } /** * Gets the `count` tokens that follows a given node or token. * @param {ASTNode|Token|Comment} node - The AST node or token. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstTokens() * @returns {Token[]} Tokens. */ }, { key: "getTokensAfter", value: function getTokensAfter(node, options) { return createCursorWithCount(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[1], -1, options).getAllTokens(); } /** * Gets the first `count` tokens between two non-overlapping nodes. * @param {ASTNode|Token|Comment} left - Node before the desired token range. * @param {ASTNode|Token|Comment} right - Node after the desired token range. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstTokens() * @returns {Token[]} Tokens between left and right. */ }, { key: "getFirstTokensBetween", value: function getFirstTokensBetween(left, right, options) { return createCursorWithCount(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], left.range[1], right.range[0], options).getAllTokens(); } /** * Gets the last `count` tokens between two non-overlapping nodes. * @param {ASTNode|Token|Comment} left Node before the desired token range. * @param {ASTNode|Token|Comment} right Node after the desired token range. * @param {number|Function|Object} [options=0] - The option object. Same options as getFirstTokens() * @returns {Token[]} Tokens between left and right. */ }, { key: "getLastTokensBetween", value: function getLastTokensBetween(left, right, options) { return createCursorWithCount(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], left.range[1], right.range[0], options).getAllTokens().reverse(); } /** * Gets all tokens that are related to the given node. * @param {ASTNode} node - The AST node. * @param {Function|Object} options The option object. If this is a function then it's `options.filter`. * @param {boolean} [options.includeComments=false] - The flag to iterate comments as well. * @param {Function|null} [options.filter=null] - The predicate function to choose tokens. * @param {number} [options.count=0] - The maximum count of tokens the cursor iterates. * @returns {Token[]} Array of objects representing tokens. */ /** * Gets all tokens that are related to the given node. * @param {ASTNode} node - The AST node. * @param {int} [beforeCount=0] - The number of tokens before the node to retrieve. * @param {int} [afterCount=0] - The number of tokens after the node to retrieve. * @returns {Token[]} Array of objects representing tokens. */ }, { key: "getTokens", value: function getTokens(node, beforeCount, afterCount) { return createCursorWithPadding(this[TOKENS], this[COMMENTS], this[INDEX_MAP], node.range[0], node.range[1], beforeCount, afterCount).getAllTokens(); } /** * Gets all of the tokens between two non-overlapping nodes. * @param {ASTNode|Token|Comment} left Node before the desired token range. * @param {ASTNode|Token|Comment} right Node after the desired token range. * @param {Function|Object} options The option object. If this is a function then it's `options.filter`. * @param {boolean} [options.includeComments=false] - The flag to iterate comments as well. * @param {Function|null} [options.filter=null] - The predicate function to choose tokens. * @param {number} [options.count=0] - The maximum count of tokens the cursor iterates. * @returns {Token[]} Tokens between left and right. */ /** * Gets all of the tokens between two non-overlapping nodes. * @param {ASTNode|Token|Comment} left Node before the desired token range. * @param {ASTNode|Token|Comment} right Node after the desired token range. * @param {int} [padding=0] Number of extra tokens on either side of center. * @returns {Token[]} Tokens between left and right. */ }, { key: "getTokensBetween", value: function getTokensBetween(left, right, padding) { return createCursorWithPadding(this[TOKENS], this[COMMENTS], this[INDEX_MAP], left.range[1], right.range[0], padding, padding).getAllTokens(); } //-------------------------------------------------------------------------- // Others. //-------------------------------------------------------------------------- /** * Checks whether any comments exist or not between the given 2 nodes. * * @param {ASTNode} left - The node to check. * @param {ASTNode} right - The node to check. * @returns {boolean} `true` if one or more comments exist. */ }, { key: "commentsExistBetween", value: function commentsExistBetween(left, right) { var index = utils.search(this[COMMENTS], left.range[1]); return index < this[COMMENTS].length && this[COMMENTS][index].range[1] <= right.range[0]; } /** * Gets all comment tokens directly before the given node or token. * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens. * @returns {Array} An array of comments in occurrence order. */ }, { key: "getCommentsBefore", value: function getCommentsBefore(nodeOrToken) { var cursor = createCursorWithCount(cursors.backward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], -1, nodeOrToken.range[0], { includeComments: true }); return getAdjacentCommentTokensFromCursor(cursor).reverse(); } /** * Gets all comment tokens directly after the given node or token. * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens. * @returns {Array} An array of comments in occurrence order. */ }, { key: "getCommentsAfter", value: function getCommentsAfter(nodeOrToken) { var cursor = createCursorWithCount(cursors.forward, this[TOKENS], this[COMMENTS], this[INDEX_MAP], nodeOrToken.range[1], -1, { includeComments: true }); return getAdjacentCommentTokensFromCursor(cursor); } /** * Gets all comment tokens inside the given node. * @param {ASTNode} node The AST node to get the comments for. * @returns {Array} An array of comments in occurrence order. */ }, { key: "getCommentsInside", value: function getCommentsInside(node) { return this.getTokens(node, { includeComments: true, filter: astUtils.isCommentToken }); } }]); return TokenStore; }(); },{"../util/ast-utils":405,"./cursors":393,"./forward-token-cursor":397,"./padded-token-cursor":400,"./utils":402,"assert":46}],399:[function(require,module,exports){ /** * @fileoverview Define the cursor which limits the number of tokens. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var DecorativeCursor = require("./decorative-cursor"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The decorative cursor which limits the number of tokens. */ module.exports = function (_DecorativeCursor) { _inherits(LimitCursor, _DecorativeCursor); /** * Initializes this cursor. * @param {Cursor} cursor - The cursor to be decorated. * @param {number} count - The count of tokens this cursor iterates. */ function LimitCursor(cursor, count) { _classCallCheck(this, LimitCursor); var _this = _possibleConstructorReturn(this, (LimitCursor.__proto__ || Object.getPrototypeOf(LimitCursor)).call(this, cursor)); _this.count = count; return _this; } /** @inheritdoc */ _createClass(LimitCursor, [{ key: "moveNext", value: function moveNext() { if (this.count > 0) { this.count -= 1; return _get(LimitCursor.prototype.__proto__ || Object.getPrototypeOf(LimitCursor.prototype), "moveNext", this).call(this); } return false; } }]); return LimitCursor; }(DecorativeCursor); },{"./decorative-cursor":394}],400:[function(require,module,exports){ /** * @fileoverview Define the cursor which iterates tokens only, with inflated range. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var ForwardTokenCursor = require("./forward-token-cursor"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The cursor which iterates tokens only, with inflated range. * This is for the backward compatibility of padding options. */ module.exports = function (_ForwardTokenCursor) { _inherits(PaddedTokenCursor, _ForwardTokenCursor); /** * Initializes this cursor. * @param {Token[]} tokens - The array of tokens. * @param {Comment[]} comments - The array of comments. * @param {Object} indexMap - The map from locations to indices in `tokens`. * @param {number} startLoc - The start location of the iteration range. * @param {number} endLoc - The end location of the iteration range. * @param {number} beforeCount - The number of tokens this cursor iterates before start. * @param {number} afterCount - The number of tokens this cursor iterates after end. */ function PaddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) { _classCallCheck(this, PaddedTokenCursor); var _this = _possibleConstructorReturn(this, (PaddedTokenCursor.__proto__ || Object.getPrototypeOf(PaddedTokenCursor)).call(this, tokens, comments, indexMap, startLoc, endLoc)); _this.index = Math.max(0, _this.index - beforeCount); _this.indexEnd = Math.min(tokens.length - 1, _this.indexEnd + afterCount); return _this; } return PaddedTokenCursor; }(ForwardTokenCursor); },{"./forward-token-cursor":397}],401:[function(require,module,exports){ /** * @fileoverview Define the cursor which ignores the first few tokens. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var DecorativeCursor = require("./decorative-cursor"); //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * The decorative cursor which ignores the first few tokens. */ module.exports = function (_DecorativeCursor) { _inherits(SkipCursor, _DecorativeCursor); /** * Initializes this cursor. * @param {Cursor} cursor - The cursor to be decorated. * @param {number} count - The count of tokens this cursor skips. */ function SkipCursor(cursor, count) { _classCallCheck(this, SkipCursor); var _this = _possibleConstructorReturn(this, (SkipCursor.__proto__ || Object.getPrototypeOf(SkipCursor)).call(this, cursor)); _this.count = count; return _this; } /** @inheritdoc */ _createClass(SkipCursor, [{ key: "moveNext", value: function moveNext() { while (this.count > 0) { this.count -= 1; if (!_get(SkipCursor.prototype.__proto__ || Object.getPrototypeOf(SkipCursor.prototype), "moveNext", this).call(this)) { return false; } } return _get(SkipCursor.prototype.__proto__ || Object.getPrototypeOf(SkipCursor.prototype), "moveNext", this).call(this); } }]); return SkipCursor; }(DecorativeCursor); },{"./decorative-cursor":394}],402:[function(require,module,exports){ /** * @fileoverview Define utilify functions for token store. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets `token.range[0]` from the given token. * * @param {Node|Token|Comment} token - The token to get. * @returns {number} The start location. * @private */ function getStartLocation(token) { return token.range[0]; } //------------------------------------------------------------------------------ // Exports //------------------------------------------------------------------------------ /** * Binary-searches the index of the first token which is after the given location. * If it was not found, this returns `tokens.length`. * * @param {(Token|Comment)[]} tokens - It searches the token in this list. * @param {number} location - The location to search. * @returns {number} The found index or `tokens.length`. */ exports.search = function search(tokens, location) { return lodash.sortedIndexBy(tokens, { range: [location] }, getStartLocation); }; /** * Gets the index of the `startLoc` in `tokens`. * `startLoc` can be the value of `node.range[1]`, so this checks about `startLoc - 1` as well. * * @param {(Token|Comment)[]} tokens - The tokens to find an index. * @param {Object} indexMap - The map from locations to indices. * @param {number} startLoc - The location to get an index. * @returns {number} The index. */ exports.getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) { if (startLoc in indexMap) { return indexMap[startLoc]; } if (startLoc - 1 in indexMap) { var index = indexMap[startLoc - 1]; var token = index >= 0 && index < tokens.length ? tokens[index] : null; /* * For the map of "comment's location -> token's index", it points the next token of a comment. * In that case, +1 is unnecessary. */ if (token && token.range[0] >= startLoc) { return index; } return index + 1; } return 0; }; /** * Gets the index of the `endLoc` in `tokens`. * The information of end locations are recorded at `endLoc - 1` in `indexMap`, so this checks about `endLoc - 1` as well. * * @param {(Token|Comment)[]} tokens - The tokens to find an index. * @param {Object} indexMap - The map from locations to indices. * @param {number} endLoc - The location to get an index. * @returns {number} The index. */ exports.getLastIndex = function getLastIndex(tokens, indexMap, endLoc) { if (endLoc in indexMap) { return indexMap[endLoc] - 1; } if (endLoc - 1 in indexMap) { var index = indexMap[endLoc - 1]; var token = index >= 0 && index < tokens.length ? tokens[index] : null; /* * For the map of "comment's location -> token's index", it points the next token of a comment. * In that case, -1 is necessary. */ if (token && token.range[1] > endLoc) { return index - 1; } return index; } return tokens.length - 1; }; },{"lodash":92}],403:[function(require,module,exports){ /** * @fileoverview The instance of Ajv validator. * @author Evgeny Poberezkin */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var Ajv = require("ajv"), metaSchema = require("ajv/lib/refs/json-schema-draft-04.json"); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ var ajv = new Ajv({ meta: false, validateSchema: false, missingRefs: "ignore", verbose: true, schemaId: "auto" }); ajv.addMetaSchema(metaSchema); // eslint-disable-next-line no-underscore-dangle ajv._opts.defaultMeta = metaSchema.id; module.exports = ajv; },{"ajv":4,"ajv/lib/refs/json-schema-draft-04.json":44}],404:[function(require,module,exports){ /** * @fileoverview A module that filters reported problems based on `eslint-disable` and `eslint-enable` comments * @author Teddy Katz */ "use strict"; var lodash = require("lodash"); /** * Compares the locations of two objects in a source file * @param {{line: number, column: number}} itemA The first object * @param {{line: number, column: number}} itemB The second object * @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if * itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location. */ function compareLocations(itemA, itemB) { return itemA.line - itemB.line || itemA.column - itemB.column; } /** * This is the same as the exported function, except that it * doesn't handle disable-line and disable-next-line directives, and it always reports unused * disable directives. * @param {Object} options options for applying directives. This is the same as the options * for the exported function, except that `reportUnusedDisableDirectives` is not supported * (this function always reports unused disable directives). * @returns {{problems: Problem[], unusedDisableDirectives: Problem[]}} An object with a list * of filtered problems and unused eslint-disable directives */ function applyDirectives(options) { var problems = []; var nextDirectiveIndex = 0; var currentGlobalDisableDirective = null; var disabledRuleMap = new Map(); // enabledRules is only used when there is a current global disable directive. var enabledRules = new Set(); var usedDisableDirectives = new Set(); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = options.problems[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var problem = _step.value; while (nextDirectiveIndex < options.directives.length && compareLocations(options.directives[nextDirectiveIndex], problem) <= 0) { var directive = options.directives[nextDirectiveIndex++]; switch (directive.type) { case "disable": if (directive.ruleId === null) { currentGlobalDisableDirective = directive; disabledRuleMap.clear(); enabledRules.clear(); } else if (currentGlobalDisableDirective) { enabledRules.delete(directive.ruleId); disabledRuleMap.set(directive.ruleId, directive); } else { disabledRuleMap.set(directive.ruleId, directive); } break; case "enable": if (directive.ruleId === null) { currentGlobalDisableDirective = null; disabledRuleMap.clear(); } else if (currentGlobalDisableDirective) { enabledRules.add(directive.ruleId); disabledRuleMap.delete(directive.ruleId); } else { disabledRuleMap.delete(directive.ruleId); } break; // no default } } if (disabledRuleMap.has(problem.ruleId)) { usedDisableDirectives.add(disabledRuleMap.get(problem.ruleId)); } else if (currentGlobalDisableDirective && !enabledRules.has(problem.ruleId)) { usedDisableDirectives.add(currentGlobalDisableDirective); } else { problems.push(problem); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var unusedDisableDirectives = options.directives.filter(function (directive) { return directive.type === "disable" && !usedDisableDirectives.has(directive); }).map(function (directive) { return { ruleId: null, message: directive.ruleId ? "Unused eslint-disable directive (no problems were reported from '" + directive.ruleId + "')." : "Unused eslint-disable directive (no problems were reported).", line: directive.unprocessedDirective.line, column: directive.unprocessedDirective.column, severity: 2, nodeType: null }; }); return { problems: problems, unusedDisableDirectives: unusedDisableDirectives }; } /** * Given a list of directive comments (i.e. metadata about eslint-disable and eslint-enable comments) and a list * of reported problems, determines which problems should be reported. * @param {Object} options Information about directives and problems * @param {{ * type: ("disable"|"enable"|"disable-line"|"disable-next-line"), * ruleId: (string|null), * line: number, * column: number * }} options.directives Directive comments found in the file, with one-based columns. * Two directive comments can only have the same location if they also have the same type (e.g. a single eslint-disable * comment for two different rules is represented as two directives). * @param {{ruleId: (string|null), line: number, column: number}[]} options.problems * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns. * @param {boolean} options.reportUnusedDisableDirectives If `true`, adds additional problems for unused directives * @returns {{ruleId: (string|null), line: number, column: number}[]} * A list of reported problems that were not disabled by the directive comments. */ module.exports = function (options) { var blockDirectives = options.directives.filter(function (directive) { return directive.type === "disable" || directive.type === "enable"; }).map(function (directive) { return Object.assign({}, directive, { unprocessedDirective: directive }); }).sort(compareLocations); var lineDirectives = lodash.flatMap(options.directives, function (directive) { switch (directive.type) { case "disable": case "enable": return []; case "disable-line": return [{ type: "disable", line: directive.line, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive }, { type: "enable", line: directive.line + 1, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive }]; case "disable-next-line": return [{ type: "disable", line: directive.line + 1, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive }, { type: "enable", line: directive.line + 2, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive }]; default: throw new TypeError("Unrecognized directive type '" + directive.type + "'"); } }).sort(compareLocations); var blockDirectivesResult = applyDirectives({ problems: options.problems, directives: blockDirectives }); var lineDirectivesResult = applyDirectives({ problems: blockDirectivesResult.problems, directives: lineDirectives }); return options.reportUnusedDisableDirectives ? lineDirectivesResult.problems.concat(blockDirectivesResult.unusedDisableDirectives).concat(lineDirectivesResult.unusedDisableDirectives).sort(compareLocations) : lineDirectivesResult.problems; }; },{"lodash":92}],405:[function(require,module,exports){ /** * @fileoverview Common utils for AST. * @author Gyandeep Singh */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var esutils = require("esutils"); var espree = require("espree"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/; var anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/; var arrayOrTypedArrayPattern = /Array$/; var arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/; var bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/; var breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/; var thisTagPattern = /^[\s*]*@this/m; var COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/; var LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]); var LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/; var SHEBANG_MATCHER = /^#!([^\r\n]+)/; // A set of node types that can contain a list of statements var STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]); /** * Checks reference if is non initializer and writable. * @param {Reference} reference - A reference to check. * @param {int} index - The index of the reference in the references. * @param {Reference[]} references - The array that the reference belongs to. * @returns {boolean} Success/Failure * @private */ function isModifyingReference(reference, index, references) { var identifier = reference.identifier; /* * Destructuring assignments can have multiple default value, so * possibly there are multiple writeable references for the same * identifier. */ var modifyingDifferentIdentifier = index === 0 || references[index - 1].identifier !== identifier; return identifier && reference.init === false && reference.isWrite() && modifyingDifferentIdentifier; } /** * Checks whether the given string starts with uppercase or not. * * @param {string} s - The string to check. * @returns {boolean} `true` if the string starts with uppercase. */ function startsWithUpperCase(s) { return s[0] !== s[0].toLocaleLowerCase(); } /** * Checks whether or not a node is a constructor. * @param {ASTNode} node - A function node to check. * @returns {boolean} Wehether or not a node is a constructor. */ function isES5Constructor(node) { return node.id && startsWithUpperCase(node.id.name); } /** * Finds a function node from ancestors of a node. * @param {ASTNode} node - A start node to find. * @returns {Node|null} A found function node. */ function getUpperFunction(node) { for (var currentNode = node; currentNode; currentNode = currentNode.parent) { if (anyFunctionPattern.test(currentNode.type)) { return currentNode; } } return null; } /** * Checks whether a given node is a function node or not. * The following types are function nodes: * * - ArrowFunctionExpression * - FunctionDeclaration * - FunctionExpression * * @param {ASTNode|null} node - A node to check. * @returns {boolean} `true` if the node is a function node. */ function isFunction(node) { return Boolean(node && anyFunctionPattern.test(node.type)); } /** * Checks whether a given node is a loop node or not. * The following types are loop nodes: * * - DoWhileStatement * - ForInStatement * - ForOfStatement * - ForStatement * - WhileStatement * * @param {ASTNode|null} node - A node to check. * @returns {boolean} `true` if the node is a loop node. */ function isLoop(node) { return Boolean(node && anyLoopPattern.test(node.type)); } /** * Checks whether the given node is in a loop or not. * * @param {ASTNode} node - The node to check. * @returns {boolean} `true` if the node is in a loop. */ function isInLoop(node) { for (var currentNode = node; currentNode && !isFunction(currentNode); currentNode = currentNode.parent) { if (isLoop(currentNode)) { return true; } } return false; } /** * Checks whether or not a node is `null` or `undefined`. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is a `null` or `undefined`. * @public */ function isNullOrUndefined(node) { return module.exports.isNullLiteral(node) || node.type === "Identifier" && node.name === "undefined" || node.type === "UnaryExpression" && node.operator === "void"; } /** * Checks whether or not a node is callee. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is callee. */ function isCallee(node) { return node.parent.type === "CallExpression" && node.parent.callee === node; } /** * Checks whether or not a node is `Reflect.apply`. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is a `Reflect.apply`. */ function isReflectApply(node) { return node.type === "MemberExpression" && node.object.type === "Identifier" && node.object.name === "Reflect" && node.property.type === "Identifier" && node.property.name === "apply" && node.computed === false; } /** * Checks whether or not a node is `Array.from`. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is a `Array.from`. */ function isArrayFromMethod(node) { return node.type === "MemberExpression" && node.object.type === "Identifier" && arrayOrTypedArrayPattern.test(node.object.name) && node.property.type === "Identifier" && node.property.name === "from" && node.computed === false; } /** * Checks whether or not a node is a method which has `thisArg`. * @param {ASTNode} node - A node to check. * @returns {boolean} Whether or not the node is a method which has `thisArg`. */ function isMethodWhichHasThisArg(node) { for (var currentNode = node; currentNode.type === "MemberExpression" && !currentNode.computed; currentNode = currentNode.property) { if (currentNode.property.type === "Identifier") { return arrayMethodPattern.test(currentNode.property.name); } } return false; } /** * Creates the negate function of the given function. * @param {Function} f - The function to negate. * @returns {Function} Negated function. */ function negate(f) { return function (token) { return !f(token); }; } /** * Checks whether or not a node has a `@this` tag in its comments. * @param {ASTNode} node - A node to check. * @param {SourceCode} sourceCode - A SourceCode instance to get comments. * @returns {boolean} Whether or not the node has a `@this` tag in its comments. */ function hasJSDocThisTag(node, sourceCode) { var jsdocComment = sourceCode.getJSDocComment(node); if (jsdocComment && thisTagPattern.test(jsdocComment.value)) { return true; } // Checks `@this` in its leading comments for callbacks, // because callbacks don't have its JSDoc comment. // e.g. // sinon.test(/* @this sinon.Sandbox */function() { this.spy(); }); return sourceCode.getCommentsBefore(node).some(function (comment) { return thisTagPattern.test(comment.value); }); } /** * Determines if a node is surrounded by parentheses. * @param {SourceCode} sourceCode The ESLint source code object * @param {ASTNode} node The node to be checked. * @returns {boolean} True if the node is parenthesised. * @private */ function isParenthesised(sourceCode, node) { var previousToken = sourceCode.getTokenBefore(node), nextToken = sourceCode.getTokenAfter(node); return Boolean(previousToken && nextToken) && previousToken.value === "(" && previousToken.range[1] <= node.range[0] && nextToken.value === ")" && nextToken.range[0] >= node.range[1]; } /** * Checks if the given token is an arrow token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is an arrow token. */ function isArrowToken(token) { return token.value === "=>" && token.type === "Punctuator"; } /** * Checks if the given token is a comma token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a comma token. */ function isCommaToken(token) { return token.value === "," && token.type === "Punctuator"; } /** * Checks if the given token is a semicolon token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a semicolon token. */ function isSemicolonToken(token) { return token.value === ";" && token.type === "Punctuator"; } /** * Checks if the given token is a colon token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a colon token. */ function isColonToken(token) { return token.value === ":" && token.type === "Punctuator"; } /** * Checks if the given token is an opening parenthesis token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is an opening parenthesis token. */ function isOpeningParenToken(token) { return token.value === "(" && token.type === "Punctuator"; } /** * Checks if the given token is a closing parenthesis token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a closing parenthesis token. */ function isClosingParenToken(token) { return token.value === ")" && token.type === "Punctuator"; } /** * Checks if the given token is an opening square bracket token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is an opening square bracket token. */ function isOpeningBracketToken(token) { return token.value === "[" && token.type === "Punctuator"; } /** * Checks if the given token is a closing square bracket token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a closing square bracket token. */ function isClosingBracketToken(token) { return token.value === "]" && token.type === "Punctuator"; } /** * Checks if the given token is an opening brace token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is an opening brace token. */ function isOpeningBraceToken(token) { return token.value === "{" && token.type === "Punctuator"; } /** * Checks if the given token is a closing brace token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a closing brace token. */ function isClosingBraceToken(token) { return token.value === "}" && token.type === "Punctuator"; } /** * Checks if the given token is a comment token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a comment token. */ function isCommentToken(token) { return token.type === "Line" || token.type === "Block" || token.type === "Shebang"; } /** * Checks if the given token is a keyword token or not. * * @param {Token} token - The token to check. * @returns {boolean} `true` if the token is a keyword token. */ function isKeywordToken(token) { return token.type === "Keyword"; } /** * Gets the `(` token of the given function node. * * @param {ASTNode} node - The function node to get. * @param {SourceCode} sourceCode - The source code object to get tokens. * @returns {Token} `(` token. */ function getOpeningParenOfParams(node, sourceCode) { return node.id ? sourceCode.getTokenAfter(node.id, isOpeningParenToken) : sourceCode.getFirstToken(node, isOpeningParenToken); } /** * Creates a version of the LINEBREAK_MATCHER regex with the global flag. * Global regexes are mutable, so this needs to be a function instead of a constant. * @returns {RegExp} A global regular expression that matches line terminators */ function createGlobalLinebreakMatcher() { return new RegExp(LINEBREAK_MATCHER.source, "g"); } /** * Checks whether or not the tokens of two given nodes are same. * @param {ASTNode} left - A node 1 to compare. * @param {ASTNode} right - A node 2 to compare. * @param {SourceCode} sourceCode - The ESLint source code object. * @returns {boolean} the source code for the given node. */ function equalTokens(left, right, sourceCode) { var tokensL = sourceCode.getTokens(left); var tokensR = sourceCode.getTokens(right); if (tokensL.length !== tokensR.length) { return false; } for (var i = 0; i < tokensL.length; ++i) { if (tokensL[i].type !== tokensR[i].type || tokensL[i].value !== tokensR[i].value) { return false; } } return true; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = { COMMENTS_IGNORE_PATTERN: COMMENTS_IGNORE_PATTERN, LINEBREAKS: LINEBREAKS, LINEBREAK_MATCHER: LINEBREAK_MATCHER, SHEBANG_MATCHER: SHEBANG_MATCHER, STATEMENT_LIST_PARENTS: STATEMENT_LIST_PARENTS, /** * Determines whether two adjacent tokens are on the same line. * @param {Object} left - The left token object. * @param {Object} right - The right token object. * @returns {boolean} Whether or not the tokens are on the same line. * @public */ isTokenOnSameLine: function isTokenOnSameLine(left, right) { return left.loc.end.line === right.loc.start.line; }, isNullOrUndefined: isNullOrUndefined, isCallee: isCallee, isES5Constructor: isES5Constructor, getUpperFunction: getUpperFunction, isFunction: isFunction, isLoop: isLoop, isInLoop: isInLoop, isArrayFromMethod: isArrayFromMethod, isParenthesised: isParenthesised, createGlobalLinebreakMatcher: createGlobalLinebreakMatcher, equalTokens: equalTokens, isArrowToken: isArrowToken, isClosingBraceToken: isClosingBraceToken, isClosingBracketToken: isClosingBracketToken, isClosingParenToken: isClosingParenToken, isColonToken: isColonToken, isCommaToken: isCommaToken, isCommentToken: isCommentToken, isKeywordToken: isKeywordToken, isNotClosingBraceToken: negate(isClosingBraceToken), isNotClosingBracketToken: negate(isClosingBracketToken), isNotClosingParenToken: negate(isClosingParenToken), isNotColonToken: negate(isColonToken), isNotCommaToken: negate(isCommaToken), isNotOpeningBraceToken: negate(isOpeningBraceToken), isNotOpeningBracketToken: negate(isOpeningBracketToken), isNotOpeningParenToken: negate(isOpeningParenToken), isNotSemicolonToken: negate(isSemicolonToken), isOpeningBraceToken: isOpeningBraceToken, isOpeningBracketToken: isOpeningBracketToken, isOpeningParenToken: isOpeningParenToken, isSemicolonToken: isSemicolonToken, /** * Checks whether or not a given node is a string literal. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a string literal. */ isStringLiteral: function isStringLiteral(node) { return node.type === "Literal" && typeof node.value === "string" || node.type === "TemplateLiteral"; }, /** * Checks whether a given node is a breakable statement or not. * The node is breakable if the node is one of the following type: * * - DoWhileStatement * - ForInStatement * - ForOfStatement * - ForStatement * - SwitchStatement * - WhileStatement * * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is breakable. */ isBreakableStatement: function isBreakableStatement(node) { return breakableTypePattern.test(node.type); }, /** * Gets the label if the parent node of a given node is a LabeledStatement. * * @param {ASTNode} node - A node to get. * @returns {string|null} The label or `null`. */ getLabel: function getLabel(node) { if (node.parent.type === "LabeledStatement") { return node.parent.label.name; } return null; }, /** * Gets references which are non initializer and writable. * @param {Reference[]} references - An array of references. * @returns {Reference[]} An array of only references which are non initializer and writable. * @public */ getModifyingReferences: function getModifyingReferences(references) { return references.filter(isModifyingReference); }, /** * Validate that a string passed in is surrounded by the specified character * @param {string} val The text to check. * @param {string} character The character to see if it's surrounded by. * @returns {boolean} True if the text is surrounded by the character, false if not. * @private */ isSurroundedBy: function isSurroundedBy(val, character) { return val[0] === character && val[val.length - 1] === character; }, /** * Returns whether the provided node is an ESLint directive comment or not * @param {Line|Block} node The comment token to be checked * @returns {boolean} `true` if the node is an ESLint directive comment */ isDirectiveComment: function isDirectiveComment(node) { var comment = node.value.trim(); return node.type === "Line" && comment.indexOf("eslint-") === 0 || node.type === "Block" && (comment.indexOf("global ") === 0 || comment.indexOf("eslint ") === 0 || comment.indexOf("eslint-") === 0); }, /** * Gets the trailing statement of a given node. * * if (code) * consequent; * * When taking this `IfStatement`, returns `consequent;` statement. * * @param {ASTNode} A node to get. * @returns {ASTNode|null} The trailing statement's node. */ getTrailingStatement: esutils.ast.trailingStatement, /** * Finds the variable by a given name in a given scope and its upper scopes. * * @param {eslint-scope.Scope} initScope - A scope to start find. * @param {string} name - A variable name to find. * @returns {eslint-scope.Variable|null} A found variable or `null`. */ getVariableByName: function getVariableByName(initScope, name) { var scope = initScope; while (scope) { var variable = scope.set.get(name); if (variable) { return variable; } scope = scope.upper; } return null; }, /** * Checks whether or not a given function node is the default `this` binding. * * First, this checks the node: * * - The function name does not start with uppercase (it's a constructor). * - The function does not have a JSDoc comment that has a @this tag. * * Next, this checks the location of the node. * If the location is below, this judges `this` is valid. * * - The location is not on an object literal. * - The location is not assigned to a variable which starts with an uppercase letter. * - The location is not on an ES2015 class. * - Its `bind`/`call`/`apply` method is not called directly. * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given. * * @param {ASTNode} node - A function node to check. * @param {SourceCode} sourceCode - A SourceCode instance to get comments. * @returns {boolean} The function node is the default `this` binding. */ isDefaultThisBinding: function isDefaultThisBinding(node, sourceCode) { if (isES5Constructor(node) || hasJSDocThisTag(node, sourceCode)) { return false; } var isAnonymous = node.id === null; var currentNode = node; while (currentNode) { var parent = currentNode.parent; switch (parent.type) { /* * Looks up the destination. * e.g., obj.foo = nativeFoo || function foo() { ... }; */ case "LogicalExpression": case "ConditionalExpression": currentNode = parent; break; /* * If the upper function is IIFE, checks the destination of the return value. * e.g. * obj.foo = (function() { * // setup... * return function foo() { ... }; * })(); * obj.foo = (() => * function foo() { ... } * )(); */ case "ReturnStatement": { var func = getUpperFunction(parent); if (func === null || !isCallee(func)) { return true; } currentNode = func.parent; break; } case "ArrowFunctionExpression": if (currentNode !== parent.body || !isCallee(parent)) { return true; } currentNode = parent.parent; break; /* * e.g. * var obj = { foo() { ... } }; * var obj = { foo: function() { ... } }; * class A { constructor() { ... } } * class A { foo() { ... } } * class A { get foo() { ... } } * class A { set foo() { ... } } * class A { static foo() { ... } } */ case "Property": case "MethodDefinition": return parent.value !== currentNode; /* * e.g. * obj.foo = function foo() { ... }; * Foo = function() { ... }; * [obj.foo = function foo() { ... }] = a; * [Foo = function() { ... }] = a; */ case "AssignmentExpression": case "AssignmentPattern": if (parent.left.type === "MemberExpression") { return false; } if (isAnonymous && parent.left.type === "Identifier" && startsWithUpperCase(parent.left.name)) { return false; } return true; /* * e.g. * var Foo = function() { ... }; */ case "VariableDeclarator": return !(isAnonymous && parent.init === currentNode && parent.id.type === "Identifier" && startsWithUpperCase(parent.id.name)); /* * e.g. * var foo = function foo() { ... }.bind(obj); * (function foo() { ... }).call(obj); * (function foo() { ... }).apply(obj, []); */ case "MemberExpression": return parent.object !== currentNode || parent.property.type !== "Identifier" || !bindOrCallOrApplyPattern.test(parent.property.name) || !isCallee(parent) || parent.parent.arguments.length === 0 || isNullOrUndefined(parent.parent.arguments[0]); /* * e.g. * Reflect.apply(function() {}, obj, []); * Array.from([], function() {}, obj); * list.forEach(function() {}, obj); */ case "CallExpression": if (isReflectApply(parent.callee)) { return parent.arguments.length !== 3 || parent.arguments[0] !== currentNode || isNullOrUndefined(parent.arguments[1]); } if (isArrayFromMethod(parent.callee)) { return parent.arguments.length !== 3 || parent.arguments[1] !== currentNode || isNullOrUndefined(parent.arguments[2]); } if (isMethodWhichHasThisArg(parent.callee)) { return parent.arguments.length !== 2 || parent.arguments[0] !== currentNode || isNullOrUndefined(parent.arguments[1]); } return true; // Otherwise `this` is default. default: return true; } } /* istanbul ignore next */ return true; }, /** * Get the precedence level based on the node type * @param {ASTNode} node node to evaluate * @returns {int} precedence level * @private */ getPrecedence: function getPrecedence(node) { switch (node.type) { case "SequenceExpression": return 0; case "AssignmentExpression": case "ArrowFunctionExpression": case "YieldExpression": return 1; case "ConditionalExpression": return 3; case "LogicalExpression": switch (node.operator) { case "||": return 4; case "&&": return 5; // no default } /* falls through */ case "BinaryExpression": switch (node.operator) { case "|": return 6; case "^": return 7; case "&": return 8; case "==": case "!=": case "===": case "!==": return 9; case "<": case "<=": case ">": case ">=": case "in": case "instanceof": return 10; case "<<": case ">>": case ">>>": return 11; case "+": case "-": return 12; case "*": case "/": case "%": return 13; case "**": return 15; // no default } /* falls through */ case "UnaryExpression": case "AwaitExpression": return 16; case "UpdateExpression": return 17; case "CallExpression": return 18; case "NewExpression": return 19; default: return 20; } }, /** * Checks whether the given node is an empty block node or not. * * @param {ASTNode|null} node - The node to check. * @returns {boolean} `true` if the node is an empty block. */ isEmptyBlock: function isEmptyBlock(node) { return Boolean(node && node.type === "BlockStatement" && node.body.length === 0); }, /** * Checks whether the given node is an empty function node or not. * * @param {ASTNode|null} node - The node to check. * @returns {boolean} `true` if the node is an empty function. */ isEmptyFunction: function isEmptyFunction(node) { return isFunction(node) && module.exports.isEmptyBlock(node.body); }, /** * Gets the property name of a given node. * The node can be a MemberExpression, a Property, or a MethodDefinition. * * If the name is dynamic, this returns `null`. * * For examples: * * a.b // => "b" * a["b"] // => "b" * a['b'] // => "b" * a[`b`] // => "b" * a[100] // => "100" * a[b] // => null * a["a" + "b"] // => null * a[tag`b`] // => null * a[`${b}`] // => null * * let a = {b: 1} // => "b" * let a = {["b"]: 1} // => "b" * let a = {['b']: 1} // => "b" * let a = {[`b`]: 1} // => "b" * let a = {[100]: 1} // => "100" * let a = {[b]: 1} // => null * let a = {["a" + "b"]: 1} // => null * let a = {[tag`b`]: 1} // => null * let a = {[`${b}`]: 1} // => null * * @param {ASTNode} node - The node to get. * @returns {string|null} The property name if static. Otherwise, null. */ getStaticPropertyName: function getStaticPropertyName(node) { var prop = void 0; switch (node && node.type) { case "Property": case "MethodDefinition": prop = node.key; break; case "MemberExpression": prop = node.property; break; // no default } switch (prop && prop.type) { case "Literal": return String(prop.value); case "TemplateLiteral": if (prop.expressions.length === 0 && prop.quasis.length === 1) { return prop.quasis[0].value.cooked; } break; case "Identifier": if (!node.computed) { return prop.name; } break; // no default } return null; }, /** * Get directives from directive prologue of a Program or Function node. * @param {ASTNode} node - The node to check. * @returns {ASTNode[]} The directives found in the directive prologue. */ getDirectivePrologue: function getDirectivePrologue(node) { var directives = []; // Directive prologues only occur at the top of files or functions. if (node.type === "Program" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || /* * Do not check arrow functions with implicit return. * `() => "use strict";` returns the string `"use strict"`. */ node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement") { var statements = node.type === "Program" ? node.body : node.body.body; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = statements[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var statement = _step.value; if (statement.type === "ExpressionStatement" && statement.expression.type === "Literal") { directives.push(statement); } else { break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } return directives; }, /** * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added * after the node will be parsed as a decimal point, rather than a property-access dot. * @param {ASTNode} node - The node to check. * @returns {boolean} `true` if this node is a decimal integer. * @example * * 5 // true * 5. // false * 5.0 // false * 05 // false * 0x5 // false * 0b101 // false * 0o5 // false * 5e0 // false * '5' // false */ isDecimalInteger: function isDecimalInteger(node) { return node.type === "Literal" && typeof node.value === "number" && /^(0|[1-9]\d*)$/.test(node.raw); }, /** * Gets the name and kind of the given function node. * * - `function foo() {}` .................... `function 'foo'` * - `(function foo() {})` .................. `function 'foo'` * - `(function() {})` ...................... `function` * - `function* foo() {}` ................... `generator function 'foo'` * - `(function* foo() {})` ................. `generator function 'foo'` * - `(function*() {})` ..................... `generator function` * - `() => {}` ............................. `arrow function` * - `async () => {}` ....................... `async arrow function` * - `({ foo: function foo() {} })` ......... `method 'foo'` * - `({ foo: function() {} })` ............. `method 'foo'` * - `({ ['foo']: function() {} })` ......... `method 'foo'` * - `({ [foo]: function() {} })` ........... `method` * - `({ foo() {} })` ....................... `method 'foo'` * - `({ foo: function* foo() {} })` ........ `generator method 'foo'` * - `({ foo: function*() {} })` ............ `generator method 'foo'` * - `({ ['foo']: function*() {} })` ........ `generator method 'foo'` * - `({ [foo]: function*() {} })` .......... `generator method` * - `({ *foo() {} })` ...................... `generator method 'foo'` * - `({ foo: async function foo() {} })` ... `async method 'foo'` * - `({ foo: async function() {} })` ....... `async method 'foo'` * - `({ ['foo']: async function() {} })` ... `async method 'foo'` * - `({ [foo]: async function() {} })` ..... `async method` * - `({ async foo() {} })` ................. `async method 'foo'` * - `({ get foo() {} })` ................... `getter 'foo'` * - `({ set foo(a) {} })` .................. `setter 'foo'` * - `class A { constructor() {} }` ......... `constructor` * - `class A { foo() {} }` ................. `method 'foo'` * - `class A { *foo() {} }` ................ `generator method 'foo'` * - `class A { async foo() {} }` ........... `async method 'foo'` * - `class A { ['foo']() {} }` ............. `method 'foo'` * - `class A { *['foo']() {} }` ............ `generator method 'foo'` * - `class A { async ['foo']() {} }` ....... `async method 'foo'` * - `class A { [foo]() {} }` ............... `method` * - `class A { *[foo]() {} }` .............. `generator method` * - `class A { async [foo]() {} }` ......... `async method` * - `class A { get foo() {} }` ............. `getter 'foo'` * - `class A { set foo(a) {} }` ............ `setter 'foo'` * - `class A { static foo() {} }` .......... `static method 'foo'` * - `class A { static *foo() {} }` ......... `static generator method 'foo'` * - `class A { static async foo() {} }` .... `static async method 'foo'` * - `class A { static get foo() {} }` ...... `static getter 'foo'` * - `class A { static set foo(a) {} }` ..... `static setter 'foo'` * * @param {ASTNode} node - The function node to get. * @returns {string} The name and kind of the function node. */ getFunctionNameWithKind: function getFunctionNameWithKind(node) { var parent = node.parent; var tokens = []; if (parent.type === "MethodDefinition" && parent.static) { tokens.push("static"); } if (node.async) { tokens.push("async"); } if (node.generator) { tokens.push("generator"); } if (node.type === "ArrowFunctionExpression") { tokens.push("arrow", "function"); } else if (parent.type === "Property" || parent.type === "MethodDefinition") { if (parent.kind === "constructor") { return "constructor"; } if (parent.kind === "get") { tokens.push("getter"); } else if (parent.kind === "set") { tokens.push("setter"); } else { tokens.push("method"); } } else { tokens.push("function"); } if (node.id) { tokens.push("'" + node.id.name + "'"); } else { var name = module.exports.getStaticPropertyName(parent); if (name) { tokens.push("'" + name + "'"); } } return tokens.join(" "); }, /** * Gets the location of the given function node for reporting. * * - `function foo() {}` * ^^^^^^^^^^^^ * - `(function foo() {})` * ^^^^^^^^^^^^ * - `(function() {})` * ^^^^^^^^ * - `function* foo() {}` * ^^^^^^^^^^^^^ * - `(function* foo() {})` * ^^^^^^^^^^^^^ * - `(function*() {})` * ^^^^^^^^^ * - `() => {}` * ^^ * - `async () => {}` * ^^ * - `({ foo: function foo() {} })` * ^^^^^^^^^^^^^^^^^ * - `({ foo: function() {} })` * ^^^^^^^^^^^^^ * - `({ ['foo']: function() {} })` * ^^^^^^^^^^^^^^^^^ * - `({ [foo]: function() {} })` * ^^^^^^^^^^^^^^^ * - `({ foo() {} })` * ^^^ * - `({ foo: function* foo() {} })` * ^^^^^^^^^^^^^^^^^^ * - `({ foo: function*() {} })` * ^^^^^^^^^^^^^^ * - `({ ['foo']: function*() {} })` * ^^^^^^^^^^^^^^^^^^ * - `({ [foo]: function*() {} })` * ^^^^^^^^^^^^^^^^ * - `({ *foo() {} })` * ^^^^ * - `({ foo: async function foo() {} })` * ^^^^^^^^^^^^^^^^^^^^^^^ * - `({ foo: async function() {} })` * ^^^^^^^^^^^^^^^^^^^ * - `({ ['foo']: async function() {} })` * ^^^^^^^^^^^^^^^^^^^^^^^ * - `({ [foo]: async function() {} })` * ^^^^^^^^^^^^^^^^^^^^^ * - `({ async foo() {} })` * ^^^^^^^^^ * - `({ get foo() {} })` * ^^^^^^^ * - `({ set foo(a) {} })` * ^^^^^^^ * - `class A { constructor() {} }` * ^^^^^^^^^^^ * - `class A { foo() {} }` * ^^^ * - `class A { *foo() {} }` * ^^^^ * - `class A { async foo() {} }` * ^^^^^^^^^ * - `class A { ['foo']() {} }` * ^^^^^^^ * - `class A { *['foo']() {} }` * ^^^^^^^^ * - `class A { async ['foo']() {} }` * ^^^^^^^^^^^^^ * - `class A { [foo]() {} }` * ^^^^^ * - `class A { *[foo]() {} }` * ^^^^^^ * - `class A { async [foo]() {} }` * ^^^^^^^^^^^ * - `class A { get foo() {} }` * ^^^^^^^ * - `class A { set foo(a) {} }` * ^^^^^^^ * - `class A { static foo() {} }` * ^^^^^^^^^^ * - `class A { static *foo() {} }` * ^^^^^^^^^^^ * - `class A { static async foo() {} }` * ^^^^^^^^^^^^^^^^ * - `class A { static get foo() {} }` * ^^^^^^^^^^^^^^ * - `class A { static set foo(a) {} }` * ^^^^^^^^^^^^^^ * * @param {ASTNode} node - The function node to get. * @param {SourceCode} sourceCode - The source code object to get tokens. * @returns {string} The location of the function node for reporting. */ getFunctionHeadLoc: function getFunctionHeadLoc(node, sourceCode) { var parent = node.parent; var start = null; var end = null; if (node.type === "ArrowFunctionExpression") { var arrowToken = sourceCode.getTokenBefore(node.body, isArrowToken); start = arrowToken.loc.start; end = arrowToken.loc.end; } else if (parent.type === "Property" || parent.type === "MethodDefinition") { start = parent.loc.start; end = getOpeningParenOfParams(node, sourceCode).loc.start; } else { start = node.loc.start; end = getOpeningParenOfParams(node, sourceCode).loc.start; } return { start: Object.assign({}, start), end: Object.assign({}, end) }; }, /** * Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses * surrounding the node. * @param {SourceCode} sourceCode The source code object * @param {ASTNode} node An expression node * @returns {string} The text representing the node, with all surrounding parentheses included */ getParenthesisedText: function getParenthesisedText(sourceCode, node) { var leftToken = sourceCode.getFirstToken(node); var rightToken = sourceCode.getLastToken(node); while (sourceCode.getTokenBefore(leftToken) && sourceCode.getTokenBefore(leftToken).type === "Punctuator" && sourceCode.getTokenBefore(leftToken).value === "(" && sourceCode.getTokenAfter(rightToken) && sourceCode.getTokenAfter(rightToken).type === "Punctuator" && sourceCode.getTokenAfter(rightToken).value === ")") { leftToken = sourceCode.getTokenBefore(leftToken); rightToken = sourceCode.getTokenAfter(rightToken); } return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]); }, /* * Determine if a node has a possiblity to be an Error object * @param {ASTNode} node ASTNode to check * @returns {boolean} True if there is a chance it contains an Error obj */ couldBeError: function couldBeError(node) { switch (node.type) { case "Identifier": case "CallExpression": case "NewExpression": case "MemberExpression": case "TaggedTemplateExpression": case "YieldExpression": case "AwaitExpression": return true; // possibly an error object. case "AssignmentExpression": return module.exports.couldBeError(node.right); case "SequenceExpression": { var exprs = node.expressions; return exprs.length !== 0 && module.exports.couldBeError(exprs[exprs.length - 1]); } case "LogicalExpression": return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right); case "ConditionalExpression": return module.exports.couldBeError(node.consequent) || module.exports.couldBeError(node.alternate); default: return false; } }, /** * Determines whether the given node is a `null` literal. * @param {ASTNode} node The node to check * @returns {boolean} `true` if the node is a `null` literal */ isNullLiteral: function isNullLiteral(node) { /* * Checking `node.value === null` does not guarantee that a literal is a null literal. * When parsing values that cannot be represented in the current environment (e.g. unicode * regexes in Node 4), `node.value` is set to `null` because it wouldn't be possible to * set `node.value` to a unicode regex. To make sure a literal is actually `null`, check * `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020 */ return node.type === "Literal" && node.value === null && !node.regex; }, /** * Determines whether two tokens can safely be placed next to each other without merging into a single token * @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used. * @param {Token|string} rightValue The right token. If this is a string, it will be tokenized and the first token will be used. * @returns {boolean} If the tokens cannot be safely placed next to each other, returns `false`. If the tokens can be placed * next to each other, behavior is undefined (although it should return `true` in most cases). */ canTokensBeAdjacent: function canTokensBeAdjacent(leftValue, rightValue) { var leftToken = void 0; if (typeof leftValue === "string") { var leftTokens = espree.tokenize(leftValue, { ecmaVersion: 2015 }); leftToken = leftTokens[leftTokens.length - 1]; } else { leftToken = leftValue; } var rightToken = typeof rightValue === "string" ? espree.tokenize(rightValue, { ecmaVersion: 2015 })[0] : rightValue; if (leftToken.type === "Punctuator" || rightToken.type === "Punctuator") { if (leftToken.type === "Punctuator" && rightToken.type === "Punctuator") { var PLUS_TOKENS = new Set(["+", "++"]); var MINUS_TOKENS = new Set(["-", "--"]); return !(PLUS_TOKENS.has(leftToken.value) && PLUS_TOKENS.has(rightToken.value) || MINUS_TOKENS.has(leftToken.value) && MINUS_TOKENS.has(rightToken.value)); } return true; } if (leftToken.type === "String" || rightToken.type === "String" || leftToken.type === "Template" || rightToken.type === "Template") { return true; } if (leftToken.type !== "Numeric" && rightToken.type === "Numeric" && rightToken.value.startsWith(".")) { return true; } return false; } }; },{"espree":"espree","esutils":80}],406:[function(require,module,exports){ /** * @fileoverview Config Comment Parser * @author Nicholas C. Zakas */ /* eslint-disable class-methods-use-this*/ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var levn = require("levn"), ConfigOps = require("../config/config-ops"); var debug = require("debug")("eslint:config-comment-parser"); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * Object to parse ESLint configuration comments inside JavaScript files. * @name ConfigCommentParser */ module.exports = function () { function ConfigCommentParser() { _classCallCheck(this, ConfigCommentParser); } _createClass(ConfigCommentParser, [{ key: "parseBooleanConfig", /** * Parses a list of "name:boolean_value" or/and "name" options divided by comma or * whitespace. Used for "global" and "exported" comments. * @param {string} string The string to parse. * @param {Comment} comment The comment node which has the string. * @returns {Object} Result map object of names and boolean values */ value: function parseBooleanConfig(string, comment) { debug("Parsing Boolean config"); var items = {}; // Collapse whitespace around `:` and `,` to make parsing easier var trimmedString = string.replace(/\s*([:,])\s*/g, "$1"); trimmedString.split(/\s|,+/).forEach(function (name) { if (!name) { return; } // value defaults to "false" (if not provided), e.g: "foo" => ["foo", "false"] var _name$split = name.split(":"), _name$split2 = _slicedToArray(_name$split, 2), key = _name$split2[0], _name$split2$ = _name$split2[1], value = _name$split2$ === undefined ? "false" : _name$split2$; items[key] = { value: value === "true", comment: comment }; }); return items; } /** * Parses a JSON-like config. * @param {string} string The string to parse. * @param {Object} location Start line and column of comments for potential error message. * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object */ }, { key: "parseJsonConfig", value: function parseJsonConfig(string, location) { debug("Parsing JSON config"); var items = {}; // Parses a JSON-like comment by the same way as parsing CLI option. try { items = levn.parse("Object", string) || {}; // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`. // Also, commaless notations have invalid severity: // "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"} // Should ignore that case as well. if (ConfigOps.isEverySeverityValid(items)) { return { success: true, config: items }; } } catch (ex) { debug("Levn parsing failed; falling back to manual parsing."); // ignore to parse the string by a fallback. } /* * Optionator cannot parse commaless notations. * But we are supporting that. So this is a fallback for that. */ items = {}; var normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,"); try { items = JSON.parse("{" + normalizedString + "}"); } catch (ex) { debug("Manual parsing failed."); return { success: false, error: { ruleId: null, fatal: true, severity: 2, message: "Failed to parse JSON from '" + normalizedString + "': " + ex.message, line: location.start.line, column: location.start.column + 1 } }; } return { success: true, config: items }; } /** * Parses a config of values separated by comma. * @param {string} string The string to parse. * @returns {Object} Result map of values and true values */ }, { key: "parseListConfig", value: function parseListConfig(string) { debug("Parsing list config"); var items = {}; // Collapse whitespace around commas string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(function (name) { var trimmedName = name.trim(); if (trimmedName) { items[trimmedName] = true; } }); return items; } }]); return ConfigCommentParser; }(); },{"../config/config-ops":119,"debug":53,"levn":90}],407:[function(require,module,exports){ /** * @fileoverview Helper class to aid in constructing fix commands. * @author Alan Pierce */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var astUtils = require("../util/ast-utils"); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * A helper class to combine fix options into a fix command. Currently, it * exposes some "retain" methods that extend the range of the text being * replaced so that other fixes won't touch that region in the same pass. */ var FixTracker = function () { /** * Create a new FixTracker. * * @param {ruleFixer} fixer A ruleFixer instance. * @param {SourceCode} sourceCode A SourceCode object for the current code. */ function FixTracker(fixer, sourceCode) { _classCallCheck(this, FixTracker); this.fixer = fixer; this.sourceCode = sourceCode; this.retainedRange = null; } /** * Mark the given range as "retained", meaning that other fixes may not * may not modify this region in the same pass. * * @param {int[]} range The range to retain. * @returns {FixTracker} The same RuleFixer, for chained calls. */ _createClass(FixTracker, [{ key: "retainRange", value: function retainRange(range) { this.retainedRange = range; return this; } /** * Given a node, find the function containing it (or the entire program) and * mark it as retained, meaning that other fixes may not modify it in this * pass. This is useful for avoiding conflicts in fixes that modify control * flow. * * @param {ASTNode} node The node to use as a starting point. * @returns {FixTracker} The same RuleFixer, for chained calls. */ }, { key: "retainEnclosingFunction", value: function retainEnclosingFunction(node) { var functionNode = astUtils.getUpperFunction(node); return this.retainRange(functionNode ? functionNode.range : this.sourceCode.ast.range); } /** * Given a node or token, find the token before and afterward, and mark that * range as retained, meaning that other fixes may not modify it in this * pass. This is useful for avoiding conflicts in fixes that make a small * change to the code where the AST should not be changed. * * @param {ASTNode|Token} nodeOrToken The node or token to use as a starting * point. The token to the left and right are use in the range. * @returns {FixTracker} The same RuleFixer, for chained calls. */ }, { key: "retainSurroundingTokens", value: function retainSurroundingTokens(nodeOrToken) { var tokenBefore = this.sourceCode.getTokenBefore(nodeOrToken) || nodeOrToken; var tokenAfter = this.sourceCode.getTokenAfter(nodeOrToken) || nodeOrToken; return this.retainRange([tokenBefore.range[0], tokenAfter.range[1]]); } /** * Create a fix command that replaces the given range with the given text, * accounting for any retained ranges. * * @param {int[]} range The range to remove in the fix. * @param {string} text The text to insert in place of the range. * @returns {Object} The fix command. */ }, { key: "replaceTextRange", value: function replaceTextRange(range, text) { var actualRange = void 0; if (this.retainedRange) { actualRange = [Math.min(this.retainedRange[0], range[0]), Math.max(this.retainedRange[1], range[1])]; } else { actualRange = range; } return this.fixer.replaceTextRange(actualRange, this.sourceCode.text.slice(actualRange[0], range[0]) + text + this.sourceCode.text.slice(range[1], actualRange[1])); } /** * Create a fix command that removes the given node or token, accounting for * any retained ranges. * * @param {ASTNode|Token} nodeOrToken The node or token to remove. * @returns {Object} The fix command. */ }, { key: "remove", value: function remove(nodeOrToken) { return this.replaceTextRange(nodeOrToken.range, ""); } }]); return FixTracker; }(); module.exports = FixTracker; },{"../util/ast-utils":405}],408:[function(require,module,exports){ /** * @fileoverview Interpolate keys from an object into a string with {{ }} markers. * @author Jed Fox */ "use strict"; //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = function (text, data) { if (!data) { return text; } // Substitution content for any {{ }} markers. return text.replace(/\{\{([^{}]+?)\}\}/g, function (fullMatch, termWithWhitespace) { var term = termWithWhitespace.trim(); if (term in data) { return data[term]; } // Preserve old behavior: If parameter name not provided, don't replace it. return fullMatch; }); }; },{}],409:[function(require,module,exports){ /** * @fileoverview A shared list of ES3 keywords. * @author Josh Perez */ "use strict"; module.exports = ["abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with"]; },{}],410:[function(require,module,exports){ /** * @fileoverview The event generator for AST nodes. * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var esquery = require("esquery"); var lodash = require("lodash"); //------------------------------------------------------------------------------ // Typedefs //------------------------------------------------------------------------------ /** * An object describing an AST selector * @typedef {Object} ASTSelector * @property {string} rawSelector The string that was parsed into this selector * @property {boolean} isExit `true` if this should be emitted when exiting the node rather than when entering * @property {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector * @property {string[]|null} listenerTypes A list of node types that could possibly cause the selector to match, * or `null` if all node types could cause a match * @property {number} attributeCount The total number of classes, pseudo-classes, and attribute queries in this selector * @property {number} identifierCount The total number of identifier queries in this selector */ //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets the possible types of a selector * @param {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector * @returns {string[]|null} The node types that could possibly trigger this selector, or `null` if all node types could trigger it */ function getPossibleTypes(parsedSelector) { switch (parsedSelector.type) { case "identifier": return [parsedSelector.value]; case "matches": { var typesForComponents = parsedSelector.selectors.map(getPossibleTypes); if (typesForComponents.every(Boolean)) { return lodash.union.apply(lodash, _toConsumableArray(typesForComponents)); } return null; } case "compound": { var _typesForComponents = parsedSelector.selectors.map(getPossibleTypes).filter(function (typesForComponent) { return typesForComponent; }); // If all of the components could match any type, then the compound could also match any type. if (!_typesForComponents.length) { return null; } /* * If at least one of the components could only match a particular type, the compound could only match * the intersection of those types. */ return lodash.intersection.apply(lodash, _toConsumableArray(_typesForComponents)); } case "child": case "descendant": case "sibling": case "adjacent": return getPossibleTypes(parsedSelector.right); default: return null; } } /** * Counts the number of class, pseudo-class, and attribute queries in this selector * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior * @returns {number} The number of class, pseudo-class, and attribute queries in this selector */ function countClassAttributes(parsedSelector) { switch (parsedSelector.type) { case "child": case "descendant": case "sibling": case "adjacent": return countClassAttributes(parsedSelector.left) + countClassAttributes(parsedSelector.right); case "compound": case "not": case "matches": return parsedSelector.selectors.reduce(function (sum, childSelector) { return sum + countClassAttributes(childSelector); }, 0); case "attribute": case "field": case "nth-child": case "nth-last-child": return 1; default: return 0; } } /** * Counts the number of identifier queries in this selector * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior * @returns {number} The number of identifier queries */ function countIdentifiers(parsedSelector) { switch (parsedSelector.type) { case "child": case "descendant": case "sibling": case "adjacent": return countIdentifiers(parsedSelector.left) + countIdentifiers(parsedSelector.right); case "compound": case "not": case "matches": return parsedSelector.selectors.reduce(function (sum, childSelector) { return sum + countIdentifiers(childSelector); }, 0); case "identifier": return 1; default: return 0; } } /** * Compares the specificity of two selector objects, with CSS-like rules. * @param {ASTSelector} selectorA An AST selector descriptor * @param {ASTSelector} selectorB Another AST selector descriptor * @returns {number} * a value less than 0 if selectorA is less specific than selectorB * a value greater than 0 if selectorA is more specific than selectorB * a value less than 0 if selectorA and selectorB have the same specificity, and selectorA <= selectorB alphabetically * a value greater than 0 if selectorA and selectorB have the same specificity, and selectorA > selectorB alphabetically */ function compareSpecificity(selectorA, selectorB) { return selectorA.attributeCount - selectorB.attributeCount || selectorA.identifierCount - selectorB.identifierCount || (selectorA.rawSelector <= selectorB.rawSelector ? -1 : 1); } /** * Parses a raw selector string, and throws a useful error if parsing fails. * @param {string} rawSelector A raw AST selector * @returns {Object} An object (from esquery) describing the matching behavior of this selector * @throws {Error} An error if the selector is invalid */ function tryParseSelector(rawSelector) { try { return esquery.parse(rawSelector.replace(/:exit$/, "")); } catch (err) { if (typeof err.offset === "number") { throw new SyntaxError("Syntax error in selector \"" + rawSelector + "\" at position " + err.offset + ": " + err.message); } throw err; } } /** * Parses a raw selector string, and returns the parsed selector along with specificity and type information. * @param {string} rawSelector A raw AST selector * @returns {ASTSelector} A selector descriptor */ var parseSelector = lodash.memoize(function (rawSelector) { var parsedSelector = tryParseSelector(rawSelector); return { rawSelector: rawSelector, isExit: rawSelector.endsWith(":exit"), parsedSelector: parsedSelector, listenerTypes: getPossibleTypes(parsedSelector), attributeCount: countClassAttributes(parsedSelector), identifierCount: countIdentifiers(parsedSelector) }; }); //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * The event generator for AST nodes. * This implements below interface. * * ```ts * interface EventGenerator { * emitter: SafeEmitter; * enterNode(node: ASTNode): void; * leaveNode(node: ASTNode): void; * } * ``` */ var NodeEventGenerator = function () { /** * @param {SafeEmitter} emitter * An SafeEmitter which is the destination of events. This emitter must already * have registered listeners for all of the events that it needs to listen for. * (See lib/util/safe-emitter.js for more details on `SafeEmitter`.) * @returns {NodeEventGenerator} new instance */ function NodeEventGenerator(emitter) { var _this = this; _classCallCheck(this, NodeEventGenerator); this.emitter = emitter; this.currentAncestry = []; this.enterSelectorsByNodeType = new Map(); this.exitSelectorsByNodeType = new Map(); this.anyTypeEnterSelectors = []; this.anyTypeExitSelectors = []; emitter.eventNames().forEach(function (rawSelector) { var selector = parseSelector(rawSelector); if (selector.listenerTypes) { selector.listenerTypes.forEach(function (nodeType) { var typeMap = selector.isExit ? _this.exitSelectorsByNodeType : _this.enterSelectorsByNodeType; if (!typeMap.has(nodeType)) { typeMap.set(nodeType, []); } typeMap.get(nodeType).push(selector); }); } else { (selector.isExit ? _this.anyTypeExitSelectors : _this.anyTypeEnterSelectors).push(selector); } }); this.anyTypeEnterSelectors.sort(compareSpecificity); this.anyTypeExitSelectors.sort(compareSpecificity); this.enterSelectorsByNodeType.forEach(function (selectorList) { return selectorList.sort(compareSpecificity); }); this.exitSelectorsByNodeType.forEach(function (selectorList) { return selectorList.sort(compareSpecificity); }); } /** * Checks a selector against a node, and emits it if it matches * @param {ASTNode} node The node to check * @param {ASTSelector} selector An AST selector descriptor * @returns {void} */ _createClass(NodeEventGenerator, [{ key: "applySelector", value: function applySelector(node, selector) { if (esquery.matches(node, selector.parsedSelector, this.currentAncestry)) { this.emitter.emit(selector.rawSelector, node); } } /** * Applies all appropriate selectors to a node, in specificity order * @param {ASTNode} node The node to check * @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited * @returns {void} */ }, { key: "applySelectors", value: function applySelectors(node, isExit) { var selectorsByNodeType = (isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType).get(node.type) || []; var anyTypeSelectors = isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors; /* * selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor. * Iterate through each of them, applying selectors in the right order. */ var selectorsByTypeIndex = 0; var anyTypeSelectorsIndex = 0; while (selectorsByTypeIndex < selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length) { if (selectorsByTypeIndex >= selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length && compareSpecificity(anyTypeSelectors[anyTypeSelectorsIndex], selectorsByNodeType[selectorsByTypeIndex]) < 0) { this.applySelector(node, anyTypeSelectors[anyTypeSelectorsIndex++]); } else { this.applySelector(node, selectorsByNodeType[selectorsByTypeIndex++]); } } } /** * Emits an event of entering AST node. * @param {ASTNode} node - A node which was entered. * @returns {void} */ }, { key: "enterNode", value: function enterNode(node) { if (node.parent) { this.currentAncestry.unshift(node.parent); } this.applySelectors(node, false); } /** * Emits an event of leaving AST node. * @param {ASTNode} node - A node which was left. * @returns {void} */ }, { key: "leaveNode", value: function leaveNode(node) { this.applySelectors(node, true); this.currentAncestry.shift(); } }]); return NodeEventGenerator; }(); module.exports = NodeEventGenerator; },{"esquery":71,"lodash":92}],411:[function(require,module,exports){ /** * @fileoverview Pattern for detecting any letter (even letters outside of ASCII). * NOTE: This file was generated using this script in JSCS based on the Unicode 7.0.0 standard: https://github.com/jscs-dev/node-jscs/blob/f5ed14427deb7e7aac84f3056a5aab2d9f3e563e/publish/helpers/generate-patterns.js * Do not edit this file by hand-- please use https://github.com/mathiasbynens/regenerate to regenerate the regular expression exported from this file. * @author Kevin Partington * @license MIT License (from JSCS). See below. */ /* * The MIT License (MIT) * * Copyright 2013-2016 Dulin Marat and other contributors * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ "use strict"; module.exports = /[A-Za-z\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-\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\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-\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\u16F1-\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\u2183\u2184\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\u3006\u3031-\u3035\u303B\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-\uA6E5\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\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\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]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\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]|\uD87E[\uDC00-\uDE1D]/; },{}],412:[function(require,module,exports){ /** * @fileoverview A helper that translates context.report() calls from the rule API into generic problem objects * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var assert = require("assert"); var ruleFixer = require("./rule-fixer"); var interpolate = require("./interpolate"); //------------------------------------------------------------------------------ // Typedefs //------------------------------------------------------------------------------ /** * An error message description * @typedef {Object} MessageDescriptor * @property {ASTNode} [node] The reported node * @property {Location} loc The location of the problem. * @property {string} message The problem message. * @property {Object} [data] Optional data to use to fill in placeholders in the * message. * @property {Function} [fix] The function to call that creates a fix command. */ /** * Information about the report * @typedef {Object} ReportInfo * @property {string} ruleId * @property {(0|1|2)} severity * @property {(string|undefined)} message * @property {(string|undefined)} messageId * @property {number} line * @property {number} column * @property {(number|undefined)} endLine * @property {(number|undefined)} endColumn * @property {(string|null)} nodeType * @property {string} source * @property {({text: string, range: (number[]|null)}|null)} fix */ //------------------------------------------------------------------------------ // Module Definition //------------------------------------------------------------------------------ /** * Translates a multi-argument context.report() call into a single object argument call * @param {...*} args A list of arguments passed to `context.report` * @returns {MessageDescriptor} A normalized object containing report information */ function normalizeMultiArgReportCall() { // If there is one argument, it is considered to be a new-style call already. if (arguments.length === 1) { // Shallow clone the object to avoid surprises if reusing the descriptor return Object.assign({}, arguments.length <= 0 ? undefined : arguments[0]); } // If the second argument is a string, the arguments are interpreted as [node, message, data, fix]. if (typeof (arguments.length <= 1 ? undefined : arguments[1]) === "string") { return { node: arguments.length <= 0 ? undefined : arguments[0], message: arguments.length <= 1 ? undefined : arguments[1], data: arguments.length <= 2 ? undefined : arguments[2], fix: arguments.length <= 3 ? undefined : arguments[3] }; } // Otherwise, the arguments are interpreted as [node, loc, message, data, fix]. return { node: arguments.length <= 0 ? undefined : arguments[0], loc: arguments.length <= 1 ? undefined : arguments[1], message: arguments.length <= 2 ? undefined : arguments[2], data: arguments.length <= 3 ? undefined : arguments[3], fix: arguments.length <= 4 ? undefined : arguments[4] }; } /** * Asserts that either a loc or a node was provided, and the node is valid if it was provided. * @param {MessageDescriptor} descriptor A descriptor to validate * @returns {void} * @throws AssertionError if neither a node nor a loc was provided, or if the node is not an object */ function assertValidNodeInfo(descriptor) { if (descriptor.node) { assert(_typeof(descriptor.node) === "object", "Node must be an object"); } else { assert(descriptor.loc, "Node must be provided when reporting error if location is not provided"); } } /** * Normalizes a MessageDescriptor to always have a `loc` with `start` and `end` properties * @param {MessageDescriptor} descriptor A descriptor for the report from a rule. * @returns {{start: Location, end: (Location|null)}} An updated location that infers the `start` and `end` properties * from the `node` of the original descriptor, or infers the `start` from the `loc` of the original descriptor. */ function normalizeReportLoc(descriptor) { if (descriptor.loc) { if (descriptor.loc.start) { return descriptor.loc; } return { start: descriptor.loc, end: null }; } return descriptor.node.loc; } /** * Compares items in a fixes array by range. * @param {Fix} a The first message. * @param {Fix} b The second message. * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. * @private */ function compareFixesByRange(a, b) { return a.range[0] - b.range[0] || a.range[1] - b.range[1]; } /** * Merges the given fixes array into one. * @param {Fix[]} fixes The fixes to merge. * @param {SourceCode} sourceCode The source code object to get the text between fixes. * @returns {{text: string, range: number[]}} The merged fixes */ function mergeFixes(fixes, sourceCode) { if (fixes.length === 0) { return null; } if (fixes.length === 1) { return fixes[0]; } fixes.sort(compareFixesByRange); var originalText = sourceCode.text; var start = fixes[0].range[0]; var end = fixes[fixes.length - 1].range[1]; var text = ""; var lastPos = Number.MIN_SAFE_INTEGER; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = fixes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var fix = _step.value; assert(fix.range[0] >= lastPos, "Fix objects must not be overlapped in a report."); if (fix.range[0] >= 0) { text += originalText.slice(Math.max(0, start, lastPos), fix.range[0]); } text += fix.text; lastPos = fix.range[1]; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } text += originalText.slice(Math.max(0, start, lastPos), end); return { range: [start, end], text: text }; } /** * Gets one fix object from the given descriptor. * If the descriptor retrieves multiple fixes, this merges those to one. * @param {MessageDescriptor} descriptor The report descriptor. * @param {SourceCode} sourceCode The source code object to get text between fixes. * @returns {({text: string, range: number[]}|null)} The fix for the descriptor */ function normalizeFixes(descriptor, sourceCode) { if (typeof descriptor.fix !== "function") { return null; } // @type {null | Fix | Fix[] | IterableIterator} var fix = descriptor.fix(ruleFixer); // Merge to one. if (fix && Symbol.iterator in fix) { return mergeFixes(Array.from(fix), sourceCode); } return fix; } /** * Creates information about the report from a descriptor * @param {Object} options Information about the problem * @param {string} options.ruleId Rule ID * @param {(0|1|2)} options.severity Rule severity * @param {(ASTNode|null)} options.node Node * @param {string} options.message Error message * @param {string} [options.messageId] The error message ID. * @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location * @param {{text: string, range: (number[]|null)}} options.fix The fix object * @returns {function(...args): ReportInfo} Function that returns information about the report */ function createProblem(options) { var problem = { ruleId: options.ruleId, severity: options.severity, message: options.message, line: options.loc.start.line, column: options.loc.start.column + 1, nodeType: options.node && options.node.type || null }; /* * If this isn’t in the conditional, some of the tests fail * because `messageId` is present in the problem object */ if (options.messageId) { problem.messageId = options.messageId; } if (options.loc.end) { problem.endLine = options.loc.end.line; problem.endColumn = options.loc.end.column + 1; } if (options.fix) { problem.fix = options.fix; } return problem; } /** * Returns a function that converts the arguments of a `context.report` call from a rule into a reported * problem for the Node.js API. * @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object}} metadata Metadata for the reported problem * @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted * @returns {function(...args): ReportInfo} Function that returns information about the report */ module.exports = function createReportTranslator(metadata) { /* * `createReportTranslator` gets called once per enabled rule per file. It needs to be very performant. * The report translator itself (i.e. the function that `createReportTranslator` returns) gets * called every time a rule reports a problem, which happens much less frequently (usually, the vast * majority of rules don't report any problems for a given file). */ return function () { var descriptor = normalizeMultiArgReportCall.apply(undefined, arguments); assertValidNodeInfo(descriptor); var computedMessage = void 0; if (descriptor.messageId) { if (!metadata.messageIds) { throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata."); } var id = descriptor.messageId; var messages = metadata.messageIds; if (descriptor.message) { throw new TypeError("context.report() called with a message and a messageId. Please only pass one."); } if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) { throw new TypeError("context.report() called with a messageId of '" + id + "' which is not present in the 'messages' config: " + JSON.stringify(messages, null, 2)); } computedMessage = messages[id]; } else if (descriptor.message) { computedMessage = descriptor.message; } else { throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem."); } return createProblem({ ruleId: metadata.ruleId, severity: metadata.severity, node: descriptor.node, message: interpolate(computedMessage, descriptor.data), messageId: descriptor.messageId, loc: normalizeReportLoc(descriptor), fix: normalizeFixes(descriptor, metadata.sourceCode) }); }; }; },{"./interpolate":408,"./rule-fixer":413,"assert":46}],413:[function(require,module,exports){ /** * @fileoverview An object that creates fix commands for rules. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ // none! //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Creates a fix command that inserts text at the specified index in the source text. * @param {int} index The 0-based index at which to insert the new text. * @param {string} text The text to insert. * @returns {Object} The fix command. * @private */ function insertTextAt(index, text) { return { range: [index, index], text: text }; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * Creates code fixing commands for rules. */ var ruleFixer = Object.freeze({ /** * Creates a fix command that inserts text after the given node or token. * The fix is not applied until applyFixes() is called. * @param {ASTNode|Token} nodeOrToken The node or token to insert after. * @param {string} text The text to insert. * @returns {Object} The fix command. */ insertTextAfter: function insertTextAfter(nodeOrToken, text) { return this.insertTextAfterRange(nodeOrToken.range, text); }, /** * Creates a fix command that inserts text after the specified range in the source text. * The fix is not applied until applyFixes() is called. * @param {int[]} range The range to replace, first item is start of range, second * is end of range. * @param {string} text The text to insert. * @returns {Object} The fix command. */ insertTextAfterRange: function insertTextAfterRange(range, text) { return insertTextAt(range[1], text); }, /** * Creates a fix command that inserts text before the given node or token. * The fix is not applied until applyFixes() is called. * @param {ASTNode|Token} nodeOrToken The node or token to insert before. * @param {string} text The text to insert. * @returns {Object} The fix command. */ insertTextBefore: function insertTextBefore(nodeOrToken, text) { return this.insertTextBeforeRange(nodeOrToken.range, text); }, /** * Creates a fix command that inserts text before the specified range in the source text. * The fix is not applied until applyFixes() is called. * @param {int[]} range The range to replace, first item is start of range, second * is end of range. * @param {string} text The text to insert. * @returns {Object} The fix command. */ insertTextBeforeRange: function insertTextBeforeRange(range, text) { return insertTextAt(range[0], text); }, /** * Creates a fix command that replaces text at the node or token. * The fix is not applied until applyFixes() is called. * @param {ASTNode|Token} nodeOrToken The node or token to remove. * @param {string} text The text to insert. * @returns {Object} The fix command. */ replaceText: function replaceText(nodeOrToken, text) { return this.replaceTextRange(nodeOrToken.range, text); }, /** * Creates a fix command that replaces text at the specified range in the source text. * The fix is not applied until applyFixes() is called. * @param {int[]} range The range to replace, first item is start of range, second * is end of range. * @param {string} text The text to insert. * @returns {Object} The fix command. */ replaceTextRange: function replaceTextRange(range, text) { return { range: range, text: text }; }, /** * Creates a fix command that removes the node or token from the source. * The fix is not applied until applyFixes() is called. * @param {ASTNode|Token} nodeOrToken The node or token to remove. * @returns {Object} The fix command. */ remove: function remove(nodeOrToken) { return this.removeRange(nodeOrToken.range); }, /** * Creates a fix command that removes the specified range of text from the source. * The fix is not applied until applyFixes() is called. * @param {int[]} range The range to remove, first item is start of range, second * is end of range. * @returns {Object} The fix command. */ removeRange: function removeRange(range) { return { range: range, text: "" }; } }); module.exports = ruleFixer; },{}],414:[function(require,module,exports){ /** * @fileoverview A variant of EventEmitter which does not give listeners information about each other * @author Teddy Katz */ "use strict"; //------------------------------------------------------------------------------ // Typedefs //------------------------------------------------------------------------------ /** * An event emitter * @typedef {Object} SafeEmitter * @property {function(eventName: string, listenerFunc: Function): void} on Adds a listener for a given event name * @property {function(eventName: string, arg1?: any, arg2?: any, arg3?: any)} emit Emits an event with a given name. * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments. * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners. */ /** * Creates an object which can listen for and emit events. * This is similar to the EventEmitter API in Node's standard library, but it has a few differences. * The goal is to allow multiple modules to attach arbitrary listeners to the same emitter, without * letting the modules know about each other at all. * 1. It has no special keys like `error` and `newListener`, which would allow modules to detect when * another module throws an error or registers a listener. * 2. It calls listener functions without any `this` value. (`EventEmitter` calls listeners with a * `this` value of the emitter instance, which would give listeners access to other listeners.) * @returns {SafeEmitter} An emitter */ module.exports = function () { var listeners = Object.create(null); return Object.freeze({ on: function on(eventName, listener) { if (eventName in listeners) { listeners[eventName].push(listener); } else { listeners[eventName] = [listener]; } }, emit: function emit(eventName) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if (eventName in listeners) { listeners[eventName].forEach(function (listener) { return listener.apply(undefined, args); }); } }, eventNames: function eventNames() { return Object.keys(listeners); } }); }; },{}],415:[function(require,module,exports){ /** * @fileoverview An object that caches and applies source code fixes. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var debug = require("debug")("eslint:source-code-fixer"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ var BOM = "\uFEFF"; /** * Compares items in a messages array by range. * @param {Message} a The first message. * @param {Message} b The second message. * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. * @private */ function compareMessagesByFixRange(a, b) { return a.fix.range[0] - b.fix.range[0] || a.fix.range[1] - b.fix.range[1]; } /** * Compares items in a messages array by line and column. * @param {Message} a The first message. * @param {Message} b The second message. * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. * @private */ function compareMessagesByLocation(a, b) { return a.line - b.line || a.column - b.column; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * Utility for apply fixes to source code. * @constructor */ function SourceCodeFixer() { Object.freeze(this); } /** * Applies the fixes specified by the messages to the given text. Tries to be * smart about the fixes and won't apply fixes over the same area in the text. * @param {string} sourceText The text to apply the changes to. * @param {Message[]} messages The array of messages reported by ESLint. * @param {boolean|Function} [shouldFix=true] Determines whether each message should be fixed * @returns {Object} An object containing the fixed text and any unfixed messages. */ SourceCodeFixer.applyFixes = function (sourceText, messages, shouldFix) { debug("Applying fixes"); if (shouldFix === false) { debug("shouldFix parameter was false, not attempting fixes"); return { fixed: false, messages: messages, output: sourceText }; } // clone the array var remainingMessages = [], fixes = [], bom = sourceText.startsWith(BOM) ? BOM : "", text = bom ? sourceText.slice(1) : sourceText; var lastPos = Number.NEGATIVE_INFINITY, output = bom; /** * Try to use the 'fix' from a problem. * @param {Message} problem The message object to apply fixes from * @returns {boolean} Whether fix was successfully applied */ function attemptFix(problem) { var fix = problem.fix; var start = fix.range[0]; var end = fix.range[1]; // Remain it as a problem if it's overlapped or it's a negative range if (lastPos >= start || start > end) { remainingMessages.push(problem); return false; } // Remove BOM. if (start < 0 && end >= 0 || start === 0 && fix.text.startsWith(BOM)) { output = ""; } // Make output to this fix. output += text.slice(Math.max(0, lastPos), Math.max(0, start)); output += fix.text; lastPos = end; return true; } messages.forEach(function (problem) { if (Object.prototype.hasOwnProperty.call(problem, "fix")) { fixes.push(problem); } else { remainingMessages.push(problem); } }); if (fixes.length) { debug("Found fixes to apply"); var fixesWereApplied = false; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = fixes.sort(compareMessagesByFixRange)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var problem = _step.value; if (typeof shouldFix !== "function" || shouldFix(problem)) { attemptFix(problem); /* * The only time attemptFix will fail is if a previous fix was * applied which conflicts with it. So we can mark this as true. */ fixesWereApplied = true; } else { remainingMessages.push(problem); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } output += text.slice(Math.max(0, lastPos)); return { fixed: fixesWereApplied, messages: remainingMessages.sort(compareMessagesByLocation), output: output }; } debug("No fixes to apply"); return { fixed: false, messages: messages, output: bom + text }; }; module.exports = SourceCodeFixer; },{"debug":53}],416:[function(require,module,exports){ /** * @fileoverview Abstraction of JavaScript source code. * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var TokenStore = require("../token-store"), Traverser = require("./traverser"), astUtils = require("../util/ast-utils"), lodash = require("lodash"); //------------------------------------------------------------------------------ // Private //------------------------------------------------------------------------------ /** * Validates that the given AST has the required information. * @param {ASTNode} ast The Program node of the AST to check. * @throws {Error} If the AST doesn't contain the correct information. * @returns {void} * @private */ function validate(ast) { if (!ast.tokens) { throw new Error("AST is missing the tokens array."); } if (!ast.comments) { throw new Error("AST is missing the comments array."); } if (!ast.loc) { throw new Error("AST is missing location information."); } if (!ast.range) { throw new Error("AST is missing range information"); } } /** * Check to see if its a ES6 export declaration. * @param {ASTNode} astNode An AST node. * @returns {boolean} whether the given node represents an export declaration. * @private */ function looksLikeExport(astNode) { return astNode.type === "ExportDefaultDeclaration" || astNode.type === "ExportNamedDeclaration" || astNode.type === "ExportAllDeclaration" || astNode.type === "ExportSpecifier"; } /** * Merges two sorted lists into a larger sorted list in O(n) time. * @param {Token[]} tokens The list of tokens. * @param {Token[]} comments The list of comments. * @returns {Token[]} A sorted list of tokens and comments. * @private */ function sortedMerge(tokens, comments) { var result = []; var tokenIndex = 0; var commentIndex = 0; while (tokenIndex < tokens.length || commentIndex < comments.length) { if (commentIndex >= comments.length || tokenIndex < tokens.length && tokens[tokenIndex].range[0] < comments[commentIndex].range[0]) { result.push(tokens[tokenIndex++]); } else { result.push(comments[commentIndex++]); } } return result; } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ var SourceCode = function (_TokenStore) { _inherits(SourceCode, _TokenStore); /** * Represents parsed source code. * @param {string|Object} textOrConfig - The source code text or config object. * @param {string} textOrConfig.text - The source code text. * @param {ASTNode} textOrConfig.ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. * @param {Object|null} textOrConfig.parserServices - The parser services. * @param {ScopeManager|null} textOrConfig.scopeManager - The scope of this source code. * @param {Object|null} textOrConfig.visitorKeys - The visitor keys to traverse AST. * @param {ASTNode} [astIfNoConfig] - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. * @constructor */ function SourceCode(textOrConfig, astIfNoConfig) { _classCallCheck(this, SourceCode); var text = void 0, ast = void 0, parserServices = void 0, scopeManager = void 0, visitorKeys = void 0; // Process overloading. if (typeof textOrConfig === "string") { text = textOrConfig; ast = astIfNoConfig; } else if ((typeof textOrConfig === "undefined" ? "undefined" : _typeof(textOrConfig)) === "object" && textOrConfig !== null) { text = textOrConfig.text; ast = textOrConfig.ast; parserServices = textOrConfig.parserServices; scopeManager = textOrConfig.scopeManager; visitorKeys = textOrConfig.visitorKeys; } validate(ast); /** * The flag to indicate that the source code has Unicode BOM. * @type boolean */ var _this = _possibleConstructorReturn(this, (SourceCode.__proto__ || Object.getPrototypeOf(SourceCode)).call(this, ast.tokens, ast.comments)); _this.hasBOM = text.charCodeAt(0) === 0xFEFF; /** * The original text source code. * BOM was stripped from this text. * @type string */ _this.text = _this.hasBOM ? text.slice(1) : text; /** * The parsed AST for the source code. * @type ASTNode */ _this.ast = ast; /** * The parser services of this source code. * @type {Object} */ _this.parserServices = parserServices || {}; /** * The scope of this source code. * @type {ScopeManager|null} */ _this.scopeManager = scopeManager || null; /** * The visitor keys to traverse AST. * @type {Object} */ _this.visitorKeys = visitorKeys || Traverser.DEFAULT_VISITOR_KEYS; // Check the source text for the presence of a shebang since it is parsed as a standard line comment. var shebangMatched = _this.text.match(astUtils.SHEBANG_MATCHER); var hasShebang = shebangMatched && ast.comments.length && ast.comments[0].value === shebangMatched[1]; if (hasShebang) { ast.comments[0].type = "Shebang"; } _this.tokensAndComments = sortedMerge(ast.tokens, ast.comments); /** * The source code split into lines according to ECMA-262 specification. * This is done to avoid each rule needing to do so separately. * @type string[] */ _this.lines = []; _this.lineStartIndices = [0]; var lineEndingPattern = astUtils.createGlobalLinebreakMatcher(); var match = void 0; /* * Previously, this was implemented using a regex that * matched a sequence of non-linebreak characters followed by a * linebreak, then adding the lengths of the matches. However, * this caused a catastrophic backtracking issue when the end * of a file contained a large number of non-newline characters. * To avoid this, the current implementation just matches newlines * and uses match.index to get the correct line start indices. */ while (match = lineEndingPattern.exec(_this.text)) { _this.lines.push(_this.text.slice(_this.lineStartIndices[_this.lineStartIndices.length - 1], match.index)); _this.lineStartIndices.push(match.index + match[0].length); } _this.lines.push(_this.text.slice(_this.lineStartIndices[_this.lineStartIndices.length - 1])); // Cache for comments found using getComments(). _this._commentCache = new WeakMap(); // don't allow modification of this object Object.freeze(_this); Object.freeze(_this.lines); return _this; } /** * Split the source code into multiple lines based on the line delimiters. * @param {string} text Source code as a string. * @returns {string[]} Array of source code lines. * @public */ _createClass(SourceCode, [{ key: "getText", /** * Gets the source code for the given node. * @param {ASTNode=} node The AST node to get the text for. * @param {int=} beforeCount The number of characters before the node to retrieve. * @param {int=} afterCount The number of characters after the node to retrieve. * @returns {string} The text representing the AST node. * @public */ value: function getText(node, beforeCount, afterCount) { if (node) { return this.text.slice(Math.max(node.range[0] - (beforeCount || 0), 0), node.range[1] + (afterCount || 0)); } return this.text; } /** * Gets the entire source text split into an array of lines. * @returns {Array} The source text as an array of lines. * @public */ }, { key: "getLines", value: function getLines() { return this.lines; } /** * Retrieves an array containing all comments in the source code. * @returns {ASTNode[]} An array of comment nodes. * @public */ }, { key: "getAllComments", value: function getAllComments() { return this.ast.comments; } /** * Gets all comments for the given node. * @param {ASTNode} node The AST node to get the comments for. * @returns {Object} An object containing a leading and trailing array * of comments indexed by their position. * @public */ }, { key: "getComments", value: function getComments(node) { if (this._commentCache.has(node)) { return this._commentCache.get(node); } var comments = { leading: [], trailing: [] }; /* * Return all comments as leading comments of the Program node when * there is no executable code. */ if (node.type === "Program") { if (node.body.length === 0) { comments.leading = node.comments; } } else { /* * Return comments as trailing comments of nodes that only contain * comments (to mimic the comment attachment behavior present in Espree). */ if ((node.type === "BlockStatement" || node.type === "ClassBody") && node.body.length === 0 || node.type === "ObjectExpression" && node.properties.length === 0 || node.type === "ArrayExpression" && node.elements.length === 0 || node.type === "SwitchStatement" && node.cases.length === 0) { comments.trailing = this.getTokens(node, { includeComments: true, filter: astUtils.isCommentToken }); } /* * Iterate over tokens before and after node and collect comment tokens. * Do not include comments that exist outside of the parent node * to avoid duplication. */ var currentToken = this.getTokenBefore(node, { includeComments: true }); while (currentToken && astUtils.isCommentToken(currentToken)) { if (node.parent && currentToken.start < node.parent.start) { break; } comments.leading.push(currentToken); currentToken = this.getTokenBefore(currentToken, { includeComments: true }); } comments.leading.reverse(); currentToken = this.getTokenAfter(node, { includeComments: true }); while (currentToken && astUtils.isCommentToken(currentToken)) { if (node.parent && currentToken.end > node.parent.end) { break; } comments.trailing.push(currentToken); currentToken = this.getTokenAfter(currentToken, { includeComments: true }); } } this._commentCache.set(node, comments); return comments; } /** * Retrieves the JSDoc comment for a given node. * @param {ASTNode} node The AST node to get the comment for. * @returns {Token|null} The Block comment token containing the JSDoc comment * for the given node or null if not found. * @public * @deprecated */ }, { key: "getJSDocComment", value: function getJSDocComment(node) { var _this2 = this; /** * Checks for the presence of a JSDoc comment for the given node and returns it. * @param {ASTNode} astNode The AST node to get the comment for. * @returns {Token|null} The Block comment token containing the JSDoc comment * for the given node or null if not found. * @private */ var findJSDocComment = function findJSDocComment(astNode) { var tokenBefore = _this2.getTokenBefore(astNode, { includeComments: true }); if (tokenBefore && astUtils.isCommentToken(tokenBefore) && tokenBefore.type === "Block" && tokenBefore.value.charAt(0) === "*" && astNode.loc.start.line - tokenBefore.loc.end.line <= 1) { return tokenBefore; } return null; }; var parent = node.parent; switch (node.type) { case "ClassDeclaration": case "FunctionDeclaration": return findJSDocComment(looksLikeExport(parent) ? parent : node); case "ClassExpression": return findJSDocComment(parent.parent); case "ArrowFunctionExpression": case "FunctionExpression": if (parent.type !== "CallExpression" && parent.type !== "NewExpression") { while (!this.getCommentsBefore(parent).length && !/Function/.test(parent.type) && parent.type !== "MethodDefinition" && parent.type !== "Property") { parent = parent.parent; if (!parent) { break; } } if (parent && parent.type !== "FunctionDeclaration" && parent.type !== "Program") { return findJSDocComment(parent); } } return findJSDocComment(node); // falls through default: return null; } } /** * Gets the deepest node containing a range index. * @param {int} index Range index of the desired node. * @returns {ASTNode} The node if found or null if not found. * @public */ }, { key: "getNodeByRangeIndex", value: function getNodeByRangeIndex(index) { var result = null; Traverser.traverse(this.ast, { visitorKeys: this.visitorKeys, enter: function enter(node) { if (node.range[0] <= index && index < node.range[1]) { result = node; } else { this.skip(); } }, leave: function leave(node) { if (node === result) { this.break(); } } }); return result; } /** * Determines if two tokens have at least one whitespace character * between them. This completely disregards comments in making the * determination, so comments count as zero-length substrings. * @param {Token} first The token to check after. * @param {Token} second The token to check before. * @returns {boolean} True if there is only space between tokens, false * if there is anything other than whitespace between tokens. * @public */ }, { key: "isSpaceBetweenTokens", value: function isSpaceBetweenTokens(first, second) { var text = this.text.slice(first.range[1], second.range[0]); return (/\s/.test(text.replace(/\/\*.*?\*\//g, "")) ); } /** * Converts a source text index into a (line, column) pair. * @param {number} index The index of a character in a file * @returns {Object} A {line, column} location object with a 0-indexed column * @public */ }, { key: "getLocFromIndex", value: function getLocFromIndex(index) { if (typeof index !== "number") { throw new TypeError("Expected `index` to be a number."); } if (index < 0 || index > this.text.length) { throw new RangeError("Index out of range (requested index " + index + ", but source text has length " + this.text.length + ")."); } /* * For an argument of this.text.length, return the location one "spot" past the last character * of the file. If the last character is a linebreak, the location will be column 0 of the next * line; otherwise, the location will be in the next column on the same line. * * See getIndexFromLoc for the motivation for this special case. */ if (index === this.text.length) { return { line: this.lines.length, column: this.lines[this.lines.length - 1].length }; } /* * To figure out which line rangeIndex is on, determine the last index at which rangeIndex could * be inserted into lineIndices to keep the list sorted. */ var lineNumber = lodash.sortedLastIndex(this.lineStartIndices, index); return { line: lineNumber, column: index - this.lineStartIndices[lineNumber - 1] }; } /** * Converts a (line, column) pair into a range index. * @param {Object} loc A line/column location * @param {number} loc.line The line number of the location (1-indexed) * @param {number} loc.column The column number of the location (0-indexed) * @returns {number} The range index of the location in the file. * @public */ }, { key: "getIndexFromLoc", value: function getIndexFromLoc(loc) { if ((typeof loc === "undefined" ? "undefined" : _typeof(loc)) !== "object" || typeof loc.line !== "number" || typeof loc.column !== "number") { throw new TypeError("Expected `loc` to be an object with numeric `line` and `column` properties."); } if (loc.line <= 0) { throw new RangeError("Line number out of range (line " + loc.line + " requested). Line numbers should be 1-based."); } if (loc.line > this.lineStartIndices.length) { throw new RangeError("Line number out of range (line " + loc.line + " requested, but only " + this.lineStartIndices.length + " lines present)."); } var lineStartIndex = this.lineStartIndices[loc.line - 1]; var lineEndIndex = loc.line === this.lineStartIndices.length ? this.text.length : this.lineStartIndices[loc.line]; var positionIndex = lineStartIndex + loc.column; /* * By design, getIndexFromLoc({ line: lineNum, column: 0 }) should return the start index of * the given line, provided that the line number is valid element of this.lines. Since the * last element of this.lines is an empty string for files with trailing newlines, add a * special case where getting the index for the first location after the end of the file * will return the length of the file, rather than throwing an error. This allows rules to * use getIndexFromLoc consistently without worrying about edge cases at the end of a file. */ if (loc.line === this.lineStartIndices.length && positionIndex > lineEndIndex || loc.line < this.lineStartIndices.length && positionIndex >= lineEndIndex) { throw new RangeError("Column number out of range (column " + loc.column + " requested, but the length of line " + loc.line + " is " + (lineEndIndex - lineStartIndex) + ")."); } return positionIndex; } }], [{ key: "splitLines", value: function splitLines(text) { return text.split(astUtils.createGlobalLinebreakMatcher()); } }]); return SourceCode; }(TokenStore); module.exports = SourceCode; },{"../token-store":398,"../util/ast-utils":405,"./traverser":418,"lodash":92}],417:[function(require,module,exports){ (function (process){ /** * @fileoverview Tracks performance of individual rules. * @author Brandon Mills */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /* istanbul ignore next */ /** * Align the string to left * @param {string} str string to evaluate * @param {int} len length of the string * @param {string} ch delimiter character * @returns {string} modified string * @private */ function alignLeft(str, len, ch) { return str + new Array(len - str.length + 1).join(ch || " "); } /* istanbul ignore next */ /** * Align the string to right * @param {string} str string to evaluate * @param {int} len length of the string * @param {string} ch delimiter character * @returns {string} modified string * @private */ function alignRight(str, len, ch) { return new Array(len - str.length + 1).join(ch || " ") + str; } //------------------------------------------------------------------------------ // Module definition //------------------------------------------------------------------------------ var enabled = !!process.env.TIMING; var HEADERS = ["Rule", "Time (ms)", "Relative"]; var ALIGN = [alignLeft, alignRight, alignRight]; /* istanbul ignore next */ /** * display the data * @param {Object} data Data object to be displayed * @returns {string} modified string * @private */ function display(data) { var total = 0; var rows = Object.keys(data).map(function (key) { var time = data[key]; total += time; return [key, time]; }).sort(function (a, b) { return b[1] - a[1]; }).slice(0, 10); rows.forEach(function (row) { row.push((row[1] * 100 / total).toFixed(1) + "%"); row[1] = row[1].toFixed(3); }); rows.unshift(HEADERS); var widths = []; rows.forEach(function (row) { var len = row.length; for (var i = 0; i < len; i++) { var n = row[i].length; if (!widths[i] || n > widths[i]) { widths[i] = n; } } }); var table = rows.map(function (row) { return row.map(function (cell, index) { return ALIGN[index](cell, widths[index]); }).join(" | "); }); table.splice(1, 0, widths.map(function (width, index) { var extraAlignment = index !== 0 && index !== widths.length - 1 ? 2 : 1; return ALIGN[index](":", width + extraAlignment, "-"); }).join("|")); console.log(table.join("\n")); // eslint-disable-line no-console } /* istanbul ignore next */ module.exports = function () { var data = Object.create(null); /** * Time the run * @param {*} key key from the data object * @param {Function} fn function to be called * @returns {Function} function to be executed * @private */ function time(key, fn) { if (typeof data[key] === "undefined") { data[key] = 0; } return function () { var t = process.hrtime(); fn.apply(undefined, arguments); t = process.hrtime(t); data[key] += t[0] * 1e3 + t[1] / 1e6; }; } if (enabled) { process.on("exit", function () { display(data); }); } return { time: time, enabled: enabled }; }(); }).call(this,require('_process')) },{"_process":103}],418:[function(require,module,exports){ /** * @fileoverview Traverser to traverse AST trees. * @author Nicholas C. Zakas * @author Toru Nagashima */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var vk = require("eslint-visitor-keys"); var debug = require("debug")("eslint:traverser"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Do nothing. * @returns {void} */ function noop() {} // do nothing. /** * Check whether the given value is an ASTNode or not. * @param {any} x The value to check. * @returns {boolean} `true` if the value is an ASTNode. */ function isNode(x) { return x !== null && (typeof x === "undefined" ? "undefined" : _typeof(x)) === "object" && typeof x.type === "string"; } /** * Get the visitor keys of a given node. * @param {Object} visitorKeys The map of visitor keys. * @param {ASTNode} node The node to get their visitor keys. * @returns {string[]} The visitor keys of the node. */ function getVisitorKeys(visitorKeys, node) { var keys = visitorKeys[node.type]; if (!keys) { keys = vk.getKeys(node); debug("Unknown node type \"%s\": Estimated visitor keys %j", node.type, keys); } return keys; } /** * The traverser class to traverse AST trees. */ var Traverser = function () { function Traverser() { _classCallCheck(this, Traverser); this._current = null; this._parents = []; this._skipped = false; this._broken = false; this._visitorKeys = null; this._enter = null; this._leave = null; } /** * @returns {ASTNode} The current node. */ _createClass(Traverser, [{ key: "current", value: function current() { return this._current; } /** * @returns {ASTNode[]} The ancestor nodes. */ }, { key: "parents", value: function parents() { return this._parents.slice(0); } /** * Break the current traversal. * @returns {void} */ }, { key: "break", value: function _break() { this._broken = true; } /** * Skip child nodes for the current traversal. * @returns {void} */ }, { key: "skip", value: function skip() { this._skipped = true; } /** * Traverse the given AST tree. * @param {ASTNode} node The root node to traverse. * @param {Object} options The option object. * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`. * @param {Function} [options.enter=noop] The callback function which is called on entering each node. * @param {Function} [options.leave=noop] The callback function which is called on leaving each node. * @returns {void} */ }, { key: "traverse", value: function traverse(node, options) { this._current = null; this._parents = []; this._skipped = false; this._broken = false; this._visitorKeys = options.visitorKeys || vk.KEYS; this._enter = options.enter || noop; this._leave = options.leave || noop; this._traverse(node, null); } /** * Traverse the given AST tree recursively. * @param {ASTNode} node The current node. * @param {ASTNode|null} parent The parent node. * @returns {void} * @private */ }, { key: "_traverse", value: function _traverse(node, parent) { if (!isNode(node)) { return; } this._current = node; this._skipped = false; this._enter(node, parent); if (!this._skipped && !this._broken) { var keys = getVisitorKeys(this._visitorKeys, node); if (keys.length >= 1) { this._parents.push(node); for (var i = 0; i < keys.length && !this._broken; ++i) { var child = node[keys[i]]; if (Array.isArray(child)) { for (var j = 0; j < child.length && !this._broken; ++j) { this._traverse(child[j], node); } } else { this._traverse(child, node); } } this._parents.pop(); } } if (!this._broken) { this._leave(node, parent); } this._current = parent; } /** * Calculates the keys to use for traversal. * @param {ASTNode} node The node to read keys from. * @returns {string[]} An array of keys to visit on the node. * @private */ }], [{ key: "getKeys", value: function getKeys(node) { return vk.getKeys(node); } /** * Traverse the given AST tree. * @param {ASTNode} node The root node to traverse. * @param {Object} options The option object. * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`. * @param {Function} [options.enter=noop] The callback function which is called on entering each node. * @param {Function} [options.leave=noop] The callback function which is called on leaving each node. * @returns {void} */ }, { key: "traverse", value: function traverse(node, options) { new Traverser().traverse(node, options); } /** * The default visitor keys. * @type {Object} */ }, { key: "DEFAULT_VISITOR_KEYS", get: function get() { return vk.KEYS; } }]); return Traverser; }(); module.exports = Traverser; },{"debug":53,"eslint-visitor-keys":69}],419:[function(require,module,exports){ /** * @author Toru Nagashima */ "use strict"; module.exports = { isCombiningCharacter: require("./is-combining-character"), isEmojiModifier: require("./is-emoji-modifier"), isRegionalIndicatorSymbol: require("./is-regional-indicator-symbol"), isSurrogatePair: require("./is-surrogate-pair") }; },{"./is-combining-character":420,"./is-emoji-modifier":421,"./is-regional-indicator-symbol":422,"./is-surrogate-pair":423}],420:[function(require,module,exports){ // THIS FILE WAS GENERATED BY 'tools/update-unicode-utils.js' "use strict"; var combiningChars = new Set([768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1471, 1473, 1474, 1476, 1477, 1479, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1648, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1759, 1760, 1761, 1762, 1763, 1764, 1767, 1768, 1770, 1771, 1772, 1773, 1809, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2070, 2071, 2072, 2073, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2085, 2086, 2087, 2089, 2090, 2091, 2092, 2093, 2137, 2138, 2139, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2362, 2363, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2402, 2403, 2433, 2434, 2435, 2492, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2503, 2504, 2507, 2508, 2509, 2519, 2530, 2531, 2561, 2562, 2563, 2620, 2622, 2623, 2624, 2625, 2626, 2631, 2632, 2635, 2636, 2637, 2641, 2672, 2673, 2677, 2689, 2690, 2691, 2748, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2759, 2760, 2761, 2763, 2764, 2765, 2786, 2787, 2810, 2811, 2812, 2813, 2814, 2815, 2817, 2818, 2819, 2876, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2887, 2888, 2891, 2892, 2893, 2902, 2903, 2914, 2915, 2946, 3006, 3007, 3008, 3009, 3010, 3014, 3015, 3016, 3018, 3019, 3020, 3021, 3031, 3072, 3073, 3074, 3075, 3134, 3135, 3136, 3137, 3138, 3139, 3140, 3142, 3143, 3144, 3146, 3147, 3148, 3149, 3157, 3158, 3170, 3171, 3201, 3202, 3203, 3260, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3270, 3271, 3272, 3274, 3275, 3276, 3277, 3285, 3286, 3298, 3299, 3328, 3329, 3330, 3331, 3387, 3388, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3398, 3399, 3400, 3402, 3403, 3404, 3405, 3415, 3426, 3427, 3458, 3459, 3530, 3535, 3536, 3537, 3538, 3539, 3540, 3542, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3570, 3571, 3633, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3761, 3764, 3765, 3766, 3767, 3768, 3769, 3771, 3772, 3784, 3785, 3786, 3787, 3788, 3789, 3864, 3865, 3893, 3895, 3897, 3902, 3903, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3974, 3975, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, 4038, 4139, 4140, 4141, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4182, 4183, 4184, 4185, 4190, 4191, 4192, 4194, 4195, 4196, 4199, 4200, 4201, 4202, 4203, 4204, 4205, 4209, 4210, 4211, 4212, 4226, 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4239, 4250, 4251, 4252, 4253, 4957, 4958, 4959, 5906, 5907, 5908, 5938, 5939, 5940, 5970, 5971, 6002, 6003, 6068, 6069, 6070, 6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 6079, 6080, 6081, 6082, 6083, 6084, 6085, 6086, 6087, 6088, 6089, 6090, 6091, 6092, 6093, 6094, 6095, 6096, 6097, 6098, 6099, 6109, 6155, 6156, 6157, 6277, 6278, 6313, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6448, 6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, 6679, 6680, 6681, 6682, 6683, 6741, 6742, 6743, 6744, 6745, 6746, 6747, 6748, 6749, 6750, 6752, 6753, 6754, 6755, 6756, 6757, 6758, 6759, 6760, 6761, 6762, 6763, 6764, 6765, 6766, 6767, 6768, 6769, 6770, 6771, 6772, 6773, 6774, 6775, 6776, 6777, 6778, 6779, 6780, 6783, 6832, 6833, 6834, 6835, 6836, 6837, 6838, 6839, 6840, 6841, 6842, 6843, 6844, 6845, 6846, 6912, 6913, 6914, 6915, 6916, 6964, 6965, 6966, 6967, 6968, 6969, 6970, 6971, 6972, 6973, 6974, 6975, 6976, 6977, 6978, 6979, 6980, 7019, 7020, 7021, 7022, 7023, 7024, 7025, 7026, 7027, 7040, 7041, 7042, 7073, 7074, 7075, 7076, 7077, 7078, 7079, 7080, 7081, 7082, 7083, 7084, 7085, 7142, 7143, 7144, 7145, 7146, 7147, 7148, 7149, 7150, 7151, 7152, 7153, 7154, 7155, 7204, 7205, 7206, 7207, 7208, 7209, 7210, 7211, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, 7220, 7221, 7222, 7223, 7376, 7377, 7378, 7380, 7381, 7382, 7383, 7384, 7385, 7386, 7387, 7388, 7389, 7390, 7391, 7392, 7393, 7394, 7395, 7396, 7397, 7398, 7399, 7400, 7405, 7410, 7411, 7412, 7415, 7416, 7417, 7616, 7617, 7618, 7619, 7620, 7621, 7622, 7623, 7624, 7625, 7626, 7627, 7628, 7629, 7630, 7631, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, 7643, 7644, 7645, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7654, 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7675, 7676, 7677, 7678, 7679, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8411, 8412, 8413, 8414, 8415, 8416, 8417, 8418, 8419, 8420, 8421, 8422, 8423, 8424, 8425, 8426, 8427, 8428, 8429, 8430, 8431, 8432, 11503, 11504, 11505, 11647, 11744, 11745, 11746, 11747, 11748, 11749, 11750, 11751, 11752, 11753, 11754, 11755, 11756, 11757, 11758, 11759, 11760, 11761, 11762, 11763, 11764, 11765, 11766, 11767, 11768, 11769, 11770, 11771, 11772, 11773, 11774, 11775, 12330, 12331, 12332, 12333, 12334, 12335, 12441, 12442, 42607, 42608, 42609, 42610, 42612, 42613, 42614, 42615, 42616, 42617, 42618, 42619, 42620, 42621, 42654, 42655, 42736, 42737, 43010, 43014, 43019, 43043, 43044, 43045, 43046, 43047, 43136, 43137, 43188, 43189, 43190, 43191, 43192, 43193, 43194, 43195, 43196, 43197, 43198, 43199, 43200, 43201, 43202, 43203, 43204, 43205, 43232, 43233, 43234, 43235, 43236, 43237, 43238, 43239, 43240, 43241, 43242, 43243, 43244, 43245, 43246, 43247, 43248, 43249, 43302, 43303, 43304, 43305, 43306, 43307, 43308, 43309, 43335, 43336, 43337, 43338, 43339, 43340, 43341, 43342, 43343, 43344, 43345, 43346, 43347, 43392, 43393, 43394, 43395, 43443, 43444, 43445, 43446, 43447, 43448, 43449, 43450, 43451, 43452, 43453, 43454, 43455, 43456, 43493, 43561, 43562, 43563, 43564, 43565, 43566, 43567, 43568, 43569, 43570, 43571, 43572, 43573, 43574, 43587, 43596, 43597, 43643, 43644, 43645, 43696, 43698, 43699, 43700, 43703, 43704, 43710, 43711, 43713, 43755, 43756, 43757, 43758, 43759, 43765, 43766, 44003, 44004, 44005, 44006, 44007, 44008, 44009, 44010, 44012, 44013, 64286, 65024, 65025, 65026, 65027, 65028, 65029, 65030, 65031, 65032, 65033, 65034, 65035, 65036, 65037, 65038, 65039, 65056, 65057, 65058, 65059, 65060, 65061, 65062, 65063, 65064, 65065, 65066, 65067, 65068, 65069, 65070, 65071, 66045, 66272, 66422, 66423, 66424, 66425, 66426, 68097, 68098, 68099, 68101, 68102, 68108, 68109, 68110, 68111, 68152, 68153, 68154, 68159, 68325, 68326, 69632, 69633, 69634, 69688, 69689, 69690, 69691, 69692, 69693, 69694, 69695, 69696, 69697, 69698, 69699, 69700, 69701, 69702, 69759, 69760, 69761, 69762, 69808, 69809, 69810, 69811, 69812, 69813, 69814, 69815, 69816, 69817, 69818, 69888, 69889, 69890, 69927, 69928, 69929, 69930, 69931, 69932, 69933, 69934, 69935, 69936, 69937, 69938, 69939, 69940, 70003, 70016, 70017, 70018, 70067, 70068, 70069, 70070, 70071, 70072, 70073, 70074, 70075, 70076, 70077, 70078, 70079, 70080, 70090, 70091, 70092, 70188, 70189, 70190, 70191, 70192, 70193, 70194, 70195, 70196, 70197, 70198, 70199, 70206, 70367, 70368, 70369, 70370, 70371, 70372, 70373, 70374, 70375, 70376, 70377, 70378, 70400, 70401, 70402, 70403, 70460, 70462, 70463, 70464, 70465, 70466, 70467, 70468, 70471, 70472, 70475, 70476, 70477, 70487, 70498, 70499, 70502, 70503, 70504, 70505, 70506, 70507, 70508, 70512, 70513, 70514, 70515, 70516, 70709, 70710, 70711, 70712, 70713, 70714, 70715, 70716, 70717, 70718, 70719, 70720, 70721, 70722, 70723, 70724, 70725, 70726, 70832, 70833, 70834, 70835, 70836, 70837, 70838, 70839, 70840, 70841, 70842, 70843, 70844, 70845, 70846, 70847, 70848, 70849, 70850, 70851, 71087, 71088, 71089, 71090, 71091, 71092, 71093, 71096, 71097, 71098, 71099, 71100, 71101, 71102, 71103, 71104, 71132, 71133, 71216, 71217, 71218, 71219, 71220, 71221, 71222, 71223, 71224, 71225, 71226, 71227, 71228, 71229, 71230, 71231, 71232, 71339, 71340, 71341, 71342, 71343, 71344, 71345, 71346, 71347, 71348, 71349, 71350, 71351, 71453, 71454, 71455, 71456, 71457, 71458, 71459, 71460, 71461, 71462, 71463, 71464, 71465, 71466, 71467, 72193, 72194, 72195, 72196, 72197, 72198, 72199, 72200, 72201, 72202, 72243, 72244, 72245, 72246, 72247, 72248, 72249, 72251, 72252, 72253, 72254, 72263, 72273, 72274, 72275, 72276, 72277, 72278, 72279, 72280, 72281, 72282, 72283, 72330, 72331, 72332, 72333, 72334, 72335, 72336, 72337, 72338, 72339, 72340, 72341, 72342, 72343, 72344, 72345, 72751, 72752, 72753, 72754, 72755, 72756, 72757, 72758, 72760, 72761, 72762, 72763, 72764, 72765, 72766, 72767, 72850, 72851, 72852, 72853, 72854, 72855, 72856, 72857, 72858, 72859, 72860, 72861, 72862, 72863, 72864, 72865, 72866, 72867, 72868, 72869, 72870, 72871, 72873, 72874, 72875, 72876, 72877, 72878, 72879, 72880, 72881, 72882, 72883, 72884, 72885, 72886, 73009, 73010, 73011, 73012, 73013, 73014, 73018, 73020, 73021, 73023, 73024, 73025, 73026, 73027, 73028, 73029, 73031, 92912, 92913, 92914, 92915, 92916, 92976, 92977, 92978, 92979, 92980, 92981, 92982, 94033, 94034, 94035, 94036, 94037, 94038, 94039, 94040, 94041, 94042, 94043, 94044, 94045, 94046, 94047, 94048, 94049, 94050, 94051, 94052, 94053, 94054, 94055, 94056, 94057, 94058, 94059, 94060, 94061, 94062, 94063, 94064, 94065, 94066, 94067, 94068, 94069, 94070, 94071, 94072, 94073, 94074, 94075, 94076, 94077, 94078, 94095, 94096, 94097, 94098, 113821, 113822, 119141, 119142, 119143, 119144, 119145, 119149, 119150, 119151, 119152, 119153, 119154, 119163, 119164, 119165, 119166, 119167, 119168, 119169, 119170, 119173, 119174, 119175, 119176, 119177, 119178, 119179, 119210, 119211, 119212, 119213, 119362, 119363, 119364, 121344, 121345, 121346, 121347, 121348, 121349, 121350, 121351, 121352, 121353, 121354, 121355, 121356, 121357, 121358, 121359, 121360, 121361, 121362, 121363, 121364, 121365, 121366, 121367, 121368, 121369, 121370, 121371, 121372, 121373, 121374, 121375, 121376, 121377, 121378, 121379, 121380, 121381, 121382, 121383, 121384, 121385, 121386, 121387, 121388, 121389, 121390, 121391, 121392, 121393, 121394, 121395, 121396, 121397, 121398, 121403, 121404, 121405, 121406, 121407, 121408, 121409, 121410, 121411, 121412, 121413, 121414, 121415, 121416, 121417, 121418, 121419, 121420, 121421, 121422, 121423, 121424, 121425, 121426, 121427, 121428, 121429, 121430, 121431, 121432, 121433, 121434, 121435, 121436, 121437, 121438, 121439, 121440, 121441, 121442, 121443, 121444, 121445, 121446, 121447, 121448, 121449, 121450, 121451, 121452, 121461, 121476, 121499, 121500, 121501, 121502, 121503, 121505, 121506, 121507, 121508, 121509, 121510, 121511, 121512, 121513, 121514, 121515, 121516, 121517, 121518, 121519, 122880, 122881, 122882, 122883, 122884, 122885, 122886, 122888, 122889, 122890, 122891, 122892, 122893, 122894, 122895, 122896, 122897, 122898, 122899, 122900, 122901, 122902, 122903, 122904, 122907, 122908, 122909, 122910, 122911, 122912, 122913, 122915, 122916, 122918, 122919, 122920, 122921, 122922, 125136, 125137, 125138, 125139, 125140, 125141, 125142, 125252, 125253, 125254, 125255, 125256, 125257, 125258, 917760, 917761, 917762, 917763, 917764, 917765, 917766, 917767, 917768, 917769, 917770, 917771, 917772, 917773, 917774, 917775, 917776, 917777, 917778, 917779, 917780, 917781, 917782, 917783, 917784, 917785, 917786, 917787, 917788, 917789, 917790, 917791, 917792, 917793, 917794, 917795, 917796, 917797, 917798, 917799, 917800, 917801, 917802, 917803, 917804, 917805, 917806, 917807, 917808, 917809, 917810, 917811, 917812, 917813, 917814, 917815, 917816, 917817, 917818, 917819, 917820, 917821, 917822, 917823, 917824, 917825, 917826, 917827, 917828, 917829, 917830, 917831, 917832, 917833, 917834, 917835, 917836, 917837, 917838, 917839, 917840, 917841, 917842, 917843, 917844, 917845, 917846, 917847, 917848, 917849, 917850, 917851, 917852, 917853, 917854, 917855, 917856, 917857, 917858, 917859, 917860, 917861, 917862, 917863, 917864, 917865, 917866, 917867, 917868, 917869, 917870, 917871, 917872, 917873, 917874, 917875, 917876, 917877, 917878, 917879, 917880, 917881, 917882, 917883, 917884, 917885, 917886, 917887, 917888, 917889, 917890, 917891, 917892, 917893, 917894, 917895, 917896, 917897, 917898, 917899, 917900, 917901, 917902, 917903, 917904, 917905, 917906, 917907, 917908, 917909, 917910, 917911, 917912, 917913, 917914, 917915, 917916, 917917, 917918, 917919, 917920, 917921, 917922, 917923, 917924, 917925, 917926, 917927, 917928, 917929, 917930, 917931, 917932, 917933, 917934, 917935, 917936, 917937, 917938, 917939, 917940, 917941, 917942, 917943, 917944, 917945, 917946, 917947, 917948, 917949, 917950, 917951, 917952, 917953, 917954, 917955, 917956, 917957, 917958, 917959, 917960, 917961, 917962, 917963, 917964, 917965, 917966, 917967, 917968, 917969, 917970, 917971, 917972, 917973, 917974, 917975, 917976, 917977, 917978, 917979, 917980, 917981, 917982, 917983, 917984, 917985, 917986, 917987, 917988, 917989, 917990, 917991, 917992, 917993, 917994, 917995, 917996, 917997, 917998, 917999]); /** * Check whether a given character is a combining mark or not. * @param {number} c The character code to check. * @returns {boolean} `true` if the character belongs to the category, one of `Mc`, `Me`, and `Mn`. */ module.exports = function isCombiningCharacter(c) { return combiningChars.has(c); }; },{}],421:[function(require,module,exports){ /** * @author Toru Nagashima */ "use strict"; /** * Check whether a given character is an emoji modifier. * @param {number} code The character code to check. * @returns {boolean} `true` if the character is an emoji modifier. */ module.exports = function isEmojiModifier(code) { return code >= 0x1F3FB && code <= 0x1F3FF; }; },{}],422:[function(require,module,exports){ /** * @author Toru Nagashima */ "use strict"; /** * Check whether a given character is a regional indicator symbol. * @param {number} code The character code to check. * @returns {boolean} `true` if the character is a regional indicator symbol. */ module.exports = function isRegionalIndicatorSymbol(code) { return code >= 0x1F1E6 && code <= 0x1F1FF; }; },{}],423:[function(require,module,exports){ /** * @author Toru Nagashima */ "use strict"; /** * Check whether given two characters are a surrogate pair. * @param {number} lead The code of the lead character. * @param {number} tail The code of the tail character. * @returns {boolean} `true` if the character pair is a surrogate pair. */ module.exports = function isSurrogatePair(lead, tail) { return lead >= 0xD800 && lead < 0xDC00 && tail >= 0xDC00 && tail < 0xE000; }; },{}]},{},[122])(122) });