Best JavaScript code snippet using wpt
acorn.js
Source:acorn.js
1// Acorn is a tiny, fast JavaScript parser written in JavaScript.2//3// Acorn was written by Marijn Haverbeke and released under an MIT4// license. The Unicode regexps (for identifiers and whitespace) were5// taken from [Esprima](http://esprima.org) by Ariya Hidayat.6//7// Git repositories for Acorn are available at8//9// http://marijnhaverbeke.nl/git/acorn10// https://github.com/marijnh/acorn.git11//12// Please use the [github bug tracker][ghbt] to report issues.13//14// [ghbt]: https://github.com/marijnh/acorn/issues15//16// This file defines the main parser interface. The library also comes17// with a [error-tolerant parser][dammit] and an18// [abstract syntax tree walker][walk], defined in other files.19//20// [dammit]: acorn_loose.js21// [walk]: util/walk.js22(function(root, mod) {23 if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS24 if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD25 mod(root.acorn || (root.acorn = {})); // Plain browser env26})(this, function(exports) {27 "use strict";28 exports.version = "0.4.1";29 // The main exported interface (under `self.acorn` when in the30 // browser) is a `parse` function that takes a code string and31 // returns an abstract syntax tree as specified by [Mozilla parser32 // API][api], with the caveat that the SpiderMonkey-specific syntax33 // (`let`, `yield`, inline XML, etc) is not recognized.34 //35 // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API36 var options, input, inputLen, sourceFile;37 exports.parse = function(inpt, opts) {38 input = String(inpt); inputLen = input.length;39 setOptions(opts);40 initTokenState();41 return parseTopLevel(options.program);42 };43 // A second optional argument can be given to further configure44 // the parser process. These options are recognized:45 var defaultOptions = exports.defaultOptions = {46 // `ecmaVersion` indicates the ECMAScript version to parse. Must47 // be either 3 or 5. This48 // influences support for strict mode, the set of reserved words, and49 // support for getters and setter.50 ecmaVersion: 5,51 // Turn on `strictSemicolons` to prevent the parser from doing52 // automatic semicolon insertion.53 strictSemicolons: false,54 // When `allowTrailingCommas` is false, the parser will not allow55 // trailing commas in array and object literals.56 allowTrailingCommas: true,57 // By default, reserved words are not enforced. Enable58 // `forbidReserved` to enforce them.59 forbidReserved: false,60 // When `locations` is on, `loc` properties holding objects with61 // `start` and `end` properties in `{line, column}` form (with62 // line being 1-based and column 0-based) will be attached to the63 // nodes.64 locations: false,65 // A function can be passed as `onComment` option, which will66 // cause Acorn to call that function with `(block, text, start,67 // end)` parameters whenever a comment is skipped. `block` is a68 // boolean indicating whether this is a block (`/* */`) comment,69 // `text` is the content of the comment, and `start` and `end` are70 // character offsets that denote the start and end of the comment.71 // When the `locations` option is on, two more parameters are72 // passed, the full `{line, column}` locations of the start and73 // end of the comments.74 onComment: null,75 // Nodes have their start and end characters offsets recorded in76 // `start` and `end` properties (directly on the node, rather than77 // the `loc` object, which holds line/column data. To also add a78 // [semi-standardized][range] `range` property holding a `[start,79 // end]` array with the same numbers, set the `ranges` option to80 // `true`.81 //82 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=74567883 ranges: false,84 // It is possible to parse multiple files into a single AST by85 // passing the tree produced by parsing the first file as86 // `program` option in subsequent parses. This will add the87 // toplevel forms of the parsed file to the `Program` (top) node88 // of an existing parse tree.89 program: null,90 // When `location` is on, you can pass this to record the source91 // file in every node's `loc` object.92 sourceFile: null,93 // This value, if given, is stored in every node, whether94 // `location` is on or off.95 directSourceFile: null96 };97 function setOptions(opts) {98 options = opts || {};99 for (var opt in defaultOptions) if (!Object.prototype.hasOwnProperty.call(options, opt))100 options[opt] = defaultOptions[opt];101 sourceFile = options.sourceFile || null;102 }103 // The `getLineInfo` function is mostly useful when the104 // `locations` option is off (for performance reasons) and you105 // want to find the line/column position for a given character106 // offset. `input` should be the code string that the offset refers107 // into.108 var getLineInfo = exports.getLineInfo = function(input, offset) {109 for (var line = 1, cur = 0;;) {110 lineBreak.lastIndex = cur;111 var match = lineBreak.exec(input);112 if (match && match.index < offset) {113 ++line;114 cur = match.index + match[0].length;115 } else break;116 }117 return {line: line, column: offset - cur};118 };119 // Acorn is organized as a tokenizer and a recursive-descent parser.120 // The `tokenize` export provides an interface to the tokenizer.121 // Because the tokenizer is optimized for being efficiently used by122 // the Acorn parser itself, this interface is somewhat crude and not123 // very modular. Performing another parse or call to `tokenize` will124 // reset the internal state, and invalidate existing tokenizers.125 exports.tokenize = function(inpt, opts) {126 input = String(inpt); inputLen = input.length;127 setOptions(opts);128 initTokenState();129 var t = {};130 function getToken(forceRegexp) {131 readToken(forceRegexp);132 t.start = tokStart; t.end = tokEnd;133 t.startLoc = tokStartLoc; t.endLoc = tokEndLoc;134 t.type = tokType; t.value = tokVal;135 return t;136 }137 getToken.jumpTo = function(pos, reAllowed) {138 tokPos = pos;139 if (options.locations) {140 tokCurLine = 1;141 tokLineStart = lineBreak.lastIndex = 0;142 var match;143 while ((match = lineBreak.exec(input)) && match.index < pos) {144 ++tokCurLine;145 tokLineStart = match.index + match[0].length;146 }147 }148 tokRegexpAllowed = reAllowed;149 skipSpace();150 };151 return getToken;152 };153 // State is kept in (closure-)global variables. We already saw the154 // `options`, `input`, and `inputLen` variables above.155 // The current position of the tokenizer in the input.156 var tokPos;157 // The start and end offsets of the current token.158 var tokStart, tokEnd;159 // When `options.locations` is true, these hold objects160 // containing the tokens start and end line/column pairs.161 var tokStartLoc, tokEndLoc;162 // The type and value of the current token. Token types are objects,163 // named by variables against which they can be compared, and164 // holding properties that describe them (indicating, for example,165 // the precedence of an infix operator, and the original name of a166 // keyword token). The kind of value that's held in `tokVal` depends167 // on the type of the token. For literals, it is the literal value,168 // for operators, the operator name, and so on.169 var tokType, tokVal;170 // Interal state for the tokenizer. To distinguish between division171 // operators and regular expressions, it remembers whether the last172 // token was one that is allowed to be followed by an expression.173 // (If it is, a slash is probably a regexp, if it isn't it's a174 // division operator. See the `parseStatement` function for a175 // caveat.)176 var tokRegexpAllowed;177 // When `options.locations` is true, these are used to keep178 // track of the current line, and know when a new line has been179 // entered.180 var tokCurLine, tokLineStart;181 // These store the position of the previous token, which is useful182 // when finishing a node and assigning its `end` position.183 var lastStart, lastEnd, lastEndLoc;184 // This is the parser's state. `inFunction` is used to reject185 // `return` statements outside of functions, `labels` to verify that186 // `break` and `continue` have somewhere to jump to, and `strict`187 // indicates whether strict mode is on.188 var inFunction, labels, strict;189 // This function is used to raise exceptions on parse errors. It190 // takes an offset integer (into the current `input`) to indicate191 // the location of the error, attaches the position to the end192 // of the error message, and then raises a `SyntaxError` with that193 // message.194 function raise(pos, message) {195 var loc = getLineInfo(input, pos);196 message += " (" + loc.line + ":" + loc.column + ")";197 var err = new SyntaxError(message);198 err.pos = pos; err.loc = loc; err.raisedAt = tokPos;199 throw err;200 }201 // Reused empty array added for node fields that are always empty.202 var empty = [];203 // ## Token types204 // The assignment of fine-grained, information-carrying type objects205 // allows the tokenizer to store the information it has about a206 // token in a way that is very cheap for the parser to look up.207 // All token type variables start with an underscore, to make them208 // easy to recognize.209 // These are the general types. The `type` property is only used to210 // make them recognizeable when debugging.211 var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"};212 var _name = {type: "name"}, _eof = {type: "eof"};213 // Keyword tokens. The `keyword` property (also used in keyword-like214 // operators) indicates that the token originated from an215 // identifier-like word, which is used when parsing property names.216 //217 // The `beforeExpr` property is used to disambiguate between regular218 // expressions and divisions. It is set on all token types that can219 // be followed by an expression (thus, a slash after them would be a220 // regular expression).221 //222 // `isLoop` marks a keyword as starting a loop, which is important223 // to know when parsing a label, in order to allow or disallow224 // continue jumps to that label.225 var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"};226 var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"};227 var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true};228 var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"};229 var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"};230 var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"};231 var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};232 var _this = {keyword: "this"};233 // The keywords that denote values.234 var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};235 var _false = {keyword: "false", atomValue: false};236 // Some keywords are treated as regular operators. `in` sometimes237 // (when parsing `for`) needs to be tested against specifically, so238 // we assign a variable name to it for quick comparing.239 var _in = {keyword: "in", binop: 7, beforeExpr: true};240 // Map keyword names to token types.241 var keywordTypes = {"break": _break, "case": _case, "catch": _catch,242 "continue": _continue, "debugger": _debugger, "default": _default,243 "do": _do, "else": _else, "finally": _finally, "for": _for,244 "function": _function, "if": _if, "return": _return, "switch": _switch,245 "throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with,246 "null": _null, "true": _true, "false": _false, "new": _new, "in": _in,247 "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this,248 "typeof": {keyword: "typeof", prefix: true, beforeExpr: true},249 "void": {keyword: "void", prefix: true, beforeExpr: true},250 "delete": {keyword: "delete", prefix: true, beforeExpr: true}};251 // Punctuation token types. Again, the `type` property is purely for debugging.252 var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};253 var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};254 var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};255 var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};256 // Operators. These carry several kinds of properties to help the257 // parser use them properly (the presence of these properties is258 // what categorizes them as operators).259 //260 // `binop`, when present, specifies that this operator is a binary261 // operator, and will refer to its precedence.262 //263 // `prefix` and `postfix` mark the operator as a prefix or postfix264 // unary operator. `isUpdate` specifies that the node produced by265 // the operator should be of type UpdateExpression rather than266 // simply UnaryExpression (`++` and `--`).267 //268 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as269 // binary operators with a very low precedence, that should result270 // in AssignmentExpression nodes.271 var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true};272 var _assign = {isAssign: true, beforeExpr: true};273 var _incDec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true};274 var _logicalOR = {binop: 1, beforeExpr: true};275 var _logicalAND = {binop: 2, beforeExpr: true};276 var _bitwiseOR = {binop: 3, beforeExpr: true};277 var _bitwiseXOR = {binop: 4, beforeExpr: true};278 var _bitwiseAND = {binop: 5, beforeExpr: true};279 var _equality = {binop: 6, beforeExpr: true};280 var _relational = {binop: 7, beforeExpr: true};281 var _bitShift = {binop: 8, beforeExpr: true};282 var _plusMin = {binop: 9, prefix: true, beforeExpr: true};283 var _multiplyModulo = {binop: 10, beforeExpr: true};284 // Provide access to the token types for external users of the285 // tokenizer.286 exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR,287 parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,288 dot: _dot, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof,289 num: _num, regexp: _regexp, string: _string};290 for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];291 // This is a trick taken from Esprima. It turns out that, on292 // non-Chrome browsers, to check whether a string is in a set, a293 // predicate containing a big ugly `switch` statement is faster than294 // a regular expression, and on Chrome the two are about on par.295 // This function uses `eval` (non-lexical) to produce such a296 // predicate from a space-separated string of words.297 //298 // It starts by sorting the words by length.299 function makePredicate(words) {300 words = words.split(" ");301 var f = "", cats = [];302 out: for (var i = 0; i < words.length; ++i) {303 for (var j = 0; j < cats.length; ++j)304 if (cats[j][0].length == words[i].length) {305 cats[j].push(words[i]);306 continue out;307 }308 cats.push([words[i]]);309 }310 function compareTo(arr) {311 if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";312 f += "switch(str){";313 for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";314 f += "return true}return false;";315 }316 // When there are more than three length categories, an outer317 // switch first dispatches on the lengths, to save on comparisons.318 if (cats.length > 3) {319 cats.sort(function(a, b) {return b.length - a.length;});320 f += "switch(str.length){";321 for (var i = 0; i < cats.length; ++i) {322 var cat = cats[i];323 f += "case " + cat[0].length + ":";324 compareTo(cat);325 }326 f += "}";327 // Otherwise, simply generate a flat `switch` statement.328 } else {329 compareTo(words);330 }331 return new Function("str", f);332 }333 // The ECMAScript 3 reserved word list.334 var isReservedWord3 = 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");335 // ECMAScript 5 reserved words.336 var isReservedWord5 = makePredicate("class enum extends super const export import");337 // The additional reserved words in strict mode.338 var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");339 // The forbidden variable names in strict mode.340 var isStrictBadIdWord = makePredicate("eval arguments");341 // And the keywords.342 var isKeyword = makePredicate("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");343 // ## Character categories344 // Big ugly regular expressions that match characters in the345 // whitespace, identifier, and identifier-start categories. These346 // are only applied when a character is found to actually have a347 // code point above 128.348 var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;349 var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";350 var nonASCIIidentifierChars = "\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\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\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";351 var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");352 var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");353 // Whether a single character denotes a newline.354 var newline = /[\n\r\u2028\u2029]/;355 // Matches a whole line break (where CRLF is considered a single356 // line break). Used to count lines.357 var lineBreak = /\r\n|[\n\r\u2028\u2029]/g;358 // Test whether a given character code starts an identifier.359 var isIdentifierStart = exports.isIdentifierStart = function(code) {360 if (code < 65) return code === 36;361 if (code < 91) return true;362 if (code < 97) return code === 95;363 if (code < 123)return true;364 return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));365 };366 // Test whether a given character is part of an identifier.367 var isIdentifierChar = exports.isIdentifierChar = function(code) {368 if (code < 48) return code === 36;369 if (code < 58) return true;370 if (code < 65) return false;371 if (code < 91) return true;372 if (code < 97) return code === 95;373 if (code < 123)return true;374 return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));375 };376 // ## Tokenizer377 // These are used when `options.locations` is on, for the378 // `tokStartLoc` and `tokEndLoc` properties.379 function line_loc_t() {380 this.line = tokCurLine;381 this.column = tokPos - tokLineStart;382 }383 // Reset the token state. Used at the start of a parse.384 function initTokenState() {385 tokCurLine = 1;386 tokPos = tokLineStart = 0;387 tokRegexpAllowed = true;388 skipSpace();389 }390 // Called at the end of every token. Sets `tokEnd`, `tokVal`, and391 // `tokRegexpAllowed`, and skips the space after the token, so that392 // the next one's `tokStart` will point at the right position.393 function finishToken(type, val) {394 tokEnd = tokPos;395 if (options.locations) tokEndLoc = new line_loc_t;396 tokType = type;397 skipSpace();398 tokVal = val;399 tokRegexpAllowed = type.beforeExpr;400 }401 function skipBlockComment() {402 var startLoc = options.onComment && options.locations && new line_loc_t;403 var start = tokPos, end = input.indexOf("*/", tokPos += 2);404 if (end === -1) raise(tokPos - 2, "Unterminated comment");405 tokPos = end + 2;406 if (options.locations) {407 lineBreak.lastIndex = start;408 var match;409 while ((match = lineBreak.exec(input)) && match.index < tokPos) {410 ++tokCurLine;411 tokLineStart = match.index + match[0].length;412 }413 }414 if (options.onComment)415 options.onComment(true, input.slice(start + 2, end), start, tokPos,416 startLoc, options.locations && new line_loc_t);417 }418 function skipLineComment() {419 var start = tokPos;420 var startLoc = options.onComment && options.locations && new line_loc_t;421 var ch = input.charCodeAt(tokPos+=2);422 while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {423 ++tokPos;424 ch = input.charCodeAt(tokPos);425 }426 if (options.onComment)427 options.onComment(false, input.slice(start + 2, tokPos), start, tokPos,428 startLoc, options.locations && new line_loc_t);429 }430 // Called at the start of the parse and after every token. Skips431 // whitespace and comments, and.432 function skipSpace() {433 while (tokPos < inputLen) {434 var ch = input.charCodeAt(tokPos);435 if (ch === 32) { // ' '436 ++tokPos;437 } else if (ch === 13) {438 ++tokPos;439 var next = input.charCodeAt(tokPos);440 if (next === 10) {441 ++tokPos;442 }443 if (options.locations) {444 ++tokCurLine;445 tokLineStart = tokPos;446 }447 } else if (ch === 10 || ch === 8232 || ch === 8233) {448 ++tokPos;449 if (options.locations) {450 ++tokCurLine;451 tokLineStart = tokPos;452 }453 } else if (ch > 8 && ch < 14) {454 ++tokPos;455 } else if (ch === 47) { // '/'456 var next = input.charCodeAt(tokPos + 1);457 if (next === 42) { // '*'458 skipBlockComment();459 } else if (next === 47) { // '/'460 skipLineComment();461 } else break;462 } else if (ch === 160) { // '\xa0'463 ++tokPos;464 } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {465 ++tokPos;466 } else {467 break;468 }469 }470 }471 // ### Token reading472 // This is the function that is called to fetch the next token. It473 // is somewhat obscure, because it works in character codes rather474 // than characters, and because operator parsing has been inlined475 // into it.476 //477 // All in the name of speed.478 //479 // The `forceRegexp` parameter is used in the one case where the480 // `tokRegexpAllowed` trick does not work. See `parseStatement`.481 function readToken_dot() {482 var next = input.charCodeAt(tokPos + 1);483 if (next >= 48 && next <= 57) return readNumber(true);484 ++tokPos;485 return finishToken(_dot);486 }487 function readToken_slash() { // '/'488 var next = input.charCodeAt(tokPos + 1);489 if (tokRegexpAllowed) {++tokPos; return readRegexp();}490 if (next === 61) return finishOp(_assign, 2);491 return finishOp(_slash, 1);492 }493 function readToken_mult_modulo() { // '%*'494 var next = input.charCodeAt(tokPos + 1);495 if (next === 61) return finishOp(_assign, 2);496 return finishOp(_multiplyModulo, 1);497 }498 function readToken_pipe_amp(code) { // '|&'499 var next = input.charCodeAt(tokPos + 1);500 if (next === code) return finishOp(code === 124 ? _logicalOR : _logicalAND, 2);501 if (next === 61) return finishOp(_assign, 2);502 return finishOp(code === 124 ? _bitwiseOR : _bitwiseAND, 1);503 }504 function readToken_caret() { // '^'505 var next = input.charCodeAt(tokPos + 1);506 if (next === 61) return finishOp(_assign, 2);507 return finishOp(_bitwiseXOR, 1);508 }509 function readToken_plus_min(code) { // '+-'510 var next = input.charCodeAt(tokPos + 1);511 if (next === code) {512 if (next == 45 && input.charCodeAt(tokPos + 2) == 62 &&513 newline.test(input.slice(lastEnd, tokPos))) {514 // A `-->` line comment515 tokPos += 3;516 skipLineComment();517 skipSpace();518 return readToken();519 }520 return finishOp(_incDec, 2);521 }522 if (next === 61) return finishOp(_assign, 2);523 return finishOp(_plusMin, 1);524 }525 function readToken_lt_gt(code) { // '<>'526 var next = input.charCodeAt(tokPos + 1);527 var size = 1;528 if (next === code) {529 size = code === 62 && input.charCodeAt(tokPos + 2) === 62 ? 3 : 2;530 if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1);531 return finishOp(_bitShift, size);532 }533 if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 &&534 input.charCodeAt(tokPos + 3) == 45) {535 // `<!--`, an XML-style comment that should be interpreted as a line comment536 tokPos += 4;537 skipLineComment();538 skipSpace();539 return readToken();540 }541 if (next === 61)542 size = input.charCodeAt(tokPos + 2) === 61 ? 3 : 2;543 return finishOp(_relational, size);544 }545 function readToken_eq_excl(code) { // '=!'546 var next = input.charCodeAt(tokPos + 1);547 if (next === 61) return finishOp(_equality, input.charCodeAt(tokPos + 2) === 61 ? 3 : 2);548 return finishOp(code === 61 ? _eq : _prefix, 1);549 }550 function getTokenFromCode(code) {551 switch(code) {552 // The interpretation of a dot depends on whether it is followed553 // by a digit.554 case 46: // '.'555 return readToken_dot();556 // Punctuation tokens.557 case 40: ++tokPos; return finishToken(_parenL);558 case 41: ++tokPos; return finishToken(_parenR);559 case 59: ++tokPos; return finishToken(_semi);560 case 44: ++tokPos; return finishToken(_comma);561 case 91: ++tokPos; return finishToken(_bracketL);562 case 93: ++tokPos; return finishToken(_bracketR);563 case 123: ++tokPos; return finishToken(_braceL);564 case 125: ++tokPos; return finishToken(_braceR);565 case 58: ++tokPos; return finishToken(_colon);566 case 63: ++tokPos; return finishToken(_question);567 // '0x' is a hexadecimal number.568 case 48: // '0'569 var next = input.charCodeAt(tokPos + 1);570 if (next === 120 || next === 88) return readHexNumber();571 // Anything else beginning with a digit is an integer, octal572 // number, or float.573 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9574 return readNumber(false);575 // Quotes produce strings.576 case 34: case 39: // '"', "'"577 return readString(code);578 // Operators are parsed inline in tiny state machines. '=' (61) is579 // often referred to. `finishOp` simply skips the amount of580 // characters it is given as second argument, and returns a token581 // of the type given by its first argument.582 case 47: // '/'583 return readToken_slash(code);584 case 37: case 42: // '%*'585 return readToken_mult_modulo();586 case 124: case 38: // '|&'587 return readToken_pipe_amp(code);588 case 94: // '^'589 return readToken_caret();590 case 43: case 45: // '+-'591 return readToken_plus_min(code);592 case 60: case 62: // '<>'593 return readToken_lt_gt(code);594 case 61: case 33: // '=!'595 return readToken_eq_excl(code);596 case 126: // '~'597 return finishOp(_prefix, 1);598 }599 return false;600 }601 function readToken(forceRegexp) {602 if (!forceRegexp) tokStart = tokPos;603 else tokPos = tokStart + 1;604 if (options.locations) tokStartLoc = new line_loc_t;605 if (forceRegexp) return readRegexp();606 if (tokPos >= inputLen) return finishToken(_eof);607 var code = input.charCodeAt(tokPos);608 // Identifier or keyword. '\uXXXX' sequences are allowed in609 // identifiers, so '\' also dispatches to that.610 if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord();611 var tok = getTokenFromCode(code);612 if (tok === false) {613 // If we are here, we either found a non-ASCII identifier614 // character, or something that's entirely disallowed.615 var ch = String.fromCharCode(code);616 if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord();617 raise(tokPos, "Unexpected character '" + ch + "'");618 }619 return tok;620 }621 function finishOp(type, size) {622 var str = input.slice(tokPos, tokPos + size);623 tokPos += size;624 finishToken(type, str);625 }626 // Parse a regular expression. Some context-awareness is necessary,627 // since a '/' inside a '[]' set does not end the expression.628 function readRegexp() {629 var content = "", escaped, inClass, start = tokPos;630 for (;;) {631 if (tokPos >= inputLen) raise(start, "Unterminated regular expression");632 var ch = input.charAt(tokPos);633 if (newline.test(ch)) raise(start, "Unterminated regular expression");634 if (!escaped) {635 if (ch === "[") inClass = true;636 else if (ch === "]" && inClass) inClass = false;637 else if (ch === "/" && !inClass) break;638 escaped = ch === "\\";639 } else escaped = false;640 ++tokPos;641 }642 var content = input.slice(start, tokPos);643 ++tokPos;644 // Need to use `readWord1` because '\uXXXX' sequences are allowed645 // here (don't ask).646 var mods = readWord1();647 if (mods && !/^[gmsiy]*$/.test(mods)) raise(start, "Invalid regexp flag");648 return finishToken(_regexp, new RegExp(content, mods));649 }650 // Read an integer in the given radix. Return null if zero digits651 // were read, the integer value otherwise. When `len` is given, this652 // will return `null` unless the integer has exactly `len` digits.653 function readInt(radix, len) {654 var start = tokPos, total = 0;655 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {656 var code = input.charCodeAt(tokPos), val;657 if (code >= 97) val = code - 97 + 10; // a658 else if (code >= 65) val = code - 65 + 10; // A659 else if (code >= 48 && code <= 57) val = code - 48; // 0-9660 else val = Infinity;661 if (val >= radix) break;662 ++tokPos;663 total = total * radix + val;664 }665 if (tokPos === start || len != null && tokPos - start !== len) return null;666 return total;667 }668 function readHexNumber() {669 tokPos += 2; // 0x670 var val = readInt(16);671 if (val == null) raise(tokStart + 2, "Expected hexadecimal number");672 if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");673 return finishToken(_num, val);674 }675 // Read an integer, octal integer, or floating-point number.676 function readNumber(startsWithDot) {677 var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48;678 if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number");679 if (input.charCodeAt(tokPos) === 46) {680 ++tokPos;681 readInt(10);682 isFloat = true;683 }684 var next = input.charCodeAt(tokPos);685 if (next === 69 || next === 101) { // 'eE'686 next = input.charCodeAt(++tokPos);687 if (next === 43 || next === 45) ++tokPos; // '+-'688 if (readInt(10) === null) raise(start, "Invalid number");689 isFloat = true;690 }691 if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");692 var str = input.slice(start, tokPos), val;693 if (isFloat) val = parseFloat(str);694 else if (!octal || str.length === 1) val = parseInt(str, 10);695 else if (/[89]/.test(str) || strict) raise(start, "Invalid number");696 else val = parseInt(str, 8);697 return finishToken(_num, val);698 }699 // Read a string value, interpreting backslash-escapes.700 function readString(quote) {701 tokPos++;702 var out = "";703 for (;;) {704 if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");705 var ch = input.charCodeAt(tokPos);706 if (ch === quote) {707 ++tokPos;708 return finishToken(_string, out);709 }710 if (ch === 92) { // '\'711 ch = input.charCodeAt(++tokPos);712 var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3));713 if (octal) octal = octal[0];714 while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);715 if (octal === "0") octal = null;716 ++tokPos;717 if (octal) {718 if (strict) raise(tokPos - 2, "Octal literal in strict mode");719 out += String.fromCharCode(parseInt(octal, 8));720 tokPos += octal.length - 1;721 } else {722 switch (ch) {723 case 110: out += "\n"; break; // 'n' -> '\n'724 case 114: out += "\r"; break; // 'r' -> '\r'725 case 120: out += String.fromCharCode(readHexChar(2)); break; // 'x'726 case 117: out += String.fromCharCode(readHexChar(4)); break; // 'u'727 case 85: out += String.fromCharCode(readHexChar(8)); break; // 'U'728 case 116: out += "\t"; break; // 't' -> '\t'729 case 98: out += "\b"; break; // 'b' -> '\b'730 case 118: out += "\u000b"; break; // 'v' -> '\u000b'731 case 102: out += "\f"; break; // 'f' -> '\f'732 case 48: out += "\0"; break; // 0 -> '\0'733 case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'734 case 10: // ' \n'735 if (options.locations) { tokLineStart = tokPos; ++tokCurLine; }736 break;737 default: out += String.fromCharCode(ch); break;738 }739 }740 } else {741 if (ch === 13 || ch === 10 || ch === 8232 || ch === 8233) raise(tokStart, "Unterminated string constant");742 out += String.fromCharCode(ch); // '\'743 ++tokPos;744 }745 }746 }747 // Used to read character escape sequences ('\x', '\u', '\U').748 function readHexChar(len) {749 var n = readInt(16, len);750 if (n === null) raise(tokStart, "Bad character escape sequence");751 return n;752 }753 // Used to signal to callers of `readWord1` whether the word754 // contained any escape sequences. This is needed because words with755 // escape sequences must not be interpreted as keywords.756 var containsEsc;757 // Read an identifier, and return it as a string. Sets `containsEsc`758 // to whether the word contained a '\u' escape.759 //760 // Only builds up the word character-by-character when it actually761 // containeds an escape, as a micro-optimization.762 function readWord1() {763 containsEsc = false;764 var word, first = true, start = tokPos;765 for (;;) {766 var ch = input.charCodeAt(tokPos);767 if (isIdentifierChar(ch)) {768 if (containsEsc) word += input.charAt(tokPos);769 ++tokPos;770 } else if (ch === 92) { // "\"771 if (!containsEsc) word = input.slice(start, tokPos);772 containsEsc = true;773 if (input.charCodeAt(++tokPos) != 117) // "u"774 raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");775 ++tokPos;776 var esc = readHexChar(4);777 var escStr = String.fromCharCode(esc);778 if (!escStr) raise(tokPos - 1, "Invalid Unicode escape");779 if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))780 raise(tokPos - 4, "Invalid Unicode escape");781 word += escStr;782 } else {783 break;784 }785 first = false;786 }787 return containsEsc ? word : input.slice(start, tokPos);788 }789 // Read an identifier or keyword token. Will check for reserved790 // words when necessary.791 function readWord() {792 var word = readWord1();793 var type = _name;794 if (!containsEsc) {795 if (isKeyword(word)) type = keywordTypes[word];796 else if (options.forbidReserved &&797 (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(word) ||798 strict && isStrictReservedWord(word))799 raise(tokStart, "The keyword '" + word + "' is reserved");800 }801 return finishToken(type, word);802 }803 // ## Parser804 // A recursive descent parser operates by defining functions for all805 // syntactic elements, and recursively calling those, each function806 // advancing the input stream and returning an AST node. Precedence807 // of constructs (for example, the fact that `!x[1]` means `!(x[1])`808 // instead of `(!x)[1]` is handled by the fact that the parser809 // function that parses unary prefix operators is called first, and810 // in turn calls the function that parses `[]` subscripts â that811 // way, it'll receive the node for `x[1]` already parsed, and wraps812 // *that* in the unary operator node.813 //814 // Acorn uses an [operator precedence parser][opp] to handle binary815 // operator precedence, because it is much more compact than using816 // the technique outlined above, which uses different, nesting817 // functions to specify precedence, for all of the ten binary818 // precedence levels that JavaScript defines.819 //820 // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser821 // ### Parser utilities822 // Continue to the next token.823 function next() {824 lastStart = tokStart;825 lastEnd = tokEnd;826 lastEndLoc = tokEndLoc;827 readToken();828 }829 // Enter strict mode. Re-reads the next token to please pedantic830 // tests ("use strict"; 010; -- should fail).831 function setStrict(strct) {832 strict = strct;833 tokPos = lastEnd;834 if (options.locations) {835 while (tokPos < tokLineStart) {836 tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1;837 --tokCurLine;838 }839 }840 skipSpace();841 readToken();842 }843 // Start an AST node, attaching a start offset.844 function node_t() {845 this.type = null;846 this.start = tokStart;847 this.end = null;848 }849 function node_loc_t() {850 this.start = tokStartLoc;851 this.end = null;852 if (sourceFile !== null) this.source = sourceFile;853 }854 function startNode() {855 var node = new node_t();856 if (options.locations)857 node.loc = new node_loc_t();858 if (options.directSourceFile)859 node.sourceFile = options.directSourceFile;860 if (options.ranges)861 node.range = [tokStart, 0];862 return node;863 }864 // Start a node whose start offset information should be based on865 // the start of another node. For example, a binary operator node is866 // only started after its left-hand side has already been parsed.867 function startNodeFrom(other) {868 var node = new node_t();869 node.start = other.start;870 if (options.locations) {871 node.loc = new node_loc_t();872 node.loc.start = other.loc.start;873 }874 if (options.ranges)875 node.range = [other.range[0], 0];876 return node;877 }878 // Finish an AST node, adding `type` and `end` properties.879 function finishNode(node, type) {880 node.type = type;881 node.end = lastEnd;882 if (options.locations)883 node.loc.end = lastEndLoc;884 if (options.ranges)885 node.range[1] = lastEnd;886 return node;887 }888 // Test whether a statement node is the string literal `"use strict"`.889 function isUseStrict(stmt) {890 return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" &&891 stmt.expression.type === "Literal" && stmt.expression.value === "use strict";892 }893 // Predicate that tests whether the next token is of the given894 // type, and if yes, consumes it as a side effect.895 function eat(type) {896 if (tokType === type) {897 next();898 return true;899 }900 }901 // Test whether a semicolon can be inserted at the current position.902 function canInsertSemicolon() {903 return !options.strictSemicolons &&904 (tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart)));905 }906 // Consume a semicolon, or, failing that, see if we are allowed to907 // pretend that there is a semicolon at this position.908 function semicolon() {909 if (!eat(_semi) && !canInsertSemicolon()) unexpected();910 }911 // Expect a token of a given type. If found, consume it, otherwise,912 // raise an unexpected token error.913 function expect(type) {914 if (tokType === type) next();915 else unexpected();916 }917 // Raise an unexpected token error.918 function unexpected() {919 raise(tokStart, "Unexpected token");920 }921 // Verify that a node is an lval â something that can be assigned922 // to.923 function checkLVal(expr) {924 if (expr.type !== "Identifier" && expr.type !== "MemberExpression")925 raise(expr.start, "Assigning to rvalue");926 if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name))927 raise(expr.start, "Assigning to " + expr.name + " in strict mode");928 }929 // ### Statement parsing930 // Parse a program. Initializes the parser, reads any number of931 // statements, and wraps them in a Program node. Optionally takes a932 // `program` argument. If present, the statements will be appended933 // to its body instead of creating a new node.934 function parseTopLevel(program) {935 lastStart = lastEnd = tokPos;936 if (options.locations) lastEndLoc = new line_loc_t;937 inFunction = strict = null;938 labels = [];939 readToken();940 var node = program || startNode(), first = true;941 if (!program) node.body = [];942 while (tokType !== _eof) {943 var stmt = parseStatement();944 node.body.push(stmt);945 if (first && isUseStrict(stmt)) setStrict(true);946 first = false;947 }948 return finishNode(node, "Program");949 }950 var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};951 // Parse a single statement.952 //953 // If expecting a statement and finding a slash operator, parse a954 // regular expression literal. This is to handle cases like955 // `if (foo) /blah/.exec(foo);`, where looking at the previous token956 // does not help.957 function parseStatement() {958 if (tokType === _slash || tokType === _assign && tokVal == "/=")959 readToken(true);960 var starttype = tokType, node = startNode();961 // Most types of statements are recognized by the keyword they962 // start with. Many are trivial to parse, some require a bit of963 // complexity.964 switch (starttype) {965 case _break: case _continue:966 next();967 var isBreak = starttype === _break;968 if (eat(_semi) || canInsertSemicolon()) node.label = null;969 else if (tokType !== _name) unexpected();970 else {971 node.label = parseIdent();972 semicolon();973 }974 // Verify that there is an actual destination to break or975 // continue to.976 for (var i = 0; i < labels.length; ++i) {977 var lab = labels[i];978 if (node.label == null || lab.name === node.label.name) {979 if (lab.kind != null && (isBreak || lab.kind === "loop")) break;980 if (node.label && isBreak) break;981 }982 }983 if (i === labels.length) raise(node.start, "Unsyntactic " + starttype.keyword);984 return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");985 case _debugger:986 next();987 semicolon();988 return finishNode(node, "DebuggerStatement");989 case _do:990 next();991 labels.push(loopLabel);992 node.body = parseStatement();993 labels.pop();994 expect(_while);995 node.test = parseParenExpression();996 semicolon();997 return finishNode(node, "DoWhileStatement");998 // Disambiguating between a `for` and a `for`/`in` loop is999 // non-trivial. Basically, we have to parse the init `var`1000 // statement or expression, disallowing the `in` operator (see1001 // the second parameter to `parseExpression`), and then check1002 // whether the next token is `in`. When there is no init part1003 // (semicolon immediately after the opening parenthesis), it is1004 // a regular `for` loop.1005 case _for:1006 next();1007 labels.push(loopLabel);1008 expect(_parenL);1009 if (tokType === _semi) return parseFor(node, null);1010 if (tokType === _var) {1011 var init = startNode();1012 next();1013 parseVar(init, true);1014 finishNode(init, "VariableDeclaration");1015 if (init.declarations.length === 1 && eat(_in))1016 return parseForIn(node, init);1017 return parseFor(node, init);1018 }1019 var init = parseExpression(false, true);1020 if (eat(_in)) {checkLVal(init); return parseForIn(node, init);}1021 return parseFor(node, init);1022 case _function:1023 next();1024 return parseFunction(node, true);1025 case _if:1026 next();1027 node.test = parseParenExpression();1028 node.consequent = parseStatement();1029 node.alternate = eat(_else) ? parseStatement() : null;1030 return finishNode(node, "IfStatement");1031 case _return:1032 if (!inFunction) raise(tokStart, "'return' outside of function");1033 next();1034 // In `return` (and `break`/`continue`), the keywords with1035 // optional arguments, we eagerly look for a semicolon or the1036 // possibility to insert one.1037 if (eat(_semi) || canInsertSemicolon()) node.argument = null;1038 else { node.argument = parseExpression(); semicolon(); }1039 return finishNode(node, "ReturnStatement");1040 case _switch:1041 next();1042 node.discriminant = parseParenExpression();1043 node.cases = [];1044 expect(_braceL);1045 labels.push(switchLabel);1046 // Statements under must be grouped (by label) in SwitchCase1047 // nodes. `cur` is used to keep the node that we are currently1048 // adding statements to.1049 for (var cur, sawDefault; tokType != _braceR;) {1050 if (tokType === _case || tokType === _default) {1051 var isCase = tokType === _case;1052 if (cur) finishNode(cur, "SwitchCase");1053 node.cases.push(cur = startNode());1054 cur.consequent = [];1055 next();1056 if (isCase) cur.test = parseExpression();1057 else {1058 if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;1059 cur.test = null;1060 }1061 expect(_colon);1062 } else {1063 if (!cur) unexpected();1064 cur.consequent.push(parseStatement());1065 }1066 }1067 if (cur) finishNode(cur, "SwitchCase");1068 next(); // Closing brace1069 labels.pop();1070 return finishNode(node, "SwitchStatement");1071 case _throw:1072 next();1073 if (newline.test(input.slice(lastEnd, tokStart)))1074 raise(lastEnd, "Illegal newline after throw");1075 node.argument = parseExpression();1076 semicolon();1077 return finishNode(node, "ThrowStatement");1078 case _try:1079 next();1080 node.block = parseBlock();1081 node.handler = null;1082 if (tokType === _catch) {1083 var clause = startNode();1084 next();1085 expect(_parenL);1086 clause.param = parseIdent();1087 if (strict && isStrictBadIdWord(clause.param.name))1088 raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");1089 expect(_parenR);1090 clause.guard = null;1091 clause.body = parseBlock();1092 node.handler = finishNode(clause, "CatchClause");1093 }1094 node.guardedHandlers = empty;1095 node.finalizer = eat(_finally) ? parseBlock() : null;1096 if (!node.handler && !node.finalizer)1097 raise(node.start, "Missing catch or finally clause");1098 return finishNode(node, "TryStatement");1099 case _var:1100 next();1101 parseVar(node);1102 semicolon();1103 return finishNode(node, "VariableDeclaration");1104 case _while:1105 next();1106 node.test = parseParenExpression();1107 labels.push(loopLabel);1108 node.body = parseStatement();1109 labels.pop();1110 return finishNode(node, "WhileStatement");1111 case _with:1112 if (strict) raise(tokStart, "'with' in strict mode");1113 next();1114 node.object = parseParenExpression();1115 node.body = parseStatement();1116 return finishNode(node, "WithStatement");1117 case _braceL:1118 return parseBlock();1119 case _semi:1120 next();1121 return finishNode(node, "EmptyStatement");1122 // If the statement does not start with a statement keyword or a1123 // brace, it's an ExpressionStatement or LabeledStatement. We1124 // simply start parsing an expression, and afterwards, if the1125 // next token is a colon and the expression was a simple1126 // Identifier node, we switch to interpreting it as a label.1127 default:1128 var maybeName = tokVal, expr = parseExpression();1129 if (starttype === _name && expr.type === "Identifier" && eat(_colon)) {1130 for (var i = 0; i < labels.length; ++i)1131 if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");1132 var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;1133 labels.push({name: maybeName, kind: kind});1134 node.body = parseStatement();1135 labels.pop();1136 node.label = expr;1137 return finishNode(node, "LabeledStatement");1138 } else {1139 node.expression = expr;1140 semicolon();1141 return finishNode(node, "ExpressionStatement");1142 }1143 }1144 }1145 // Used for constructs like `switch` and `if` that insist on1146 // parentheses around their expression.1147 function parseParenExpression() {1148 expect(_parenL);1149 var val = parseExpression();1150 expect(_parenR);1151 return val;1152 }1153 // Parse a semicolon-enclosed block of statements, handling `"use1154 // strict"` declarations when `allowStrict` is true (used for1155 // function bodies).1156 function parseBlock(allowStrict) {1157 var node = startNode(), first = true, strict = false, oldStrict;1158 node.body = [];1159 expect(_braceL);1160 while (!eat(_braceR)) {1161 var stmt = parseStatement();1162 node.body.push(stmt);1163 if (first && allowStrict && isUseStrict(stmt)) {1164 oldStrict = strict;1165 setStrict(strict = true);1166 }1167 first = false;1168 }1169 if (strict && !oldStrict) setStrict(false);1170 return finishNode(node, "BlockStatement");1171 }1172 // Parse a regular `for` loop. The disambiguation code in1173 // `parseStatement` will already have parsed the init statement or1174 // expression.1175 function parseFor(node, init) {1176 node.init = init;1177 expect(_semi);1178 node.test = tokType === _semi ? null : parseExpression();1179 expect(_semi);1180 node.update = tokType === _parenR ? null : parseExpression();1181 expect(_parenR);1182 node.body = parseStatement();1183 labels.pop();1184 return finishNode(node, "ForStatement");1185 }1186 // Parse a `for`/`in` loop.1187 function parseForIn(node, init) {1188 node.left = init;1189 node.right = parseExpression();1190 expect(_parenR);1191 node.body = parseStatement();1192 labels.pop();1193 return finishNode(node, "ForInStatement");1194 }1195 // Parse a list of variable declarations.1196 function parseVar(node, noIn) {1197 node.declarations = [];1198 node.kind = "var";1199 for (;;) {1200 var decl = startNode();1201 decl.id = parseIdent();1202 if (strict && isStrictBadIdWord(decl.id.name))1203 raise(decl.id.start, "Binding " + decl.id.name + " in strict mode");1204 decl.init = eat(_eq) ? parseExpression(true, noIn) : null;1205 node.declarations.push(finishNode(decl, "VariableDeclarator"));1206 if (!eat(_comma)) break;1207 }1208 return node;1209 }1210 // ### Expression parsing1211 // These nest, from the most general expression type at the top to1212 // 'atomic', nondivisible expression types at the bottom. Most of1213 // the functions will simply let the function(s) below them parse,1214 // and, *if* the syntactic construct they handle is present, wrap1215 // the AST node that the inner parser gave them in another node.1216 // Parse a full expression. The arguments are used to forbid comma1217 // sequences (in argument lists, array literals, or object literals)1218 // or the `in` operator (in for loops initalization expressions).1219 function parseExpression(noComma, noIn) {1220 var expr = parseMaybeAssign(noIn);1221 if (!noComma && tokType === _comma) {1222 var node = startNodeFrom(expr);1223 node.expressions = [expr];1224 while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));1225 return finishNode(node, "SequenceExpression");1226 }1227 return expr;1228 }1229 // Parse an assignment expression. This includes applications of1230 // operators like `+=`.1231 function parseMaybeAssign(noIn) {1232 var left = parseMaybeConditional(noIn);1233 if (tokType.isAssign) {1234 var node = startNodeFrom(left);1235 node.operator = tokVal;1236 node.left = left;1237 next();1238 node.right = parseMaybeAssign(noIn);1239 checkLVal(left);1240 return finishNode(node, "AssignmentExpression");1241 }1242 return left;1243 }1244 // Parse a ternary conditional (`?:`) operator.1245 function parseMaybeConditional(noIn) {1246 var expr = parseExprOps(noIn);1247 if (eat(_question)) {1248 var node = startNodeFrom(expr);1249 node.test = expr;1250 node.consequent = parseExpression(true);1251 expect(_colon);1252 node.alternate = parseExpression(true, noIn);1253 return finishNode(node, "ConditionalExpression");1254 }1255 return expr;1256 }1257 // Start the precedence parser.1258 function parseExprOps(noIn) {1259 return parseExprOp(parseMaybeUnary(), -1, noIn);1260 }1261 // Parse binary operators with the operator precedence parsing1262 // algorithm. `left` is the left-hand side of the operator.1263 // `minPrec` provides context that allows the function to stop and1264 // defer further parser to one of its callers when it encounters an1265 // operator that has a lower precedence than the set it is parsing.1266 function parseExprOp(left, minPrec, noIn) {1267 var prec = tokType.binop;1268 if (prec != null && (!noIn || tokType !== _in)) {1269 if (prec > minPrec) {1270 var node = startNodeFrom(left);1271 node.left = left;1272 node.operator = tokVal;1273 var op = tokType;1274 next();1275 node.right = parseExprOp(parseMaybeUnary(), prec, noIn);1276 var exprNode = finishNode(node, (op === _logicalOR || op === _logicalAND) ? "LogicalExpression" : "BinaryExpression");1277 return parseExprOp(exprNode, minPrec, noIn);1278 }1279 }1280 return left;1281 }1282 // Parse unary operators, both prefix and postfix.1283 function parseMaybeUnary() {1284 if (tokType.prefix) {1285 var node = startNode(), update = tokType.isUpdate;1286 node.operator = tokVal;1287 node.prefix = true;1288 tokRegexpAllowed = true;1289 next();1290 node.argument = parseMaybeUnary();1291 if (update) checkLVal(node.argument);1292 else if (strict && node.operator === "delete" &&1293 node.argument.type === "Identifier")1294 raise(node.start, "Deleting local variable in strict mode");1295 return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");1296 }1297 var expr = parseExprSubscripts();1298 while (tokType.postfix && !canInsertSemicolon()) {1299 var node = startNodeFrom(expr);1300 node.operator = tokVal;1301 node.prefix = false;1302 node.argument = expr;1303 checkLVal(expr);1304 next();1305 expr = finishNode(node, "UpdateExpression");1306 }1307 return expr;1308 }1309 // Parse call, dot, and `[]`-subscript expressions.1310 function parseExprSubscripts() {1311 return parseSubscripts(parseExprAtom());1312 }1313 function parseSubscripts(base, noCalls) {1314 if (eat(_dot)) {1315 var node = startNodeFrom(base);1316 node.object = base;1317 node.property = parseIdent(true);1318 node.computed = false;1319 return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);1320 } else if (eat(_bracketL)) {1321 var node = startNodeFrom(base);1322 node.object = base;1323 node.property = parseExpression();1324 node.computed = true;1325 expect(_bracketR);1326 return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);1327 } else if (!noCalls && eat(_parenL)) {1328 var node = startNodeFrom(base);1329 node.callee = base;1330 node.arguments = parseExprList(_parenR, false);1331 return parseSubscripts(finishNode(node, "CallExpression"), noCalls);1332 } else return base;1333 }1334 // Parse an atomic expression â either a single token that is an1335 // expression, an expression started by a keyword like `function` or1336 // `new`, or an expression wrapped in punctuation like `()`, `[]`,1337 // or `{}`.1338 function parseExprAtom() {1339 switch (tokType) {1340 case _this:1341 var node = startNode();1342 next();1343 return finishNode(node, "ThisExpression");1344 case _name:1345 return parseIdent();1346 case _num: case _string: case _regexp:1347 var node = startNode();1348 node.value = tokVal;1349 node.raw = input.slice(tokStart, tokEnd);1350 next();1351 return finishNode(node, "Literal");1352 case _null: case _true: case _false:1353 var node = startNode();1354 node.value = tokType.atomValue;1355 node.raw = tokType.keyword;1356 next();1357 return finishNode(node, "Literal");1358 case _parenL:1359 var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart;1360 next();1361 var val = parseExpression();1362 val.start = tokStart1;1363 val.end = tokEnd;1364 if (options.locations) {1365 val.loc.start = tokStartLoc1;1366 val.loc.end = tokEndLoc;1367 }1368 if (options.ranges)1369 val.range = [tokStart1, tokEnd];1370 expect(_parenR);1371 return val;1372 case _bracketL:1373 var node = startNode();1374 next();1375 node.elements = parseExprList(_bracketR, true, true);1376 return finishNode(node, "ArrayExpression");1377 case _braceL:1378 return parseObj();1379 case _function:1380 var node = startNode();1381 next();1382 return parseFunction(node, false);1383 case _new:1384 return parseNew();1385 default:1386 unexpected();1387 }1388 }1389 // New's precedence is slightly tricky. It must allow its argument1390 // to be a `[]` or dot subscript expression, but not a call â at1391 // least, not without wrapping it in parentheses. Thus, it uses the1392 function parseNew() {1393 var node = startNode();1394 next();1395 node.callee = parseSubscripts(parseExprAtom(), true);1396 if (eat(_parenL)) node.arguments = parseExprList(_parenR, false);1397 else node.arguments = empty;1398 return finishNode(node, "NewExpression");1399 }1400 // Parse an object literal.1401 function parseObj() {1402 var node = startNode(), first = true, sawGetSet = false;1403 node.properties = [];1404 next();1405 while (!eat(_braceR)) {1406 if (!first) {1407 expect(_comma);1408 if (options.allowTrailingCommas && eat(_braceR)) break;1409 } else first = false;1410 var prop = {key: parsePropertyName()}, isGetSet = false, kind;1411 if (eat(_colon)) {1412 prop.value = parseExpression(true);1413 kind = prop.kind = "init";1414 } else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&1415 (prop.key.name === "get" || prop.key.name === "set")) {1416 isGetSet = sawGetSet = true;1417 kind = prop.kind = prop.key.name;1418 prop.key = parsePropertyName();1419 if (tokType !== _parenL) unexpected();1420 prop.value = parseFunction(startNode(), false);1421 } else unexpected();1422 // getters and setters are not allowed to clash â either with1423 // each other or with an init property â and in strict mode,1424 // init properties are also not allowed to be repeated.1425 if (prop.key.type === "Identifier" && (strict || sawGetSet)) {1426 for (var i = 0; i < node.properties.length; ++i) {1427 var other = node.properties[i];1428 if (other.key.name === prop.key.name) {1429 var conflict = kind == other.kind || isGetSet && other.kind === "init" ||1430 kind === "init" && (other.kind === "get" || other.kind === "set");1431 if (conflict && !strict && kind === "init" && other.kind === "init") conflict = false;1432 if (conflict) raise(prop.key.start, "Redefinition of property");1433 }1434 }1435 }1436 node.properties.push(prop);1437 }1438 return finishNode(node, "ObjectExpression");1439 }1440 function parsePropertyName() {1441 if (tokType === _num || tokType === _string) return parseExprAtom();1442 return parseIdent(true);1443 }1444 // Parse a function declaration or literal (depending on the1445 // `isStatement` parameter).1446 function parseFunction(node, isStatement) {1447 if (tokType === _name) node.id = parseIdent();1448 else if (isStatement) unexpected();1449 else node.id = null;1450 node.params = [];1451 var first = true;1452 expect(_parenL);1453 while (!eat(_parenR)) {1454 if (!first) expect(_comma); else first = false;1455 node.params.push(parseIdent());1456 }1457 // Start a new scope with regard to labels and the `inFunction`1458 // flag (restore them to their old value afterwards).1459 var oldInFunc = inFunction, oldLabels = labels;1460 inFunction = true; labels = [];1461 node.body = parseBlock(true);1462 inFunction = oldInFunc; labels = oldLabels;1463 // If this is a strict mode function, verify that argument names1464 // are not repeated, and it does not try to bind the words `eval`1465 // or `arguments`.1466 if (strict || node.body.body.length && isUseStrict(node.body.body[0])) {1467 for (var i = node.id ? -1 : 0; i < node.params.length; ++i) {1468 var id = i < 0 ? node.id : node.params[i];1469 if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name))1470 raise(id.start, "Defining '" + id.name + "' in strict mode");1471 if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name)1472 raise(id.start, "Argument name clash in strict mode");1473 }1474 }1475 return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");1476 }1477 // Parses a comma-separated list of expressions, and returns them as1478 // an array. `close` is the token type that ends the list, and1479 // `allowEmpty` can be turned on to allow subsequent commas with1480 // nothing in between them to be parsed as `null` (which is needed1481 // for array literals).1482 function parseExprList(close, allowTrailingComma, allowEmpty) {1483 var elts = [], first = true;1484 while (!eat(close)) {1485 if (!first) {1486 expect(_comma);1487 if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;1488 } else first = false;1489 if (allowEmpty && tokType === _comma) elts.push(null);1490 else elts.push(parseExpression(true));1491 }1492 return elts;1493 }1494 // Parse the next token as an identifier. If `liberal` is true (used1495 // when parsing properties), it will also convert keywords into1496 // identifiers.1497 function parseIdent(liberal) {1498 var node = startNode();1499 node.name = tokType === _name ? tokVal : (liberal && !options.forbidReserved && tokType.keyword) || unexpected();1500 tokRegexpAllowed = false;1501 next();1502 return finishNode(node, "Identifier");1503 }...
acorn_loose.js
Source:acorn_loose.js
1(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 || (g.acorn = {})).loose = 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){2"use strict";3module.exports = typeof acorn != "undefined" ? acorn : _dereq_("./acorn");4},{}],2:[function(_dereq_,module,exports){5"use strict";6var _state = _dereq_("./state");7var _parseutil = _dereq_("./parseutil");8var _ = _dereq_("..");9var lp = _state.LooseParser.prototype;10lp.checkLVal = function (expr, binding) {11 if (!expr) return expr;12 switch (expr.type) {13 case "Identifier":14 return expr;15 case "MemberExpression":16 return binding ? this.dummyIdent() : expr;17 case "ParenthesizedExpression":18 expr.expression = this.checkLVal(expr.expression, binding);19 return expr;20 // FIXME recursively check contents21 case "ObjectPattern":22 case "ArrayPattern":23 case "RestElement":24 case "AssignmentPattern":25 if (this.options.ecmaVersion >= 6) return expr;26 default:27 return this.dummyIdent();28 }29};30lp.parseExpression = function (noIn) {31 var start = this.storeCurrentPos();32 var expr = this.parseMaybeAssign(noIn);33 if (this.tok.type === _.tokTypes.comma) {34 var node = this.startNodeAt(start);35 node.expressions = [expr];36 while (this.eat(_.tokTypes.comma)) node.expressions.push(this.parseMaybeAssign(noIn));37 return this.finishNode(node, "SequenceExpression");38 }39 return expr;40};41lp.parseParenExpression = function () {42 this.pushCx();43 this.expect(_.tokTypes.parenL);44 var val = this.parseExpression();45 this.popCx();46 this.expect(_.tokTypes.parenR);47 return val;48};49lp.parseMaybeAssign = function (noIn) {50 var start = this.storeCurrentPos();51 var left = this.parseMaybeConditional(noIn);52 if (this.tok.type.isAssign) {53 var node = this.startNodeAt(start);54 node.operator = this.tok.value;55 node.left = this.tok.type === _.tokTypes.eq ? this.toAssignable(left) : this.checkLVal(left);56 this.next();57 node.right = this.parseMaybeAssign(noIn);58 return this.finishNode(node, "AssignmentExpression");59 }60 return left;61};62lp.parseMaybeConditional = function (noIn) {63 var start = this.storeCurrentPos();64 var expr = this.parseExprOps(noIn);65 if (this.eat(_.tokTypes.question)) {66 var node = this.startNodeAt(start);67 node.test = expr;68 node.consequent = this.parseMaybeAssign();69 node.alternate = this.expect(_.tokTypes.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent();70 return this.finishNode(node, "ConditionalExpression");71 }72 return expr;73};74lp.parseExprOps = function (noIn) {75 var start = this.storeCurrentPos();76 var indent = this.curIndent,77 line = this.curLineStart;78 return this.parseExprOp(this.parseMaybeUnary(noIn), start, -1, noIn, indent, line);79};80lp.parseExprOp = function (left, start, minPrec, noIn, indent, line) {81 if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left;82 var prec = this.tok.type.binop;83 if (prec != null && (!noIn || this.tok.type !== _.tokTypes._in)) {84 if (prec > minPrec) {85 var node = this.startNodeAt(start);86 node.left = left;87 node.operator = this.tok.value;88 this.next();89 if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) {90 node.right = this.dummyIdent();91 } else {92 var rightStart = this.storeCurrentPos();93 node.right = this.parseExprOp(this.parseMaybeUnary(noIn), rightStart, prec, noIn, indent, line);94 }95 this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression");96 return this.parseExprOp(node, start, minPrec, noIn, indent, line);97 }98 }99 return left;100};101lp.parseMaybeUnary = function (noIn) {102 if (this.tok.type.prefix) {103 var node = this.startNode(),104 update = this.tok.type === _.tokTypes.incDec;105 node.operator = this.tok.value;106 node.prefix = true;107 this.next();108 node.argument = this.parseMaybeUnary(noIn);109 if (update) node.argument = this.checkLVal(node.argument);110 return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");111 } else if (this.tok.type === _.tokTypes.ellipsis) {112 var node = this.startNode();113 this.next();114 node.argument = this.parseMaybeUnary(noIn);115 return this.finishNode(node, "SpreadElement");116 }117 var start = this.storeCurrentPos();118 var expr = this.parseExprSubscripts();119 while (this.tok.type.postfix && !this.canInsertSemicolon()) {120 var node = this.startNodeAt(start);121 node.operator = this.tok.value;122 node.prefix = false;123 node.argument = this.checkLVal(expr);124 this.next();125 expr = this.finishNode(node, "UpdateExpression");126 }127 return expr;128};129lp.parseExprSubscripts = function () {130 var start = this.storeCurrentPos();131 return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart);132};133lp.parseSubscripts = function (base, start, noCalls, startIndent, line) {134 for (;;) {135 if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) {136 if (this.tok.type == _.tokTypes.dot && this.curIndent == startIndent) --startIndent;else return base;137 }138 if (this.eat(_.tokTypes.dot)) {139 var node = this.startNodeAt(start);140 node.object = base;141 if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) node.property = this.dummyIdent();else node.property = this.parsePropertyAccessor() || this.dummyIdent();142 node.computed = false;143 base = this.finishNode(node, "MemberExpression");144 } else if (this.tok.type == _.tokTypes.bracketL) {145 this.pushCx();146 this.next();147 var node = this.startNodeAt(start);148 node.object = base;149 node.property = this.parseExpression();150 node.computed = true;151 this.popCx();152 this.expect(_.tokTypes.bracketR);153 base = this.finishNode(node, "MemberExpression");154 } else if (!noCalls && this.tok.type == _.tokTypes.parenL) {155 var node = this.startNodeAt(start);156 node.callee = base;157 node.arguments = this.parseExprList(_.tokTypes.parenR);158 base = this.finishNode(node, "CallExpression");159 } else if (this.tok.type == _.tokTypes.backQuote) {160 var node = this.startNodeAt(start);161 node.tag = base;162 node.quasi = this.parseTemplate();163 base = this.finishNode(node, "TaggedTemplateExpression");164 } else {165 return base;166 }167 }168};169lp.parseExprAtom = function () {170 var node = undefined;171 switch (this.tok.type) {172 case _.tokTypes._this:173 case _.tokTypes._super:174 var type = this.tok.type === _.tokTypes._this ? "ThisExpression" : "Super";175 node = this.startNode();176 this.next();177 return this.finishNode(node, type);178 case _.tokTypes.name:179 var start = this.storeCurrentPos();180 var id = this.parseIdent();181 return this.eat(_.tokTypes.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id]) : id;182 case _.tokTypes.regexp:183 node = this.startNode();184 var val = this.tok.value;185 node.regex = { pattern: val.pattern, flags: val.flags };186 node.value = val.value;187 node.raw = this.input.slice(this.tok.start, this.tok.end);188 this.next();189 return this.finishNode(node, "Literal");190 case _.tokTypes.num:case _.tokTypes.string:191 node = this.startNode();192 node.value = this.tok.value;193 node.raw = this.input.slice(this.tok.start, this.tok.end);194 this.next();195 return this.finishNode(node, "Literal");196 case _.tokTypes._null:case _.tokTypes._true:case _.tokTypes._false:197 node = this.startNode();198 node.value = this.tok.type === _.tokTypes._null ? null : this.tok.type === _.tokTypes._true;199 node.raw = this.tok.type.keyword;200 this.next();201 return this.finishNode(node, "Literal");202 case _.tokTypes.parenL:203 var parenStart = this.storeCurrentPos();204 this.next();205 var inner = this.parseExpression();206 this.expect(_.tokTypes.parenR);207 if (this.eat(_.tokTypes.arrow)) {208 return this.parseArrowExpression(this.startNodeAt(parenStart), inner.expressions || (_parseutil.isDummy(inner) ? [] : [inner]));209 }210 if (this.options.preserveParens) {211 var par = this.startNodeAt(parenStart);212 par.expression = inner;213 inner = this.finishNode(par, "ParenthesizedExpression");214 }215 return inner;216 case _.tokTypes.bracketL:217 node = this.startNode();218 node.elements = this.parseExprList(_.tokTypes.bracketR, true);219 return this.finishNode(node, "ArrayExpression");220 case _.tokTypes.braceL:221 return this.parseObj();222 case _.tokTypes._class:223 return this.parseClass();224 case _.tokTypes._function:225 node = this.startNode();226 this.next();227 return this.parseFunction(node, false);228 case _.tokTypes._new:229 return this.parseNew();230 case _.tokTypes._yield:231 node = this.startNode();232 this.next();233 if (this.semicolon() || this.canInsertSemicolon() || this.tok.type != _.tokTypes.star && !this.tok.type.startsExpr) {234 node.delegate = false;235 node.argument = null;236 } else {237 node.delegate = this.eat(_.tokTypes.star);238 node.argument = this.parseMaybeAssign();239 }240 return this.finishNode(node, "YieldExpression");241 case _.tokTypes.backQuote:242 return this.parseTemplate();243 default:244 return this.dummyIdent();245 }246};247lp.parseNew = function () {248 var node = this.startNode(),249 startIndent = this.curIndent,250 line = this.curLineStart;251 var meta = this.parseIdent(true);252 if (this.options.ecmaVersion >= 6 && this.eat(_.tokTypes.dot)) {253 node.meta = meta;254 node.property = this.parseIdent(true);255 return this.finishNode(node, "MetaProperty");256 }257 var start = this.storeCurrentPos();258 node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line);259 if (this.tok.type == _.tokTypes.parenL) {260 node.arguments = this.parseExprList(_.tokTypes.parenR);261 } else {262 node.arguments = [];263 }264 return this.finishNode(node, "NewExpression");265};266lp.parseTemplateElement = function () {267 var elem = this.startNode();268 elem.value = {269 raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, "\n"),270 cooked: this.tok.value271 };272 this.next();273 elem.tail = this.tok.type === _.tokTypes.backQuote;274 return this.finishNode(elem, "TemplateElement");275};276lp.parseTemplate = function () {277 var node = this.startNode();278 this.next();279 node.expressions = [];280 var curElt = this.parseTemplateElement();281 node.quasis = [curElt];282 while (!curElt.tail) {283 this.next();284 node.expressions.push(this.parseExpression());285 if (this.expect(_.tokTypes.braceR)) {286 curElt = this.parseTemplateElement();287 } else {288 curElt = this.startNode();289 curElt.value = { cooked: "", raw: "" };290 curElt.tail = true;291 }292 node.quasis.push(curElt);293 }294 this.expect(_.tokTypes.backQuote);295 return this.finishNode(node, "TemplateLiteral");296};297lp.parseObj = function () {298 var node = this.startNode();299 node.properties = [];300 this.pushCx();301 var indent = this.curIndent + 1,302 line = this.curLineStart;303 this.eat(_.tokTypes.braceL);304 if (this.curIndent + 1 < indent) {305 indent = this.curIndent;line = this.curLineStart;306 }307 while (!this.closes(_.tokTypes.braceR, indent, line)) {308 var prop = this.startNode(),309 isGenerator = undefined,310 start = undefined;311 if (this.options.ecmaVersion >= 6) {312 start = this.storeCurrentPos();313 prop.method = false;314 prop.shorthand = false;315 isGenerator = this.eat(_.tokTypes.star);316 }317 this.parsePropertyName(prop);318 if (_parseutil.isDummy(prop.key)) {319 if (_parseutil.isDummy(this.parseMaybeAssign())) this.next();this.eat(_.tokTypes.comma);continue;320 }321 if (this.eat(_.tokTypes.colon)) {322 prop.kind = "init";323 prop.value = this.parseMaybeAssign();324 } else if (this.options.ecmaVersion >= 6 && (this.tok.type === _.tokTypes.parenL || this.tok.type === _.tokTypes.braceL)) {325 prop.kind = "init";326 prop.method = true;327 prop.value = this.parseMethod(isGenerator);328 } else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" && !prop.computed && (prop.key.name === "get" || prop.key.name === "set") && (this.tok.type != _.tokTypes.comma && this.tok.type != _.tokTypes.braceR)) {329 prop.kind = prop.key.name;330 this.parsePropertyName(prop);331 prop.value = this.parseMethod(false);332 } else {333 prop.kind = "init";334 if (this.options.ecmaVersion >= 6) {335 if (this.eat(_.tokTypes.eq)) {336 var assign = this.startNodeAt(start);337 assign.operator = "=";338 assign.left = prop.key;339 assign.right = this.parseMaybeAssign();340 prop.value = this.finishNode(assign, "AssignmentExpression");341 } else {342 prop.value = prop.key;343 }344 } else {345 prop.value = this.dummyIdent();346 }347 prop.shorthand = true;348 }349 node.properties.push(this.finishNode(prop, "Property"));350 this.eat(_.tokTypes.comma);351 }352 this.popCx();353 if (!this.eat(_.tokTypes.braceR)) {354 // If there is no closing brace, make the node span to the start355 // of the next token (this is useful for Tern)356 this.last.end = this.tok.start;357 if (this.options.locations) this.last.loc.end = this.tok.loc.start;358 }359 return this.finishNode(node, "ObjectExpression");360};361lp.parsePropertyName = function (prop) {362 if (this.options.ecmaVersion >= 6) {363 if (this.eat(_.tokTypes.bracketL)) {364 prop.computed = true;365 prop.key = this.parseExpression();366 this.expect(_.tokTypes.bracketR);367 return;368 } else {369 prop.computed = false;370 }371 }372 var key = this.tok.type === _.tokTypes.num || this.tok.type === _.tokTypes.string ? this.parseExprAtom() : this.parseIdent();373 prop.key = key || this.dummyIdent();374};375lp.parsePropertyAccessor = function () {376 if (this.tok.type === _.tokTypes.name || this.tok.type.keyword) return this.parseIdent();377};378lp.parseIdent = function () {379 var name = this.tok.type === _.tokTypes.name ? this.tok.value : this.tok.type.keyword;380 if (!name) return this.dummyIdent();381 var node = this.startNode();382 this.next();383 node.name = name;384 return this.finishNode(node, "Identifier");385};386lp.initFunction = function (node) {387 node.id = null;388 node.params = [];389 if (this.options.ecmaVersion >= 6) {390 node.generator = false;391 node.expression = false;392 }393};394// Convert existing expression atom to assignable pattern395// if possible.396lp.toAssignable = function (node, binding) {397 if (this.options.ecmaVersion >= 6 && node) {398 switch (node.type) {399 case "ObjectExpression":400 node.type = "ObjectPattern";401 var props = node.properties;402 for (var i = 0; i < props.length; i++) {403 this.toAssignable(props[i].value, binding);404 }break;405 case "ArrayExpression":406 node.type = "ArrayPattern";407 this.toAssignableList(node.elements, binding);408 break;409 case "SpreadElement":410 node.type = "RestElement";411 node.argument = this.toAssignable(node.argument, binding);412 break;413 case "AssignmentExpression":414 node.type = "AssignmentPattern";415 delete node.operator;416 break;417 }418 }419 return this.checkLVal(node, binding);420};421lp.toAssignableList = function (exprList, binding) {422 for (var i = 0; i < exprList.length; i++) {423 exprList[i] = this.toAssignable(exprList[i], binding);424 }return exprList;425};426lp.parseFunctionParams = function (params) {427 params = this.parseExprList(_.tokTypes.parenR);428 return this.toAssignableList(params, true);429};430lp.parseMethod = function (isGenerator) {431 var node = this.startNode();432 this.initFunction(node);433 node.params = this.parseFunctionParams();434 node.generator = isGenerator || false;435 node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== _.tokTypes.braceL;436 node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock();437 return this.finishNode(node, "FunctionExpression");438};439lp.parseArrowExpression = function (node, params) {440 this.initFunction(node);441 node.params = this.toAssignableList(params, true);442 node.expression = this.tok.type !== _.tokTypes.braceL;443 node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock();444 return this.finishNode(node, "ArrowFunctionExpression");445};446lp.parseExprList = function (close, allowEmpty) {447 this.pushCx();448 var indent = this.curIndent,449 line = this.curLineStart,450 elts = [];451 this.next(); // Opening bracket452 while (!this.closes(close, indent + 1, line)) {453 if (this.eat(_.tokTypes.comma)) {454 elts.push(allowEmpty ? null : this.dummyIdent());455 continue;456 }457 var elt = this.parseMaybeAssign();458 if (_parseutil.isDummy(elt)) {459 if (this.closes(close, indent, line)) break;460 this.next();461 } else {462 elts.push(elt);463 }464 this.eat(_.tokTypes.comma);465 }466 this.popCx();467 if (!this.eat(close)) {468 // If there is no closing brace, make the node span to the start469 // of the next token (this is useful for Tern)470 this.last.end = this.tok.start;471 if (this.options.locations) this.last.loc.end = this.tok.loc.start;472 }473 return elts;474};475},{"..":1,"./parseutil":4,"./state":5}],3:[function(_dereq_,module,exports){476// Acorn: Loose parser477//478// This module provides an alternative parser (`parse_dammit`) that479// exposes that same interface as `parse`, but will try to parse480// anything as JavaScript, repairing syntax error the best it can.481// There are circumstances in which it will raise an error and give482// up, but they are very rare. The resulting AST will be a mostly483// valid JavaScript AST (as per the [Mozilla parser API][api], except484// that:485//486// - Return outside functions is allowed487//488// - Label consistency (no conflicts, break only to existing labels)489// is not enforced.490//491// - Bogus Identifier nodes with a name of `"â"` are inserted whenever492// the parser got too confused to return anything meaningful.493//494// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API495//496// The expected use for this is to *first* try `acorn.parse`, and only497// if that fails switch to `parse_dammit`. The loose parser might498// parse badly indented code incorrectly, so **don't** use it as499// your default parser.500//501// Quite a lot of acorn.js is duplicated here. The alternative was to502// add a *lot* of extra cruft to that file, making it less readable503// and slower. Copying and editing the code allowed me to make504// invasive changes and simplifications without creating a complicated505// tangle.506"use strict";507exports.__esModule = true;508exports.parse_dammit = parse_dammit;509function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }510var _ = _dereq_("..");511var acorn = _interopRequireWildcard(_);512var _state = _dereq_("./state");513_dereq_("./tokenize");514_dereq_("./statement");515_dereq_("./expression");516exports.LooseParser = _state.LooseParser;517acorn.defaultOptions.tabSize = 4;518function parse_dammit(input, options) {519 var p = new _state.LooseParser(input, options);520 p.next();521 return p.parseTopLevel();522}523acorn.parse_dammit = parse_dammit;524acorn.LooseParser = _state.LooseParser;525},{"..":1,"./expression":2,"./state":5,"./statement":6,"./tokenize":7}],4:[function(_dereq_,module,exports){526"use strict";527exports.__esModule = true;528exports.isDummy = isDummy;529function isDummy(node) {530 return node.name == "â";531}532},{}],5:[function(_dereq_,module,exports){533"use strict";534exports.__esModule = true;535function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }536var _ = _dereq_("..");537var LooseParser = (function () {538 function LooseParser(input, options) {539 _classCallCheck(this, LooseParser);540 this.toks = _.tokenizer(input, options);541 this.options = this.toks.options;542 this.input = this.toks.input;543 this.tok = this.last = { type: _.tokTypes.eof, start: 0, end: 0 };544 if (this.options.locations) {545 var here = this.toks.curPosition();546 this.tok.loc = new _.SourceLocation(this.toks, here, here);547 }548 this.ahead = []; // Tokens ahead549 this.context = []; // Indentation contexted550 this.curIndent = 0;551 this.curLineStart = 0;552 this.nextLineStart = this.lineEnd(this.curLineStart) + 1;553 }554 LooseParser.prototype.startNode = function startNode() {555 return new _.Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null);556 };557 LooseParser.prototype.storeCurrentPos = function storeCurrentPos() {558 return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start;559 };560 LooseParser.prototype.startNodeAt = function startNodeAt(pos) {561 if (this.options.locations) {562 return new _.Node(this.toks, pos[0], pos[1]);563 } else {564 return new _.Node(this.toks, pos);565 }566 };567 LooseParser.prototype.finishNode = function finishNode(node, type) {568 node.type = type;569 node.end = this.last.end;570 if (this.options.locations) node.loc.end = this.last.loc.end;571 if (this.options.ranges) node.range[1] = this.last.end;572 return node;573 };574 LooseParser.prototype.dummyIdent = function dummyIdent() {575 var dummy = this.startNode();576 dummy.name = "â";577 return this.finishNode(dummy, "Identifier");578 };579 LooseParser.prototype.eat = function eat(type) {580 if (this.tok.type === type) {581 this.next();582 return true;583 } else {584 return false;585 }586 };587 LooseParser.prototype.isContextual = function isContextual(name) {588 return this.tok.type === _.tokTypes.name && this.tok.value === name;589 };590 LooseParser.prototype.eatContextual = function eatContextual(name) {591 return this.tok.value === name && this.eat(_.tokTypes.name);592 };593 LooseParser.prototype.canInsertSemicolon = function canInsertSemicolon() {594 return this.tok.type === _.tokTypes.eof || this.tok.type === _.tokTypes.braceR || _.lineBreak.test(this.input.slice(this.last.end, this.tok.start));595 };596 LooseParser.prototype.semicolon = function semicolon() {597 return this.eat(_.tokTypes.semi);598 };599 LooseParser.prototype.expect = function expect(type) {600 if (this.eat(type)) return true;601 for (var i = 1; i <= 2; i++) {602 if (this.lookAhead(i).type == type) {603 for (var j = 0; j < i; j++) {604 this.next();605 }return true;606 }607 }608 };609 LooseParser.prototype.pushCx = function pushCx() {610 this.context.push(this.curIndent);611 };612 LooseParser.prototype.popCx = function popCx() {613 this.curIndent = this.context.pop();614 };615 LooseParser.prototype.lineEnd = function lineEnd(pos) {616 while (pos < this.input.length && !_.isNewLine(this.input.charCodeAt(pos))) ++pos;617 return pos;618 };619 LooseParser.prototype.indentationAfter = function indentationAfter(pos) {620 for (var count = 0;; ++pos) {621 var ch = this.input.charCodeAt(pos);622 if (ch === 32) ++count;else if (ch === 9) count += this.options.tabSize;else return count;623 }624 };625 LooseParser.prototype.closes = function closes(closeTok, indent, line, blockHeuristic) {626 if (this.tok.type === closeTok || this.tok.type === _.tokTypes.eof) return true;627 return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() && (!blockHeuristic || this.nextLineStart >= this.input.length || this.indentationAfter(this.nextLineStart) < indent);628 };629 LooseParser.prototype.tokenStartsLine = function tokenStartsLine() {630 for (var p = this.tok.start - 1; p >= this.curLineStart; --p) {631 var ch = this.input.charCodeAt(p);632 if (ch !== 9 && ch !== 32) return false;633 }634 return true;635 };636 return LooseParser;637})();638exports.LooseParser = LooseParser;639},{"..":1}],6:[function(_dereq_,module,exports){640"use strict";641var _state = _dereq_("./state");642var _parseutil = _dereq_("./parseutil");643var _ = _dereq_("..");644var lp = _state.LooseParser.prototype;645lp.parseTopLevel = function () {646 var node = this.startNodeAt(this.options.locations ? [0, _.getLineInfo(this.input, 0)] : 0);647 node.body = [];648 while (this.tok.type !== _.tokTypes.eof) node.body.push(this.parseStatement());649 this.last = this.tok;650 if (this.options.ecmaVersion >= 6) {651 node.sourceType = this.options.sourceType;652 }653 return this.finishNode(node, "Program");654};655lp.parseStatement = function () {656 var starttype = this.tok.type,657 node = this.startNode();658 switch (starttype) {659 case _.tokTypes._break:case _.tokTypes._continue:660 this.next();661 var isBreak = starttype === _.tokTypes._break;662 if (this.semicolon() || this.canInsertSemicolon()) {663 node.label = null;664 } else {665 node.label = this.tok.type === _.tokTypes.name ? this.parseIdent() : null;666 this.semicolon();667 }668 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");669 case _.tokTypes._debugger:670 this.next();671 this.semicolon();672 return this.finishNode(node, "DebuggerStatement");673 case _.tokTypes._do:674 this.next();675 node.body = this.parseStatement();676 node.test = this.eat(_.tokTypes._while) ? this.parseParenExpression() : this.dummyIdent();677 this.semicolon();678 return this.finishNode(node, "DoWhileStatement");679 case _.tokTypes._for:680 this.next();681 this.pushCx();682 this.expect(_.tokTypes.parenL);683 if (this.tok.type === _.tokTypes.semi) return this.parseFor(node, null);684 if (this.tok.type === _.tokTypes._var || this.tok.type === _.tokTypes._let || this.tok.type === _.tokTypes._const) {685 var _init = this.parseVar(true);686 if (_init.declarations.length === 1 && (this.tok.type === _.tokTypes._in || this.isContextual("of"))) {687 return this.parseForIn(node, _init);688 }689 return this.parseFor(node, _init);690 }691 var init = this.parseExpression(true);692 if (this.tok.type === _.tokTypes._in || this.isContextual("of")) return this.parseForIn(node, this.toAssignable(init));693 return this.parseFor(node, init);694 case _.tokTypes._function:695 this.next();696 return this.parseFunction(node, true);697 case _.tokTypes._if:698 this.next();699 node.test = this.parseParenExpression();700 node.consequent = this.parseStatement();701 node.alternate = this.eat(_.tokTypes._else) ? this.parseStatement() : null;702 return this.finishNode(node, "IfStatement");703 case _.tokTypes._return:704 this.next();705 if (this.eat(_.tokTypes.semi) || this.canInsertSemicolon()) node.argument = null;else {706 node.argument = this.parseExpression();this.semicolon();707 }708 return this.finishNode(node, "ReturnStatement");709 case _.tokTypes._switch:710 var blockIndent = this.curIndent,711 line = this.curLineStart;712 this.next();713 node.discriminant = this.parseParenExpression();714 node.cases = [];715 this.pushCx();716 this.expect(_.tokTypes.braceL);717 var cur = undefined;718 while (!this.closes(_.tokTypes.braceR, blockIndent, line, true)) {719 if (this.tok.type === _.tokTypes._case || this.tok.type === _.tokTypes._default) {720 var isCase = this.tok.type === _.tokTypes._case;721 if (cur) this.finishNode(cur, "SwitchCase");722 node.cases.push(cur = this.startNode());723 cur.consequent = [];724 this.next();725 if (isCase) cur.test = this.parseExpression();else cur.test = null;726 this.expect(_.tokTypes.colon);727 } else {728 if (!cur) {729 node.cases.push(cur = this.startNode());730 cur.consequent = [];731 cur.test = null;732 }733 cur.consequent.push(this.parseStatement());734 }735 }736 if (cur) this.finishNode(cur, "SwitchCase");737 this.popCx();738 this.eat(_.tokTypes.braceR);739 return this.finishNode(node, "SwitchStatement");740 case _.tokTypes._throw:741 this.next();742 node.argument = this.parseExpression();743 this.semicolon();744 return this.finishNode(node, "ThrowStatement");745 case _.tokTypes._try:746 this.next();747 node.block = this.parseBlock();748 node.handler = null;749 if (this.tok.type === _.tokTypes._catch) {750 var clause = this.startNode();751 this.next();752 this.expect(_.tokTypes.parenL);753 clause.param = this.toAssignable(this.parseExprAtom(), true);754 this.expect(_.tokTypes.parenR);755 clause.guard = null;756 clause.body = this.parseBlock();757 node.handler = this.finishNode(clause, "CatchClause");758 }759 node.finalizer = this.eat(_.tokTypes._finally) ? this.parseBlock() : null;760 if (!node.handler && !node.finalizer) return node.block;761 return this.finishNode(node, "TryStatement");762 case _.tokTypes._var:763 case _.tokTypes._let:764 case _.tokTypes._const:765 return this.parseVar();766 case _.tokTypes._while:767 this.next();768 node.test = this.parseParenExpression();769 node.body = this.parseStatement();770 return this.finishNode(node, "WhileStatement");771 case _.tokTypes._with:772 this.next();773 node.object = this.parseParenExpression();774 node.body = this.parseStatement();775 return this.finishNode(node, "WithStatement");776 case _.tokTypes.braceL:777 return this.parseBlock();778 case _.tokTypes.semi:779 this.next();780 return this.finishNode(node, "EmptyStatement");781 case _.tokTypes._class:782 return this.parseClass(true);783 case _.tokTypes._import:784 return this.parseImport();785 case _.tokTypes._export:786 return this.parseExport();787 default:788 var expr = this.parseExpression();789 if (_parseutil.isDummy(expr)) {790 this.next();791 if (this.tok.type === _.tokTypes.eof) return this.finishNode(node, "EmptyStatement");792 return this.parseStatement();793 } else if (starttype === _.tokTypes.name && expr.type === "Identifier" && this.eat(_.tokTypes.colon)) {794 node.body = this.parseStatement();795 node.label = expr;796 return this.finishNode(node, "LabeledStatement");797 } else {798 node.expression = expr;799 this.semicolon();800 return this.finishNode(node, "ExpressionStatement");801 }802 }803};804lp.parseBlock = function () {805 var node = this.startNode();806 this.pushCx();807 this.expect(_.tokTypes.braceL);808 var blockIndent = this.curIndent,809 line = this.curLineStart;810 node.body = [];811 while (!this.closes(_.tokTypes.braceR, blockIndent, line, true)) node.body.push(this.parseStatement());812 this.popCx();813 this.eat(_.tokTypes.braceR);814 return this.finishNode(node, "BlockStatement");815};816lp.parseFor = function (node, init) {817 node.init = init;818 node.test = node.update = null;819 if (this.eat(_.tokTypes.semi) && this.tok.type !== _.tokTypes.semi) node.test = this.parseExpression();820 if (this.eat(_.tokTypes.semi) && this.tok.type !== _.tokTypes.parenR) node.update = this.parseExpression();821 this.popCx();822 this.expect(_.tokTypes.parenR);823 node.body = this.parseStatement();824 return this.finishNode(node, "ForStatement");825};826lp.parseForIn = function (node, init) {827 var type = this.tok.type === _.tokTypes._in ? "ForInStatement" : "ForOfStatement";828 this.next();829 node.left = init;830 node.right = this.parseExpression();831 this.popCx();832 this.expect(_.tokTypes.parenR);833 node.body = this.parseStatement();834 return this.finishNode(node, type);835};836lp.parseVar = function (noIn) {837 var node = this.startNode();838 node.kind = this.tok.type.keyword;839 this.next();840 node.declarations = [];841 do {842 var decl = this.startNode();843 decl.id = this.options.ecmaVersion >= 6 ? this.toAssignable(this.parseExprAtom(), true) : this.parseIdent();844 decl.init = this.eat(_.tokTypes.eq) ? this.parseMaybeAssign(noIn) : null;845 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));846 } while (this.eat(_.tokTypes.comma));847 if (!node.declarations.length) {848 var decl = this.startNode();849 decl.id = this.dummyIdent();850 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));851 }852 if (!noIn) this.semicolon();853 return this.finishNode(node, "VariableDeclaration");854};855lp.parseClass = function (isStatement) {856 var node = this.startNode();857 this.next();858 if (this.tok.type === _.tokTypes.name) node.id = this.parseIdent();else if (isStatement) node.id = this.dummyIdent();else node.id = null;859 node.superClass = this.eat(_.tokTypes._extends) ? this.parseExpression() : null;860 node.body = this.startNode();861 node.body.body = [];862 this.pushCx();863 var indent = this.curIndent + 1,864 line = this.curLineStart;865 this.eat(_.tokTypes.braceL);866 if (this.curIndent + 1 < indent) {867 indent = this.curIndent;line = this.curLineStart;868 }869 while (!this.closes(_.tokTypes.braceR, indent, line)) {870 if (this.semicolon()) continue;871 var method = this.startNode(),872 isGenerator = undefined;873 if (this.options.ecmaVersion >= 6) {874 method["static"] = false;875 isGenerator = this.eat(_.tokTypes.star);876 }877 this.parsePropertyName(method);878 if (_parseutil.isDummy(method.key)) {879 if (_parseutil.isDummy(this.parseMaybeAssign())) this.next();this.eat(_.tokTypes.comma);continue;880 }881 if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" && (this.tok.type != _.tokTypes.parenL && this.tok.type != _.tokTypes.braceL)) {882 method["static"] = true;883 isGenerator = this.eat(_.tokTypes.star);884 this.parsePropertyName(method);885 } else {886 method["static"] = false;887 }888 if (this.options.ecmaVersion >= 5 && method.key.type === "Identifier" && !method.computed && (method.key.name === "get" || method.key.name === "set") && this.tok.type !== _.tokTypes.parenL && this.tok.type !== _.tokTypes.braceL) {889 method.kind = method.key.name;890 this.parsePropertyName(method);891 method.value = this.parseMethod(false);892 } else {893 if (!method.computed && !method["static"] && !isGenerator && (method.key.type === "Identifier" && method.key.name === "constructor" || method.key.type === "Literal" && method.key.value === "constructor")) {894 method.kind = "constructor";895 } else {896 method.kind = "method";897 }898 method.value = this.parseMethod(isGenerator);899 }900 node.body.body.push(this.finishNode(method, "MethodDefinition"));901 }902 this.popCx();903 if (!this.eat(_.tokTypes.braceR)) {904 // If there is no closing brace, make the node span to the start905 // of the next token (this is useful for Tern)906 this.last.end = this.tok.start;907 if (this.options.locations) this.last.loc.end = this.tok.loc.start;908 }909 this.semicolon();910 this.finishNode(node.body, "ClassBody");911 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");912};913lp.parseFunction = function (node, isStatement) {914 this.initFunction(node);915 if (this.options.ecmaVersion >= 6) {916 node.generator = this.eat(_.tokTypes.star);917 }918 if (this.tok.type === _.tokTypes.name) node.id = this.parseIdent();else if (isStatement) node.id = this.dummyIdent();919 node.params = this.parseFunctionParams();920 node.body = this.parseBlock();921 return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");922};923lp.parseExport = function () {924 var node = this.startNode();925 this.next();926 if (this.eat(_.tokTypes.star)) {927 node.source = this.eatContextual("from") ? this.parseExprAtom() : null;928 return this.finishNode(node, "ExportAllDeclaration");929 }930 if (this.eat(_.tokTypes._default)) {931 var expr = this.parseMaybeAssign();932 if (expr.id) {933 switch (expr.type) {934 case "FunctionExpression":935 expr.type = "FunctionDeclaration";break;936 case "ClassExpression":937 expr.type = "ClassDeclaration";break;938 }939 }940 node.declaration = expr;941 this.semicolon();942 return this.finishNode(node, "ExportDefaultDeclaration");943 }944 if (this.tok.type.keyword) {945 node.declaration = this.parseStatement();946 node.specifiers = [];947 node.source = null;948 } else {949 node.declaration = null;950 node.specifiers = this.parseExportSpecifierList();951 node.source = this.eatContextual("from") ? this.parseExprAtom() : null;952 this.semicolon();953 }954 return this.finishNode(node, "ExportNamedDeclaration");955};956lp.parseImport = function () {957 var node = this.startNode();958 this.next();959 if (this.tok.type === _.tokTypes.string) {960 node.specifiers = [];961 node.source = this.parseExprAtom();962 node.kind = "";963 } else {964 var elt = undefined;965 if (this.tok.type === _.tokTypes.name && this.tok.value !== "from") {966 elt = this.startNode();967 elt.local = this.parseIdent();968 this.finishNode(elt, "ImportDefaultSpecifier");969 this.eat(_.tokTypes.comma);970 }971 node.specifiers = this.parseImportSpecifierList();972 node.source = this.eatContextual("from") ? this.parseExprAtom() : null;973 if (elt) node.specifiers.unshift(elt);974 }975 this.semicolon();976 return this.finishNode(node, "ImportDeclaration");977};978lp.parseImportSpecifierList = function () {979 var elts = [];980 if (this.tok.type === _.tokTypes.star) {981 var elt = this.startNode();982 this.next();983 if (this.eatContextual("as")) elt.local = this.parseIdent();984 elts.push(this.finishNode(elt, "ImportNamespaceSpecifier"));985 } else {986 var indent = this.curIndent,987 line = this.curLineStart,988 continuedLine = this.nextLineStart;989 this.pushCx();990 this.eat(_.tokTypes.braceL);991 if (this.curLineStart > continuedLine) continuedLine = this.curLineStart;992 while (!this.closes(_.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {993 var elt = this.startNode();994 if (this.eat(_.tokTypes.star)) {995 if (this.eatContextual("as")) elt.local = this.parseIdent();996 this.finishNode(elt, "ImportNamespaceSpecifier");997 } else {998 if (this.isContextual("from")) break;999 elt.imported = this.parseIdent();1000 if (_parseutil.isDummy(elt.imported)) break;1001 elt.local = this.eatContextual("as") ? this.parseIdent() : elt.imported;1002 this.finishNode(elt, "ImportSpecifier");1003 }1004 elts.push(elt);1005 this.eat(_.tokTypes.comma);1006 }1007 this.eat(_.tokTypes.braceR);1008 this.popCx();1009 }1010 return elts;1011};1012lp.parseExportSpecifierList = function () {1013 var elts = [];1014 var indent = this.curIndent,1015 line = this.curLineStart,1016 continuedLine = this.nextLineStart;1017 this.pushCx();1018 this.eat(_.tokTypes.braceL);1019 if (this.curLineStart > continuedLine) continuedLine = this.curLineStart;1020 while (!this.closes(_.tokTypes.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {1021 if (this.isContextual("from")) break;1022 var elt = this.startNode();1023 elt.local = this.parseIdent();1024 if (_parseutil.isDummy(elt.local)) break;1025 elt.exported = this.eatContextual("as") ? this.parseIdent() : elt.local;1026 this.finishNode(elt, "ExportSpecifier");1027 elts.push(elt);1028 this.eat(_.tokTypes.comma);1029 }1030 this.eat(_.tokTypes.braceR);1031 this.popCx();1032 return elts;1033};1034},{"..":1,"./parseutil":4,"./state":5}],7:[function(_dereq_,module,exports){1035"use strict";1036var _ = _dereq_("..");1037var _state = _dereq_("./state");1038var lp = _state.LooseParser.prototype;1039function isSpace(ch) {1040 return ch < 14 && ch > 8 || ch === 32 || ch === 160 || _.isNewLine(ch);1041}1042lp.next = function () {1043 this.last = this.tok;1044 if (this.ahead.length) this.tok = this.ahead.shift();else this.tok = this.readToken();1045 if (this.tok.start >= this.nextLineStart) {1046 while (this.tok.start >= this.nextLineStart) {1047 this.curLineStart = this.nextLineStart;1048 this.nextLineStart = this.lineEnd(this.curLineStart) + 1;1049 }1050 this.curIndent = this.indentationAfter(this.curLineStart);1051 }1052};1053lp.readToken = function () {1054 for (;;) {1055 try {1056 this.toks.next();1057 if (this.toks.type === _.tokTypes.dot && this.input.substr(this.toks.end, 1) === "." && this.options.ecmaVersion >= 6) {1058 this.toks.end++;1059 this.toks.type = _.tokTypes.ellipsis;1060 }1061 return new _.Token(this.toks);1062 } catch (e) {1063 if (!(e instanceof SyntaxError)) throw e;1064 // Try to skip some text, based on the error message, and then continue1065 var msg = e.message,1066 pos = e.raisedAt,1067 replace = true;1068 if (/unterminated/i.test(msg)) {1069 pos = this.lineEnd(e.pos + 1);1070 if (/string/.test(msg)) {1071 replace = { start: e.pos, end: pos, type: _.tokTypes.string, value: this.input.slice(e.pos + 1, pos) };1072 } else if (/regular expr/i.test(msg)) {1073 var re = this.input.slice(e.pos, pos);1074 try {1075 re = new RegExp(re);1076 } catch (e) {}1077 replace = { start: e.pos, end: pos, type: _.tokTypes.regexp, value: re };1078 } else if (/template/.test(msg)) {1079 replace = { start: e.pos, end: pos,1080 type: _.tokTypes.template,1081 value: this.input.slice(e.pos, pos) };1082 } else {1083 replace = false;1084 }1085 } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) {1086 while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos;1087 } else if (/character escape|expected hexadecimal/i.test(msg)) {1088 while (pos < this.input.length) {1089 var ch = this.input.charCodeAt(pos++);1090 if (ch === 34 || ch === 39 || _.isNewLine(ch)) break;1091 }1092 } else if (/unexpected character/i.test(msg)) {1093 pos++;1094 replace = false;1095 } else if (/regular expression/i.test(msg)) {1096 replace = true;1097 } else {1098 throw e;1099 }1100 this.resetTo(pos);1101 if (replace === true) replace = { start: pos, end: pos, type: _.tokTypes.name, value: "â" };1102 if (replace) {1103 if (this.options.locations) replace.loc = new _.SourceLocation(this.toks, _.getLineInfo(this.input, replace.start), _.getLineInfo(this.input, replace.end));1104 return replace;1105 }1106 }1107 }1108};1109lp.resetTo = function (pos) {1110 this.toks.pos = pos;1111 var ch = this.input.charAt(pos - 1);1112 this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) || /[enwfd]/.test(ch) && /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos));1113 if (this.options.locations) {1114 this.toks.curLine = 1;1115 this.toks.lineStart = _.lineBreakG.lastIndex = 0;1116 var match = undefined;1117 while ((match = _.lineBreakG.exec(this.input)) && match.index < pos) {1118 ++this.toks.curLine;1119 this.toks.lineStart = match.index + match[0].length;1120 }1121 }1122};1123lp.lookAhead = function (n) {1124 while (n > this.ahead.length) this.ahead.push(this.readToken());1125 return this.ahead[n - 1];1126};1127},{"..":1,"./state":5}]},{},[3])(3)...
index.js
Source:index.js
1/*!2 * parse-glob <https://github.com/jonschlinkert/parse-glob>3 *4 * Copyright (c) 2015, Jon Schlinkert.5 * Licensed under the MIT License.6 */7'use strict';8var isGlob = require('is-glob');9var findBase = require('glob-base');10var extglob = require('is-extglob');11var dotfile = require('is-dotfile');12/**13 * Expose `cache`14 */15var cache = module.exports.cache = {};16/**17 * Parse a glob pattern into tokens.18 *19 * When no paths or '**' are in the glob, we use a20 * different strategy for parsing the filename, since21 * file names can contain braces and other difficult22 * patterns. such as:23 *24 * - `*.{a,b}`25 * - `(**|*.js)`26 */27module.exports = function parseGlob(glob) {28 if (cache.hasOwnProperty(glob)) {29 return cache[glob];30 }31 var tok = {};32 tok.orig = glob;33 tok.is = {};34 // unescape dots and slashes in braces/brackets35 glob = escape(glob);36 var parsed = findBase(glob);37 tok.is.glob = parsed.isGlob;38 tok.glob = parsed.glob;39 tok.base = parsed.base;40 var segs = /([^\/]*)$/.exec(glob);41 tok.path = {};42 tok.path.dirname = '';43 tok.path.basename = segs[1] || '';44 tok.path.dirname = glob.split(tok.path.basename).join('') || '';45 var basename = (tok.path.basename || '').split('.') || '';46 tok.path.filename = basename[0] || '';47 tok.path.extname = basename.slice(1).join('.') || '';48 tok.path.ext = '';49 if (isGlob(tok.path.dirname) && !tok.path.basename) {50 if (!/\/$/.test(tok.glob)) {51 tok.path.basename = tok.glob;52 }53 tok.path.dirname = tok.base;54 }55 if (glob.indexOf('/') === -1 && !tok.is.globstar) {56 tok.path.dirname = '';57 tok.path.basename = tok.orig;58 }59 var dot = tok.path.basename.indexOf('.');60 if (dot !== -1) {61 tok.path.filename = tok.path.basename.slice(0, dot);62 tok.path.extname = tok.path.basename.slice(dot);63 }64 if (tok.path.extname.charAt(0) === '.') {65 var exts = tok.path.extname.split('.');66 tok.path.ext = exts[exts.length - 1];67 }68 // unescape dots and slashes in braces/brackets69 tok.glob = unescape(tok.glob);70 tok.path.dirname = unescape(tok.path.dirname);71 tok.path.basename = unescape(tok.path.basename);72 tok.path.filename = unescape(tok.path.filename);73 tok.path.extname = unescape(tok.path.extname);74 // Booleans75 var is = (glob && tok.is.glob);76 tok.is.negated = glob && glob.charAt(0) === '!';77 tok.is.extglob = glob && extglob(glob);78 tok.is.braces = has(is, glob, '{');79 tok.is.brackets = has(is, glob, '[:');80 tok.is.globstar = has(is, glob, '**');81 tok.is.dotfile = dotfile(tok.path.basename) || dotfile(tok.path.filename);82 tok.is.dotdir = dotdir(tok.path.dirname);83 return (cache[glob] = tok);84}85/**86 * Returns true if the glob matches dot-directories.87 *88 * @param {Object} `tok` The tokens object89 * @param {Object} `path` The path object90 * @return {Object}91 */92function dotdir(base) {93 if (base.indexOf('/.') !== -1) {94 return true;95 }96 if (base.charAt(0) === '.' && base.charAt(1) !== '/') {97 return true;98 }99 return false;100}101/**102 * Returns true if the pattern has the given `ch`aracter(s)103 *104 * @param {Object} `glob` The glob pattern.105 * @param {Object} `ch` The character to test for106 * @return {Object}107 */108function has(is, glob, ch) {109 return is && glob.indexOf(ch) !== -1;110}111/**112 * Escape/unescape utils113 */114function escape(str) {115 var re = /\{([^{}]*?)}|\(([^()]*?)\)|\[([^\[\]]*?)\]/g;116 return str.replace(re, function (outter, braces, parens, brackets) {117 var inner = braces || parens || brackets;118 if (!inner) { return outter; }119 return outter.split(inner).join(esc(inner));120 });121}122function esc(str) {123 str = str.split('/').join('__SLASH__');124 str = str.split('.').join('__DOT__');125 return str;126}127function unescape(str) {128 str = str.split('__SLASH__').join('/');129 str = str.split('__DOT__').join('.');130 return str;...
Using AI Code Generation
1var webdriver = require('selenium-webdriver');2var By = webdriver.By;3var until = webdriver.until;4var wpt = require('webpagetest');5var driver = new webdriver.Builder()6 .forBrowser('chrome')7 .build();8var options = {9};10 if (err) {11 console.log(err);12 return;13 }14 console.log(data);15 console.log('Test ID: ' + data.data.testId);16 console.log('Test URL: ' + data.data.summary);17 console.log('Test Video: ' + data.data.video);18 console.log('Test Timeline: ' + data.data.timeline);19 console.log('Test Image: ' + data.data.userUrl);20 console.log('Test JSON: ' + data.data.jsonUrl);21 console.log('Test CSV: ' + data.data.csvUrl);22 console.log('Test XML: ' + data.data.xmlUrl);23 console.log('Test HTML: ' + data.data.userUrl);24});
Using AI Code Generation
1var fs = require('fs');2var wptokenizer = require('./wptokenizer.js');3var text = fs.readFileSync('test.txt', 'utf8');4var tokens = wptokenizer.tok(text);5var out = "";6for (var i=0; i<tokens.length; i++) {7 out += tokens[i].token + "\n";8}9fs.writeFileSync('test_tok.txt', out, 'utf8');10var wtp = require('wtf_wikipedia');11function tok(text) {12 var doc = wtp.parse(text);13 var tokens = [];14 for (var i=0; i<doc.sections.length; i++) {15 var section = doc.sections[i];16 if (section.templates.length>0) {17 for (var j=0; j<section.templates.length; j++) {18 var template = section.templates[j];19 var token = template.template;20 tokens.push({token: token, type: "template"});21 }22 }23 if (section.lists.length>0) {24 for (var j=0; j<section.lists.length; j++) {25 var list = section.lists[j];26 for (var k=0; k<list.items.length; k++) {27 var item = list.items[k];28 var token = item.text;29 tokens.push({token: token, type: "listitem"});30 }31 }32 }33 if (section.tables.length>0) {34 for (var j=0; j<section.tables.length; j
Using AI Code Generation
1var wpt = new WebPageTest('www.webpagetest.org', 'A.6d1f6b8f6b0a6b0f6b0a6b0a6b0f6b0a');2wpt.runTest(url, function(err, data) {3 if (err) return console.error(err);4 console.log('Test submitted to WebPageTest! Check back later for results.');5 console.log('Test ID: ' + data.data.testId);6 console.log('Test status polling URL: ' + data.data.userUrl);7});8var wpt = new WebPageTest('www.webpagetest.org', 'A.6d1f6b8f6b0a6b0f6b0a6b0a6b0f6b0a');
Using AI Code Generation
1var wpt = require('./lib/webpagetest.js');2var wpt = new wpt('A.5a0c5f6d3e0c3a3d2a1c0b2f0d6a5b1f');3 if (err) {4 console.log(err);5 } else {6 console.log('Test submitted. Poll for results at:');7 }8});
Using AI Code Generation
1var WebPageTest = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org','A.2d0b1c2b5f5f0d5e9e9b9a8b1a7a9c6d');3 if (err) return console.error(err);4 console.log('Test Submitted. Polling for results...');5 wpt.getTestResults(data.data.testId, function(err, data) {6 if (err) return console.error(err);7 console.log('Speed Index:', data.data.average.firstView.SpeedIndex);8 console.log('Fully Loaded:', data.data.average.firstView.fullyLoaded);9 });10});
Using AI Code Generation
1const wpt = require('webpagetest');2const tok = 'A.1f8b25c3f3d9d1e3d3b8f3b6d3e8e3d3';3const options = {4};5const webpagetest = new wpt(options);6 if (err) {7 console.log(err);8 } else {9 console.log(data);10 }11});12}, function (err, data) {13 if (err) {14 console.log(err);15 } else {16 console.log(data);17 }18});19webpagetest.getTestResults('170701_3T_7b6a3e9f9b2d2b8a7c1f1d4d7e1e4d4e', function (err, data) {20 if (err) {21 console.log(err);22 } else {23 console.log(data);24 }25});26webpagetest.getTestStatus('170701_3T_7b6a3e9f9b2d2b8a7c1f1d4d7e1e4d4e', function (err, data) {27 if (err) {28 console.log(err);29 } else {30 console.log(data);31 }32});33webpagetest.getLocations(function (err, data) {34 if (err) {35 console.log(err);36 } else {37 console.log(data);38 }39});40webpagetest.getTesters(function (err, data) {41 if (err) {42 console.log(err);43 }
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!