UNPKG

motion

Version:

motion - moving development forward

1,585 lines (1,363 loc) 133 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn = f()}})(function(){var define,module,exports;return (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<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ // The main exported interface (under `self.acorn` when in the // browser) is a `parse` function that takes a code string and // returns an abstract syntax tree as specified by [Mozilla parser // API][api]. // // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API "use strict"; exports.parse = parse; // This function tries to parse a single expression at a given // offset in a string. Useful for parsing mixed-language formats // that embed JavaScript expressions. exports.parseExpressionAt = parseExpressionAt; // Acorn is organized as a tokenizer and a recursive-descent parser. // The `tokenize` export provides an interface to the tokenizer. exports.tokenizer = tokenizer; exports.__esModule = true; // Acorn is a tiny, fast JavaScript parser written in JavaScript. // // Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and // various contributors and released under an MIT license. // // Git repositories for Acorn are available at // // http://marijnhaverbeke.nl/git/acorn // https://github.com/marijnh/acorn.git // // Please use the [github bug tracker][ghbt] to report issues. // // [ghbt]: https://github.com/marijnh/acorn/issues // // This file defines the main parser interface. The library also comes // with a [error-tolerant parser][dammit] and an // [abstract syntax tree walker][walk], defined in other files. // // [dammit]: acorn_loose.js // [walk]: util/walk.js var _state = _dereq_("./state"); var Parser = _state.Parser; var _options = _dereq_("./options"); var getOptions = _options.getOptions; _dereq_("./parseutil"); _dereq_("./statement"); _dereq_("./lval"); _dereq_("./expression"); exports.Parser = _state.Parser; exports.plugins = _state.plugins; exports.defaultOptions = _options.defaultOptions; var _location = _dereq_("./location"); exports.SourceLocation = _location.SourceLocation; exports.getLineInfo = _location.getLineInfo; exports.Node = _dereq_("./node").Node; var _tokentype = _dereq_("./tokentype"); exports.TokenType = _tokentype.TokenType; exports.tokTypes = _tokentype.types; var _tokencontext = _dereq_("./tokencontext"); exports.TokContext = _tokencontext.TokContext; exports.tokContexts = _tokencontext.types; var _identifier = _dereq_("./identifier"); exports.isIdentifierChar = _identifier.isIdentifierChar; exports.isIdentifierStart = _identifier.isIdentifierStart; exports.Token = _dereq_("./tokenize").Token; var _whitespace = _dereq_("./whitespace"); exports.isNewLine = _whitespace.isNewLine; exports.lineBreak = _whitespace.lineBreak; exports.lineBreakG = _whitespace.lineBreakG; var version = "1.2.2";exports.version = version; function parse(input, options) { var p = parser(options, input); var startPos = p.pos, startLoc = p.options.locations && p.curPosition(); p.nextToken(); return p.parseTopLevel(p.options.program || p.startNodeAt(startPos, startLoc)); } function parseExpressionAt(input, pos, options) { var p = parser(options, input, pos); p.nextToken(); return p.parseExpression(); } function tokenizer(input, options) { return parser(options, input); } function parser(options, input) { return new Parser(getOptions(options), String(input)); } },{"./expression":6,"./identifier":7,"./location":8,"./lval":9,"./node":10,"./options":11,"./parseutil":12,"./state":13,"./statement":14,"./tokencontext":15,"./tokenize":16,"./tokentype":17,"./whitespace":19}],2:[function(_dereq_,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } },{}],3:[function(_dereq_,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; function drainQueue() { if (draining) { return; } draining = true; var currentQueue; var len = queue.length; while(len) { currentQueue = queue; queue = []; var i = -1; while (++i < len) { currentQueue[i](); } len = queue.length; } draining = false; } process.nextTick = function (fun) { queue.push(fun); if (!draining) { setTimeout(drainQueue, 0); } }; 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.binding = function (name) { throw new Error('process.binding is not supported'); }; // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],4:[function(_dereq_,module,exports){ module.exports = function isBuffer(arg) { return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function'; } },{}],5:[function(_dereq_,module,exports){ (function (process,global){ // 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. var formatRegExp = /%[sdj%]/g; exports.format = function(f) { if (!isString(f)) { var objects = []; for (var i = 0; i < arguments.length; i++) { objects.push(inspect(arguments[i])); } return objects.join(' '); } var i = 1; var args = arguments; var len = args.length; var str = String(f).replace(formatRegExp, function(x) { if (x === '%%') return '%'; if (i >= len) return x; switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': try { return JSON.stringify(args[i++]); } catch (_) { return '[Circular]'; } default: return x; } }); for (var x = args[i]; i < len; x = args[++i]) { if (isNull(x) || !isObject(x)) { str += ' ' + x; } else { str += ' ' + inspect(x); } } return str; }; // Mark that a method should not be used. // Returns a modified function which warns once by default. // If --no-deprecation is set, then it is a no-op. exports.deprecate = function(fn, msg) { // Allow for deprecating things in the process of starting up. if (isUndefined(global.process)) { return function() { return exports.deprecate(fn, msg).apply(this, arguments); }; } if (process.noDeprecation === true) { return fn; } var warned = false; function deprecated() { if (!warned) { if (process.throwDeprecation) { throw new Error(msg); } else if (process.traceDeprecation) { console.trace(msg); } else { console.error(msg); } warned = true; } return fn.apply(this, arguments); } return deprecated; }; var debugs = {}; var debugEnviron; exports.debuglog = function(set) { if (isUndefined(debugEnviron)) debugEnviron = process.env.NODE_DEBUG || ''; set = set.toUpperCase(); if (!debugs[set]) { if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { var pid = process.pid; debugs[set] = function() { var msg = exports.format.apply(exports, arguments); console.error('%s %d: %s', set, pid, msg); }; } else { debugs[set] = function() {}; } } return debugs[set]; }; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Object} opts Optional options object that alters the output. */ /* legacy: obj, showHidden, depth, colors*/ function inspect(obj, opts) { // default options var ctx = { seen: [], stylize: stylizeNoColor }; // legacy... if (arguments.length >= 3) ctx.depth = arguments[2]; if (arguments.length >= 4) ctx.colors = arguments[3]; if (isBoolean(opts)) { // legacy... ctx.showHidden = opts; } else if (opts) { // got an "options" object exports._extend(ctx, opts); } // set default options if (isUndefined(ctx.showHidden)) ctx.showHidden = false; if (isUndefined(ctx.depth)) ctx.depth = 2; if (isUndefined(ctx.colors)) ctx.colors = false; if (isUndefined(ctx.customInspect)) ctx.customInspect = true; if (ctx.colors) ctx.stylize = stylizeWithColor; return formatValue(ctx, obj, ctx.depth); } exports.inspect = inspect; // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics inspect.colors = { 'bold' : [1, 22], 'italic' : [3, 23], 'underline' : [4, 24], 'inverse' : [7, 27], 'white' : [37, 39], 'grey' : [90, 39], 'black' : [30, 39], 'blue' : [34, 39], 'cyan' : [36, 39], 'green' : [32, 39], 'magenta' : [35, 39], 'red' : [31, 39], 'yellow' : [33, 39] }; // Don't use 'blue' not visible on cmd.exe inspect.styles = { 'special': 'cyan', 'number': 'yellow', 'boolean': 'yellow', 'undefined': 'grey', 'null': 'bold', 'string': 'green', 'date': 'magenta', // "name": intentionally not styling 'regexp': 'red' }; function stylizeWithColor(str, styleType) { var style = inspect.styles[styleType]; if (style) { return '\u001b[' + inspect.colors[style][0] + 'm' + str + '\u001b[' + inspect.colors[style][1] + 'm'; } else { return str; } } function stylizeNoColor(str, styleType) { return str; } function arrayToHash(array) { var hash = {}; array.forEach(function(val, idx) { hash[val] = true; }); return hash; } function formatValue(ctx, value, recurseTimes) { // Provide a hook for user-specified inspect functions. // Check that value is an object with an inspect function on it if (ctx.customInspect && value && isFunction(value.inspect) && // Filter out the util module, it's inspect function is special value.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { var ret = value.inspect(recurseTimes, ctx); if (!isString(ret)) { ret = formatValue(ctx, ret, recurseTimes); } return ret; } // Primitive types cannot have properties var primitive = formatPrimitive(ctx, value); if (primitive) { return primitive; } // Look up the keys of the object. var keys = Object.keys(value); var visibleKeys = arrayToHash(keys); if (ctx.showHidden) { keys = Object.getOwnPropertyNames(value); } // IE doesn't make error fields non-enumerable // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx if (isError(value) && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { return formatError(value); } // Some type of object without properties can be shortcutted. if (keys.length === 0) { if (isFunction(value)) { var name = value.name ? ': ' + value.name : ''; return ctx.stylize('[Function' + name + ']', 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } if (isDate(value)) { return ctx.stylize(Date.prototype.toString.call(value), 'date'); } if (isError(value)) { return formatError(value); } } var base = '', array = false, braces = ['{', '}']; // Make Array say that they are Array if (isArray(value)) { array = true; braces = ['[', ']']; } // Make functions say that they are functions if (isFunction(value)) { var n = value.name ? ': ' + value.name : ''; base = ' [Function' + n + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + Date.prototype.toUTCString.call(value); } // Make error with message first say the error if (isError(value)) { base = ' ' + formatError(value); } if (keys.length === 0 && (!array || value.length == 0)) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { return ctx.stylize('[Object]', 'special'); } } ctx.seen.push(value); var output; if (array) { output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { output = keys.map(function(key) { return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } ctx.seen.pop(); return reduceToSingleString(output, base, braces); } function formatPrimitive(ctx, value) { if (isUndefined(value)) return ctx.stylize('undefined', 'undefined'); if (isString(value)) { var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; return ctx.stylize(simple, 'string'); } if (isNumber(value)) return ctx.stylize('' + value, 'number'); if (isBoolean(value)) return ctx.stylize('' + value, 'boolean'); // For some reason typeof null is "object", so special case here. if (isNull(value)) return ctx.stylize('null', 'null'); } function formatError(value) { return '[' + Error.prototype.toString.call(value) + ']'; } function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; for (var i = 0, l = value.length; i < l; ++i) { if (hasOwnProperty(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); } else { output.push(''); } } keys.forEach(function(key) { if (!key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } }); return output; } function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { var name, str, desc; desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; if (desc.get) { if (desc.set) { str = ctx.stylize('[Getter/Setter]', 'special'); } else { str = ctx.stylize('[Getter]', 'special'); } } else { if (desc.set) { str = ctx.stylize('[Setter]', 'special'); } } if (!hasOwnProperty(visibleKeys, key)) { name = '[' + key + ']'; } if (!str) { if (ctx.seen.indexOf(desc.value) < 0) { if (isNull(recurseTimes)) { str = formatValue(ctx, desc.value, null); } else { str = formatValue(ctx, desc.value, recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (array) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); } else { str = '\n' + str.split('\n').map(function(line) { return ' ' + line; }).join('\n'); } } } else { str = ctx.stylize('[Circular]', 'special'); } } if (isUndefined(name)) { if (array && key.match(/^\d+$/)) { return str; } name = JSON.stringify('' + key); if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { name = name.substr(1, name.length - 2); name = ctx.stylize(name, 'name'); } else { name = name.replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"); name = ctx.stylize(name, 'string'); } } return name + ': ' + str; } function reduceToSingleString(output, base, braces) { var numLinesEst = 0; var length = output.reduce(function(prev, cur) { numLinesEst++; if (cur.indexOf('\n') >= 0) numLinesEst++; return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; }, 0); if (length > 60) { return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1]; } return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(ar) { return Array.isArray(ar); } exports.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } exports.isBoolean = isBoolean; function isNull(arg) { return arg === null; } exports.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } exports.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } exports.isString = isString; function isSymbol(arg) { return typeof arg === 'symbol'; } exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } exports.isUndefined = isUndefined; function isRegExp(re) { return isObject(re) && objectToString(re) === '[object RegExp]'; } exports.isRegExp = isRegExp; function isObject(arg) { return typeof arg === 'object' && arg !== null; } exports.isObject = isObject; function isDate(d) { return isObject(d) && objectToString(d) === '[object Date]'; } exports.isDate = isDate; function isError(e) { return isObject(e) && (objectToString(e) === '[object Error]' || e instanceof Error); } exports.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } exports.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } exports.isPrimitive = isPrimitive; exports.isBuffer = _dereq_('./support/isBuffer'); function objectToString(o) { return Object.prototype.toString.call(o); } function pad(n) { return n < 10 ? '0' + n.toString(10) : n.toString(10); } var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // 26 Feb 16:19:34 function timestamp() { var d = new Date(); var time = [pad(d.getHours()), pad(d.getMinutes()), pad(d.getSeconds())].join(':'); return [d.getDate(), months[d.getMonth()], time].join(' '); } // log is just a thin wrapper to console.log that prepends a timestamp exports.log = function() { console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); }; /** * Inherit the prototype methods from one constructor into another. * * The Function.prototype.inherits from lang.js rewritten as a standalone * function (not on Function.prototype). NOTE: If this file is to be loaded * during bootstrapping this function needs to be rewritten using some native * functions as prototype setup using normal JavaScript does not work as * expected during bootstrapping (see mirror.js in r114903). * * @param {function} ctor Constructor function which needs to inherit the * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ exports.inherits = _dereq_('inherits'); exports._extend = function(origin, add) { // Don't do anything if add isn't an object if (!add || !isObject(add)) return origin; var keys = Object.keys(add); var i = keys.length; while (i--) { origin[keys[i]] = add[keys[i]]; } return origin; }; function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } }).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./support/isBuffer":4,"_process":3,"inherits":2}],6:[function(_dereq_,module,exports){ // 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 "use strict"; var tt = _dereq_("./tokentype").types; var Parser = _dereq_("./state").Parser; var reservedWords = _dereq_("./identifier").reservedWords; var has = _dereq_("./util").has; var pp = 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.checkPropClash = function (prop, propHash) { if (this.options.ecmaVersion >= 6) return; var key = prop.key, name = undefined; switch (key.type) { case "Identifier": name = key.name;break; case "Literal": name = String(key.value);break; default: return; } var kind = prop.kind || "init", other = undefined; if (has(propHash, name)) { other = propHash[name]; var isGetSet = kind !== "init"; if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(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.parseExpression = function (noIn, refShorthandDefaultPos) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); if (this.type === tt.comma) { var node = this.startNodeAt(startPos, startLoc); node.expressions = [expr]; while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos)); return this.finishNode(node, "SequenceExpression"); } return expr; }; // Parse an assignment expression. This includes applications of // operators like `+=`. pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) { if (this.type == tt._yield && this.inGenerator) return this.parseYield(); var failOnShorthandAssign = undefined; if (!refShorthandDefaultPos) { refShorthandDefaultPos = { start: 0 }; failOnShorthandAssign = true; } else { failOnShorthandAssign = false; } var startPos = this.start, startLoc = this.startLoc; if (this.type == tt.parenL || this.type == tt.name) this.potentialArrowAt = this.start; var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos); 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 === tt.eq ? this.toAssignable(left) : left; refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly this.checkLVal(left); this.next(); node.right = this.parseMaybeAssign(noIn); return this.finishNode(node, "AssignmentExpression"); } else if (failOnShorthandAssign && refShorthandDefaultPos.start) { this.unexpected(refShorthandDefaultPos.start); } return left; }; // Parse a ternary conditional (`?:`) operator. pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseExprOps(noIn, refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; if (this.eat(tt.question)) { var node = this.startNodeAt(startPos, startLoc); node.test = expr; node.consequent = this.parseMaybeAssign(); this.expect(tt.colon); node.alternate = this.parseMaybeAssign(noIn); return this.finishNode(node, "ConditionalExpression"); } return expr; }; // Start the precedence parser. pp.parseExprOps = function (noIn, refShorthandDefaultPos) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseMaybeUnary(refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; return 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.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) { var prec = this.type.binop; if (Array.isArray(leftStartPos)) { if (this.options.locations && noIn === undefined) { // shift arguments to left by one noIn = minPrec; minPrec = leftStartLoc; // flatten leftStartPos leftStartLoc = leftStartPos[1]; leftStartPos = leftStartPos[0]; } } if (prec != null && (!noIn || this.type !== tt._in)) { if (prec > minPrec) { var node = this.startNodeAt(leftStartPos, leftStartLoc); node.left = left; node.operator = this.value; var op = this.type; this.next(); var startPos = this.start, startLoc = this.startLoc; node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn); this.finishNode(node, op === tt.logicalOR || op === tt.logicalAND ? "LogicalExpression" : "BinaryExpression"); return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); } } return left; }; // Parse unary operators, both prefix and postfix. pp.parseMaybeUnary = function (refShorthandDefaultPos) { if (this.type.prefix) { var node = this.startNode(), update = this.type === tt.incDec; node.operator = this.value; node.prefix = true; this.next(); node.argument = this.parseMaybeUnary(); if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start); if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode"); return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } var startPos = this.start, startLoc = this.startLoc; var expr = this.parseExprSubscripts(refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; while (this.type.postfix && !this.canInsertSemicolon()) { var node = this.startNodeAt(startPos, startLoc); node.operator = this.value; node.prefix = false; node.argument = expr; this.checkLVal(expr); this.next(); expr = this.finishNode(node, "UpdateExpression"); } return expr; }; // Parse call, dot, and `[]`-subscript expressions. pp.parseExprSubscripts = function (refShorthandDefaultPos) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseExprAtom(refShorthandDefaultPos); if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; return this.parseSubscripts(expr, startPos, startLoc); }; pp.parseSubscripts = function (base, startPos, startLoc, noCalls) { if (Array.isArray(startPos)) { if (this.options.locations && noCalls === undefined) { // shift arguments to left by one noCalls = startLoc; // flatten startPos startLoc = startPos[1]; startPos = startPos[0]; } } for (;;) { if (this.eat(tt.dot)) { var node = this.startNodeAt(startPos, startLoc); node.object = base; node.property = this.parseIdent(true); node.computed = false; base = this.finishNode(node, "MemberExpression"); } else if (this.eat(tt.bracketL)) { var node = this.startNodeAt(startPos, startLoc); node.object = base; node.property = this.parseExpression(); node.computed = true; this.expect(tt.bracketR); base = this.finishNode(node, "MemberExpression"); } else if (!noCalls && this.eat(tt.parenL)) { var node = this.startNodeAt(startPos, startLoc); node.callee = base; node.arguments = this.parseExprList(tt.parenR, false); base = this.finishNode(node, "CallExpression"); } else if (this.type === tt.backQuote) { var node = this.startNodeAt(startPos, startLoc); node.tag = base; node.quasi = this.parseTemplate(); base = this.finishNode(node, "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.parseExprAtom = function (refShorthandDefaultPos) { var node = undefined, canBeArrow = this.potentialArrowAt == this.start; switch (this.type) { case tt._this: case tt._super: var type = this.type === tt._this ? "ThisExpression" : "Super"; node = this.startNode(); this.next(); return this.finishNode(node, type); case tt._yield: if (this.inGenerator) this.unexpected(); case tt.name: var startPos = this.start, startLoc = this.startLoc; var id = this.parseIdent(this.type !== tt.name); if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]); return id; case tt.regexp: var value = this.value; node = this.parseLiteral(value.value); node.regex = { pattern: value.pattern, flags: value.flags }; return node; case tt.num:case tt.string: return this.parseLiteral(this.value); case tt._null:case tt._true:case tt._false: node = this.startNode(); node.value = this.type === tt._null ? null : this.type === tt._true; node.raw = this.type.keyword; this.next(); return this.finishNode(node, "Literal"); case tt.parenL: return this.parseParenAndDistinguishExpression(canBeArrow); case tt.bracketL: node = this.startNode(); this.next(); // check whether this is array comprehension or regular array if (this.options.ecmaVersion >= 7 && this.type === tt._for) { return this.parseComprehension(node, false); } node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos); return this.finishNode(node, "ArrayExpression"); case tt.braceL: return this.parseObj(false, refShorthandDefaultPos); case tt._function: node = this.startNode(); this.next(); return this.parseFunction(node, false); case tt._class: return this.parseClass(this.startNode(), false); case tt._new: return this.parseNew(); case tt.backQuote: return this.parseTemplate(); default: this.unexpected(); } }; pp.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.parseParenExpression = function () { this.expect(tt.parenL); var val = this.parseExpression(); this.expect(tt.parenR); return val; }; pp.parseParenAndDistinguishExpression = function (canBeArrow) { var startPos = this.start, startLoc = this.startLoc, val = undefined; if (this.options.ecmaVersion >= 6) { this.next(); if (this.options.ecmaVersion >= 7 && this.type === tt._for) { return this.parseComprehension(this.startNodeAt(startPos, startLoc), true); } var innerStartPos = this.start, innerStartLoc = this.startLoc; var exprList = [], first = true; var refShorthandDefaultPos = { start: 0 }, spreadStart = undefined, innerParenStart = undefined; while (this.type !== tt.parenR) { first ? first = false : this.expect(tt.comma); if (this.type === tt.ellipsis) { spreadStart = this.start; exprList.push(this.parseParenItem(this.parseRest())); break; } else { if (this.type === tt.parenL && !innerParenStart) { innerParenStart = this.start; } exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem)); } } var innerEndPos = this.start, innerEndLoc = this.startLoc; this.expect(tt.parenR); if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { if (innerParenStart) this.unexpected(innerParenStart); return this.parseParenArrowList(startPos, startLoc, exprList); } if (!exprList.length) this.unexpected(this.lastTokStart); if (spreadStart) this.unexpected(spreadStart); if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start); 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.parseParenItem = function (item) { return item; }; pp.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 var empty = []; pp.parseNew = function () { var node = this.startNode(); var meta = this.parseIdent(true); if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { node.meta = meta; node.property = this.parseIdent(true); if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target"); return this.finishNode(node, "MetaProperty"); } var startPos = this.start, startLoc = this.startLoc; node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false);else node.arguments = empty; return this.finishNode(node, "NewExpression"); }; // Parse template expression. pp.parseTemplateElement = function () { var elem = this.startNode(); elem.value = { raw: this.input.slice(this.start, this.end), cooked: this.value }; this.next(); elem.tail = this.type === tt.backQuote; return this.finishNode(elem, "TemplateElement"); }; pp.parseTemplate = function () { var node = this.startNode(); this.next(); node.expressions = []; var curElt = this.parseTemplateElement(); node.quasis = [curElt]; while (!curElt.tail) { this.expect(tt.dollarBraceL); node.expressions.push(this.parseExpression()); this.expect(tt.braceR); node.quasis.push(curElt = this.parseTemplateElement()); } this.next(); return this.finishNode(node, "TemplateLiteral"); }; // Parse an object literal or binding pattern. pp.parseObj = function (isPattern, refShorthandDefaultPos) { var node = this.startNode(), first = true, propHash = {}; node.properties = []; this.next(); while (!this.eat(tt.braceR)) { if (!first) { this.expect(tt.comma); if (this.afterTrailingComma(tt.braceR)) break; } else first = false; var prop = this.startNode(), isGenerator = undefined, startPos = undefined, startLoc = undefined; if (this.options.ecmaVersion >= 6) { prop.method = false; prop.shorthand = false; if (isPattern || refShorthandDefaultPos) { startPos = this.start; startLoc = this.startLoc; } if (!isPattern) isGenerator = this.eat(tt.star); } this.parsePropertyName(prop); this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos); this.checkPropClash(prop, propHash); node.properties.push(this.finishNode(prop, "Property")); } return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); }; pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos) { if (this.eat(tt.colon)) { prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); prop.kind = "init"; } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { if (isPattern) this.unexpected(); prop.kind = "init"; prop.method = true; prop.value = this.parseMethod(isGenerator); } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != tt.comma && this.type != tt.braceR)) { if (isGenerator || isPattern) this.unexpected(); prop.kind = prop.key.name; this.parsePropertyName(prop); prop.value = this.parseMethod(false); } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { prop.kind = "init"; if (isPattern) { if (this.isKeyword(prop.key.name) || this.strict && (reservedWords.strictBind(prop.key.name) || reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name); prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); } else if (this.type === tt.eq && refShorthandDefaultPos) { if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start; prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); } else { prop.value = prop.key; } prop.shorthand = true; } else this.unexpected(); }; pp.parsePropertyName = function (prop) { if (this.options.ecmaVersion >= 6) { if (this.eat(tt.bracketL)) { prop.computed = true; prop.key = this.parseMaybeAssign(); this.expect(tt.bracketR); return prop.key; } else { prop.computed = false; } } return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true); }; // Initialize empty function node. pp.initFunction = function (node) { node.id = null; if (this.options.ecmaVersion >= 6) { node.generator = false; node.expression = false; } }; // Parse object or class method. pp.parseMethod = function (isGenerator) { var node = this.startNode(); this.initFunction(node); this.expect(tt.parenL); node.params = this.parseBindingList(tt.parenR, false, false); var allowExpressionBody = undefined; if (this.options.ecmaVersion >= 6) { node.generator = isGenerator; allowExpressionBody = true; } else { allowExpressionBody = false; } this.parseFunctionBody(node, allowExpressionBody); return this.finishNode(node, "FunctionExpression"); }; // Parse arrow function expression with given parameters. pp.parseArrowExpression = function (node, params) { this.initFunction(node); node.params = this.toAssignableList(params, true); this.parseFunctionBody(node, true); return this.finishNode(node, "ArrowFunctionExpression"); }; // Parse function body and check parameters. pp.parseFunctionBody = function (node, allowExpression) { var isExpression = allowExpression && this.type !== tt.braceL; if (isExpression) { node.body = this.parseMaybeAssign(); node.expression = true; } else { // Start a new scope with regard to labels and the `inFunction` // flag (restore them to their old value afterwards). var oldInFunc = this.inFunction, oldInGen = this.inGenerator, oldLabels = this.labels; this.inFunction = true;this.inGenerator = node.generator;this.labels = []; node.body = this.parseBlock(true); node.expression = false; this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels; } // 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 (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) { var nameHash = {}, oldStrict = this.strict; this.strict = true; if (node.id) this.checkLVal(node.id, true); for (var i = 0; i < node.params.length; i++) { this.checkLVal(node.params[i], true, nameHash); }this.strict = oldStrict; } }; // 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.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) { var elts = [], first = true; while (!this.eat(close)) { if (!first) { this.expect(tt.comma); if (allowTrailingComma && this.afterTrailingComma(close)) break; } else first = false; if (allowEmpty && this.type === tt.comma) { elts.push(null); } else { if (this.type === tt.ellipsis) elts.push(this.parseSpread(refShorthandDefaultPos));else elts.push(this.parseMaybeAssign(false, refShorthandDefaultPos)); } } return elts; }; // Parse the next token as an identifier. If `liberal` is true (used // when parsing properties), it will also convert keywords into // identifiers. pp.parseIdent = function (liberal) { var node = this.startNode(); if (liberal && this.options.allowReserved == "never") liberal = false; if (this.type === tt.name) { if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.value) || this.strict && reservedWords.strict(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1))) this.raise(this.start, "The keyword '" + this.value + "' is reserved"); node.name = this.value; } else if (liberal && this.type.keyword) { node.name = this.type.keyword; } else { this.unexpected(); } this.next(); return this.finishNode(node, "Identifier"); }; // Parses yield expression inside generator. pp.parseYield = function () { var node = this.startNode(); this.next(); if (this.type == tt.semi || this.canInsertSemicolon() || this.type != tt.star && !this.type.startsExpr) { node.delegate = false; node.argument = null; } else { node.delegate = this.eat(tt.star); node.argument = this.parseMaybeAssign(); } return this.finishNode(node, "YieldExpression"); }; // Parses array and generator comprehensions. pp.parseComprehension = function (node, isGenerator) { node.blocks = []; while (this.type === tt._for) { var block = this.startNode(); this.next(); this.expect(tt.parenL); block.left = this.parseBindingAtom(); this.checkLVal(block.left, true); this.expectContextual("of"); block.right = this.parseExpression(); this.expect(tt.parenR); node.blocks.push(this.finishNode(block, "ComprehensionBlock")); } node.filter = this.eat(tt._if) ? this.parseParenExpression() : null; node.body = this.parseExpression(); this.expect(isGenerator ? tt.parenR : tt.bracketR); node.generator = isGenerator; return this.finishNode(node, "ComprehensionExpression"); }; },{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(_dereq_,module,exports){ // Test whether a given character code starts an identifier. "use strict"; exports.isIdentifierStart = isIdentifierStart; // Test whether a given character is part of an identifier. exports.isIdentifierChar = isIdentifierChar; exports.__esModule = true; // This is a trick taken from Esprima. It turns out that, on // non-Chrome browsers, to check whether a string is in a set, a // predicate containing a big ugly `switch` statement is faster than // a regular expression, and on Chrome the two are about on par. // This function uses `eval` (non-lexical) to produce such a // predicate from a space-separated string of words. // // It starts by sorting the words by length. function makePredicate(words) { words = words.split(" "); var f = "", cats = []; out: for (var i = 0; i < words.length; ++i) { for (var j = 0; j < cats.length; ++j) { if (cats[j][0].length == words[i].length) { cats[j].push(words[i]); continue out; } }cats.push([words[i]]); } function compareTo(arr) { if (arr.length == 1) { return f += "return str === " + JSON.stringify(arr[0]) + ";"; }f += "switch(str){"; for (var i = 0; i < arr.length; ++i) { f += "case " + JSON.stringify(arr[i]) + ":"; }f += "return true}return false;"; } // When there are more than three length categories, an outer // switch first dispatches on the lengths, to save on comparisons. if (cats.length > 3) { cats.sort(function (a, b) { return b.length - a.length; }); f += "switch(str.length){"; for (var i = 0; i < cats.length; ++i) { var cat = cats[i]; f += "case " + cat[0].length + ":"; compareTo(cat); } f += "}" // Otherwise, simply generate a flat `switch` statement. ; } else { compareTo(words); } return new Function("str", f); } // Reserved word lists for various dialects of the language var reservedWords = { 3: makePredicate("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: makePredicate("class enum extends super const export import"), 6: makePredicate("enum await"), strict: makePredicate("implements interface let package private protected public sta