| /******/ (() => { // webpackBootstrap |
| /******/ "use strict"; |
| /******/ var __webpack_modules__ = ({ |
| |
| /***/ "./node_modules/esprima-next/dist/esprima.js": |
| /*!***************************************************!*\ |
| !*** ./node_modules/esprima-next/dist/esprima.js ***! |
| \***************************************************/ |
| /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { |
| |
| __webpack_require__.r(__webpack_exports__); |
| /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| /* harmony export */ ArrayExpression: () => (/* binding */ ArrayExpression), |
| /* harmony export */ ArrayPattern: () => (/* binding */ ArrayPattern), |
| /* harmony export */ ArrowFunctionExpression: () => (/* binding */ ArrowFunctionExpression), |
| /* harmony export */ AssignmentExpression: () => (/* binding */ AssignmentExpression), |
| /* harmony export */ AssignmentPattern: () => (/* binding */ AssignmentPattern), |
| /* harmony export */ AsyncFunctionDeclaration: () => (/* binding */ AsyncFunctionDeclaration), |
| /* harmony export */ AwaitExpression: () => (/* binding */ AwaitExpression), |
| /* harmony export */ BigIntLiteral: () => (/* binding */ BigIntLiteral), |
| /* harmony export */ BinaryExpression: () => (/* binding */ BinaryExpression), |
| /* harmony export */ BlockStatement: () => (/* binding */ BlockStatement), |
| /* harmony export */ BreakStatement: () => (/* binding */ BreakStatement), |
| /* harmony export */ CallExpression: () => (/* binding */ CallExpression), |
| /* harmony export */ CatchClause: () => (/* binding */ CatchClause), |
| /* harmony export */ ChainExpression: () => (/* binding */ ChainExpression), |
| /* harmony export */ ClassBody: () => (/* binding */ ClassBody), |
| /* harmony export */ ClassDeclaration: () => (/* binding */ ClassDeclaration), |
| /* harmony export */ ClassExpression: () => (/* binding */ ClassExpression), |
| /* harmony export */ ConditionalExpression: () => (/* binding */ ConditionalExpression), |
| /* harmony export */ ContinueStatement: () => (/* binding */ ContinueStatement), |
| /* harmony export */ DebuggerStatement: () => (/* binding */ DebuggerStatement), |
| /* harmony export */ Decorator: () => (/* binding */ Decorator), |
| /* harmony export */ Directive: () => (/* binding */ Directive), |
| /* harmony export */ DoWhileStatement: () => (/* binding */ DoWhileStatement), |
| /* harmony export */ EmptyStatement: () => (/* binding */ EmptyStatement), |
| /* harmony export */ ExportAllDeclaration: () => (/* binding */ ExportAllDeclaration), |
| /* harmony export */ ExportDefaultDeclaration: () => (/* binding */ ExportDefaultDeclaration), |
| /* harmony export */ ExportNamedDeclaration: () => (/* binding */ ExportNamedDeclaration), |
| /* harmony export */ ExportSpecifier: () => (/* binding */ ExportSpecifier), |
| /* harmony export */ ExpressionStatement: () => (/* binding */ ExpressionStatement), |
| /* harmony export */ ForInStatement: () => (/* binding */ ForInStatement), |
| /* harmony export */ ForOfStatement: () => (/* binding */ ForOfStatement), |
| /* harmony export */ ForStatement: () => (/* binding */ ForStatement), |
| /* harmony export */ FunctionDeclaration: () => (/* binding */ FunctionDeclaration), |
| /* harmony export */ FunctionExpression: () => (/* binding */ FunctionExpression), |
| /* harmony export */ Identifier: () => (/* binding */ Identifier), |
| /* harmony export */ IfStatement: () => (/* binding */ IfStatement), |
| /* harmony export */ ImportAttribute: () => (/* binding */ ImportAttribute), |
| /* harmony export */ ImportDeclaration: () => (/* binding */ ImportDeclaration), |
| /* harmony export */ ImportDefaultSpecifier: () => (/* binding */ ImportDefaultSpecifier), |
| /* harmony export */ ImportExpression: () => (/* binding */ ImportExpression), |
| /* harmony export */ ImportNamespaceSpecifier: () => (/* binding */ ImportNamespaceSpecifier), |
| /* harmony export */ ImportSpecifier: () => (/* binding */ ImportSpecifier), |
| /* harmony export */ LabeledStatement: () => (/* binding */ LabeledStatement), |
| /* harmony export */ Literal: () => (/* binding */ Literal), |
| /* harmony export */ LogicalExpression: () => (/* binding */ LogicalExpression), |
| /* harmony export */ MemberExpression: () => (/* binding */ MemberExpression), |
| /* harmony export */ MetaProperty: () => (/* binding */ MetaProperty), |
| /* harmony export */ MethodDefinition: () => (/* binding */ MethodDefinition), |
| /* harmony export */ Module: () => (/* binding */ Module), |
| /* harmony export */ NewExpression: () => (/* binding */ NewExpression), |
| /* harmony export */ Nodes: () => (/* binding */ nodes_exports), |
| /* harmony export */ ObjectExpression: () => (/* binding */ ObjectExpression), |
| /* harmony export */ ObjectPattern: () => (/* binding */ ObjectPattern), |
| /* harmony export */ PrivateIdentifier: () => (/* binding */ PrivateIdentifier), |
| /* harmony export */ Program: () => (/* binding */ Program), |
| /* harmony export */ Property: () => (/* binding */ Property), |
| /* harmony export */ PropertyDefinition: () => (/* binding */ PropertyDefinition), |
| /* harmony export */ RegexLiteral: () => (/* binding */ RegexLiteral), |
| /* harmony export */ RestElement: () => (/* binding */ RestElement), |
| /* harmony export */ ReturnStatement: () => (/* binding */ ReturnStatement), |
| /* harmony export */ Script: () => (/* binding */ Script), |
| /* harmony export */ SequenceExpression: () => (/* binding */ SequenceExpression), |
| /* harmony export */ SpreadElement: () => (/* binding */ SpreadElement), |
| /* harmony export */ StaticBlock: () => (/* binding */ StaticBlock), |
| /* harmony export */ Super: () => (/* binding */ Super), |
| /* harmony export */ SwitchCase: () => (/* binding */ SwitchCase), |
| /* harmony export */ SwitchStatement: () => (/* binding */ SwitchStatement), |
| /* harmony export */ Syntax: () => (/* binding */ Syntax), |
| /* harmony export */ TaggedTemplateExpression: () => (/* binding */ TaggedTemplateExpression), |
| /* harmony export */ TemplateElement: () => (/* binding */ TemplateElement), |
| /* harmony export */ TemplateLiteral: () => (/* binding */ TemplateLiteral), |
| /* harmony export */ ThisExpression: () => (/* binding */ ThisExpression), |
| /* harmony export */ ThrowStatement: () => (/* binding */ ThrowStatement), |
| /* harmony export */ TryStatement: () => (/* binding */ TryStatement), |
| /* harmony export */ UnaryExpression: () => (/* binding */ UnaryExpression), |
| /* harmony export */ UpdateExpression: () => (/* binding */ UpdateExpression), |
| /* harmony export */ VariableDeclaration: () => (/* binding */ VariableDeclaration), |
| /* harmony export */ VariableDeclarator: () => (/* binding */ VariableDeclarator), |
| /* harmony export */ Visitor: () => (/* binding */ Visitor), |
| /* harmony export */ WhileStatement: () => (/* binding */ WhileStatement), |
| /* harmony export */ WithStatement: () => (/* binding */ WithStatement), |
| /* harmony export */ YieldExpression: () => (/* binding */ YieldExpression), |
| /* harmony export */ "default": () => (/* binding */ esprima_default), |
| /* harmony export */ parse: () => (/* binding */ parse), |
| /* harmony export */ parseModule: () => (/* binding */ parseModule), |
| /* harmony export */ parseScript: () => (/* binding */ parseScript), |
| /* harmony export */ tokenize: () => (/* binding */ tokenize), |
| /* harmony export */ version: () => (/* binding */ version) |
| /* harmony export */ }); |
| var __defProp = Object.defineProperty; |
| var __export = (target, all) => { |
| for (var name in all) |
| __defProp(target, name, { get: all[name], enumerable: true }); |
| }; |
| |
| // src/syntax.ts |
| var Syntax = /* @__PURE__ */ ((Syntax2) => { |
| Syntax2["AssignmentExpression"] = "AssignmentExpression"; |
| Syntax2["AssignmentPattern"] = "AssignmentPattern"; |
| Syntax2["ArrayExpression"] = "ArrayExpression"; |
| Syntax2["ArrayPattern"] = "ArrayPattern"; |
| Syntax2["ArrowFunctionExpression"] = "ArrowFunctionExpression"; |
| Syntax2["AwaitExpression"] = "AwaitExpression"; |
| Syntax2["BlockStatement"] = "BlockStatement"; |
| Syntax2["BinaryExpression"] = "BinaryExpression"; |
| Syntax2["BreakStatement"] = "BreakStatement"; |
| Syntax2["CallExpression"] = "CallExpression"; |
| Syntax2["CatchClause"] = "CatchClause"; |
| Syntax2["ChainExpression"] = "ChainExpression"; |
| Syntax2["ClassBody"] = "ClassBody"; |
| Syntax2["ClassDeclaration"] = "ClassDeclaration"; |
| Syntax2["ClassExpression"] = "ClassExpression"; |
| Syntax2["ConditionalExpression"] = "ConditionalExpression"; |
| Syntax2["ContinueStatement"] = "ContinueStatement"; |
| Syntax2["Decorator"] = "Decorator"; |
| Syntax2["DoWhileStatement"] = "DoWhileStatement"; |
| Syntax2["DebuggerStatement"] = "DebuggerStatement"; |
| Syntax2["EmptyStatement"] = "EmptyStatement"; |
| Syntax2["ExportAllDeclaration"] = "ExportAllDeclaration"; |
| Syntax2["ExportDefaultDeclaration"] = "ExportDefaultDeclaration"; |
| Syntax2["ExportNamedDeclaration"] = "ExportNamedDeclaration"; |
| Syntax2["ExportSpecifier"] = "ExportSpecifier"; |
| Syntax2["ExpressionStatement"] = "ExpressionStatement"; |
| Syntax2["ForStatement"] = "ForStatement"; |
| Syntax2["ForOfStatement"] = "ForOfStatement"; |
| Syntax2["ForInStatement"] = "ForInStatement"; |
| Syntax2["FunctionDeclaration"] = "FunctionDeclaration"; |
| Syntax2["FunctionExpression"] = "FunctionExpression"; |
| Syntax2["Identifier"] = "Identifier"; |
| Syntax2["IfStatement"] = "IfStatement"; |
| Syntax2["ImportAttribute"] = "ImportAttribute"; |
| Syntax2["ImportExpression"] = "ImportExpression"; |
| Syntax2["ImportDeclaration"] = "ImportDeclaration"; |
| Syntax2["ImportDefaultSpecifier"] = "ImportDefaultSpecifier"; |
| Syntax2["ImportNamespaceSpecifier"] = "ImportNamespaceSpecifier"; |
| Syntax2["ImportSpecifier"] = "ImportSpecifier"; |
| Syntax2["Literal"] = "Literal"; |
| Syntax2["LabeledStatement"] = "LabeledStatement"; |
| Syntax2["LogicalExpression"] = "LogicalExpression"; |
| Syntax2["MemberExpression"] = "MemberExpression"; |
| Syntax2["MetaProperty"] = "MetaProperty"; |
| Syntax2["MethodDefinition"] = "MethodDefinition"; |
| Syntax2["NewExpression"] = "NewExpression"; |
| Syntax2["ObjectExpression"] = "ObjectExpression"; |
| Syntax2["ObjectPattern"] = "ObjectPattern"; |
| Syntax2["Program"] = "Program"; |
| Syntax2["Property"] = "Property"; |
| Syntax2["PrivateIdentifier"] = "PrivateIdentifier"; |
| Syntax2["RestElement"] = "RestElement"; |
| Syntax2["ReturnStatement"] = "ReturnStatement"; |
| Syntax2["SequenceExpression"] = "SequenceExpression"; |
| Syntax2["SpreadElement"] = "SpreadElement"; |
| Syntax2["StaticBlock"] = "StaticBlock"; |
| Syntax2["Super"] = "Super"; |
| Syntax2["SwitchCase"] = "SwitchCase"; |
| Syntax2["SwitchStatement"] = "SwitchStatement"; |
| Syntax2["TaggedTemplateExpression"] = "TaggedTemplateExpression"; |
| Syntax2["TemplateElement"] = "TemplateElement"; |
| Syntax2["TemplateLiteral"] = "TemplateLiteral"; |
| Syntax2["ThisExpression"] = "ThisExpression"; |
| Syntax2["ThrowStatement"] = "ThrowStatement"; |
| Syntax2["TryStatement"] = "TryStatement"; |
| Syntax2["UnaryExpression"] = "UnaryExpression"; |
| Syntax2["UpdateExpression"] = "UpdateExpression"; |
| Syntax2["VariableDeclaration"] = "VariableDeclaration"; |
| Syntax2["VariableDeclarator"] = "VariableDeclarator"; |
| Syntax2["WhileStatement"] = "WhileStatement"; |
| Syntax2["WithStatement"] = "WithStatement"; |
| Syntax2["YieldExpression"] = "YieldExpression"; |
| return Syntax2; |
| })(Syntax || {}); |
| |
| // src/comment-handler.ts |
| var CommentHandler = class { |
| attach; |
| comments; |
| stack; |
| leading; |
| trailing; |
| constructor() { |
| this.attach = false; |
| this.comments = []; |
| this.stack = []; |
| this.leading = []; |
| this.trailing = []; |
| } |
| insertInnerComments(node, metadata) { |
| if (node.type === "BlockStatement" /* BlockStatement */ && node.body.length === 0) { |
| const innerComments = []; |
| for (let i = this.leading.length - 1; i >= 0; --i) { |
| const entry = this.leading[i]; |
| if (metadata.end.offset >= entry.start) { |
| innerComments.unshift(entry.comment); |
| this.leading.splice(i, 1); |
| this.trailing.splice(i, 1); |
| } |
| } |
| if (innerComments.length) { |
| node.innerComments = innerComments; |
| } |
| } |
| } |
| findTrailingComments(metadata) { |
| let trailingComments = []; |
| if (this.trailing.length > 0) { |
| for (let i = this.trailing.length - 1; i >= 0; --i) { |
| const entry = this.trailing[i]; |
| if (entry.start >= metadata.end.offset) { |
| trailingComments.unshift(entry.comment); |
| } |
| } |
| this.trailing.length = 0; |
| return trailingComments; |
| } |
| const last = this.stack[this.stack.length - 1]; |
| if (last && last.node.trailingComments) { |
| const firstComment = last.node.trailingComments[0]; |
| if (firstComment && firstComment.range[0] >= metadata.end.offset) { |
| trailingComments = last.node.trailingComments; |
| delete last.node.trailingComments; |
| } |
| } |
| return trailingComments; |
| } |
| findLeadingComments(metadata) { |
| const leadingComments = []; |
| let target; |
| while (this.stack.length > 0) { |
| const entry = this.stack[this.stack.length - 1]; |
| if (entry && entry.start >= metadata.start.offset) { |
| target = entry.node; |
| this.stack.pop(); |
| } else { |
| break; |
| } |
| } |
| if (target) { |
| const count = target.leadingComments ? target.leadingComments.length : 0; |
| for (let i = count - 1; i >= 0; --i) { |
| const comment = target.leadingComments[i]; |
| if (comment.range[1] <= metadata.start.offset) { |
| leadingComments.unshift(comment); |
| target.leadingComments.splice(i, 1); |
| } |
| } |
| if (target.leadingComments && target.leadingComments.length === 0) { |
| delete target.leadingComments; |
| } |
| return leadingComments; |
| } |
| for (let i = this.leading.length - 1; i >= 0; --i) { |
| const entry = this.leading[i]; |
| if (entry.start <= metadata.start.offset) { |
| leadingComments.unshift(entry.comment); |
| this.leading.splice(i, 1); |
| } |
| } |
| return leadingComments; |
| } |
| visitNode(node, metadata) { |
| if (node.type === "Program" /* Program */ && node.body.length > 0) { |
| return; |
| } |
| this.insertInnerComments(node, metadata); |
| const trailingComments = this.findTrailingComments(metadata); |
| const leadingComments = this.findLeadingComments(metadata); |
| if (leadingComments.length > 0) { |
| node.leadingComments = leadingComments; |
| } |
| if (trailingComments.length > 0) { |
| node.trailingComments = trailingComments; |
| } |
| this.stack.push({ |
| node, |
| start: metadata.start.offset |
| }); |
| } |
| visitComment(node, metadata) { |
| const type = node.type[0] === "L" ? "Line" : "Block"; |
| const comment = { |
| type, |
| value: node.value |
| }; |
| if (node.range) { |
| comment.range = node.range; |
| } |
| if (node.loc) { |
| comment.loc = node.loc; |
| } |
| this.comments.push(comment); |
| if (this.attach) { |
| const entry = { |
| comment: { |
| type, |
| value: node.value, |
| range: [metadata.start.offset, metadata.end.offset] |
| }, |
| start: metadata.start.offset |
| }; |
| if (node.loc) { |
| entry.comment.loc = node.loc; |
| } |
| node.type = type; |
| this.leading.push(entry); |
| this.trailing.push(entry); |
| } |
| } |
| visit(node, metadata) { |
| if (node.type === "LineComment") { |
| this.visitComment(node, metadata); |
| } else if (node.type === "BlockComment") { |
| this.visitComment(node, metadata); |
| } else if (this.attach) { |
| this.visitNode(node, metadata); |
| } |
| } |
| }; |
| |
| // src/character.ts |
| var Regex = { |
| // Unicode v12.1.0 NonAsciiIdentifierStart: |
| NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7C6\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB67\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDEC0-\uDEEB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/, |
| // Unicode v12.1.0 NonAsciiIdentifierPart: |
| // eslint-disable-next-line no-misleading-character-class |
| NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05EF-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u07FD\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D3-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u09FE\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1878\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CD0-\u1CD2\u1CD4-\u1CFA\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7C6\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB67\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD27\uDD30-\uDD39\uDF00-\uDF1C\uDF27\uDF30-\uDF50\uDFE0-\uDFF6]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD44-\uDD46\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDC9-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3B-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC5E\uDC5F\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDC00-\uDC3A\uDCA0-\uDCE9\uDCFF\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDE1\uDDE3\uDDE4\uDE00-\uDE3E\uDE47\uDE50-\uDE99\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF6]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD00-\uDD2C\uDD30-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4B\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ |
| }; |
| var Character = { |
| fromCodePoint(cp) { |
| return cp < 65536 ? String.fromCharCode(cp) : String.fromCharCode(55296 + (cp - 65536 >> 10)) + String.fromCharCode(56320 + (cp - 65536 & 1023)); |
| }, |
| isStringWellFormedUnicode(text) { |
| for (let i = 0; i < text.length; i++) { |
| let c = text.charCodeAt(i); |
| if (c >= 55296 && c <= 56319) { |
| if (i === text.length - 1) { |
| return false; |
| } |
| i++; |
| c = text.charCodeAt(i); |
| if (c < 56320 && c > 57343) { |
| return false; |
| } |
| } else if (c >= 56320 && c <= 57343) { |
| return false; |
| } |
| } |
| return true; |
| }, |
| // https://tc39.github.io/ecma262/#sec-white-space |
| isWhiteSpace(cp) { |
| return cp === 32 || cp === 9 || cp === 11 || cp === 12 || cp === 160 || cp >= 5760 && [5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279].indexOf(cp) >= 0; |
| }, |
| // https://tc39.github.io/ecma262/#sec-line-terminators |
| isLineTerminator(cp) { |
| return cp === 10 || cp === 13 || cp === 8232 || cp === 8233; |
| }, |
| // https://tc39.github.io/ecma262/#sec-names-and-keywords |
| isIdentifierStart(cp) { |
| return cp === 36 || cp === 95 || // $ (dollar) and _ (underscore) |
| cp >= 65 && cp <= 90 || // A..Z |
| cp >= 97 && cp <= 122 || // a..z |
| cp === 92 || // \ (backslash) |
| cp >= 128 && Regex.NonAsciiIdentifierStart.test(Character.fromCodePoint(cp)); |
| }, |
| isIdentifierPart(cp) { |
| return cp === 36 || cp === 95 || // $ (dollar) and _ (underscore) |
| cp >= 65 && cp <= 90 || // A..Z |
| cp >= 97 && cp <= 122 || // a..z |
| cp >= 48 && cp <= 57 || // 0..9 |
| cp === 92 || // \ (backslash) |
| cp >= 128 && Regex.NonAsciiIdentifierPart.test(Character.fromCodePoint(cp)); |
| }, |
| // https://tc39.github.io/ecma262/#sec-literals-numeric-literals |
| isDecimalDigit(cp) { |
| return cp >= 48 && cp <= 57; |
| }, |
| isDecimalDigitChar(ch) { |
| return ch.length === 1 && Character.isDecimalDigit(ch.charCodeAt(0)); |
| }, |
| isHexDigit(cp) { |
| return cp >= 48 && cp <= 57 || // 0..9 |
| cp >= 65 && cp <= 70 || // A..F |
| cp >= 97 && cp <= 102; |
| }, |
| isHexDigitChar(ch) { |
| return ch.length === 1 && Character.isHexDigit(ch.charCodeAt(0)); |
| }, |
| isOctalDigit(cp) { |
| return cp >= 48 && cp <= 55; |
| }, |
| isOctalDigitChar(ch) { |
| return ch.length === 1 && Character.isOctalDigit(ch.charCodeAt(0)); |
| } |
| }; |
| |
| // src/jsx-nodes.ts |
| var JSXClosingElement = class { |
| type; |
| name; |
| constructor(name) { |
| this.type = "JSXClosingElement" /* JSXClosingElement */; |
| this.name = name; |
| } |
| }; |
| var JSXClosingFragment = class { |
| type; |
| constructor() { |
| this.type = "JSXClosingFragment" /* JSXClosingFragment */; |
| } |
| }; |
| var JSXElement = class { |
| type; |
| openingElement; |
| children; |
| closingElement; |
| constructor(openingElement, children, closingElement) { |
| this.type = "JSXElement" /* JSXElement */; |
| this.openingElement = openingElement; |
| this.children = children; |
| this.closingElement = closingElement; |
| } |
| }; |
| var JSXEmptyExpression = class { |
| type; |
| constructor() { |
| this.type = "JSXEmptyExpression" /* JSXEmptyExpression */; |
| } |
| }; |
| var JSXExpressionContainer = class { |
| type; |
| expression; |
| constructor(expression) { |
| this.type = "JSXExpressionContainer" /* JSXExpressionContainer */; |
| this.expression = expression; |
| } |
| }; |
| var JSXIdentifier = class { |
| type; |
| name; |
| constructor(name) { |
| this.type = "JSXIdentifier" /* JSXIdentifier */; |
| this.name = name; |
| } |
| }; |
| var JSXMemberExpression = class { |
| type; |
| object; |
| property; |
| constructor(object, property) { |
| this.type = "JSXMemberExpression" /* JSXMemberExpression */; |
| this.object = object; |
| this.property = property; |
| } |
| }; |
| var JSXAttribute = class { |
| type; |
| name; |
| value; |
| constructor(name, value) { |
| this.type = "JSXAttribute" /* JSXAttribute */; |
| this.name = name; |
| this.value = value; |
| } |
| }; |
| var JSXNamespacedName = class { |
| type; |
| namespace; |
| name; |
| constructor(namespace, name) { |
| this.type = "JSXNamespacedName" /* JSXNamespacedName */; |
| this.namespace = namespace; |
| this.name = name; |
| } |
| }; |
| var JSXOpeningElement = class { |
| type; |
| name; |
| selfClosing; |
| attributes; |
| constructor(name, selfClosing, attributes) { |
| this.type = "JSXOpeningElement" /* JSXOpeningElement */; |
| this.name = name; |
| this.selfClosing = selfClosing; |
| this.attributes = attributes; |
| } |
| }; |
| var JSXOpeningFragment = class { |
| type; |
| selfClosing; |
| constructor(selfClosing) { |
| this.type = "JSXOpeningFragment" /* JSXOpeningFragment */; |
| this.selfClosing = selfClosing; |
| } |
| }; |
| var JSXSpreadAttribute = class { |
| type; |
| argument; |
| constructor(argument) { |
| this.type = "JSXSpreadAttribute" /* JSXSpreadAttribute */; |
| this.argument = argument; |
| } |
| }; |
| var JSXText = class { |
| type; |
| value; |
| raw; |
| constructor(value, raw) { |
| this.type = "JSXText" /* JSXText */; |
| this.value = value; |
| this.raw = raw; |
| } |
| }; |
| |
| // src/nodes.ts |
| var nodes_exports = {}; |
| __export(nodes_exports, { |
| ArrayExpression: () => ArrayExpression, |
| ArrayPattern: () => ArrayPattern, |
| ArrowFunctionExpression: () => ArrowFunctionExpression, |
| AssignmentExpression: () => AssignmentExpression, |
| AssignmentPattern: () => AssignmentPattern, |
| AsyncFunctionDeclaration: () => AsyncFunctionDeclaration, |
| AwaitExpression: () => AwaitExpression, |
| BigIntLiteral: () => BigIntLiteral, |
| BinaryExpression: () => BinaryExpression, |
| BlockStatement: () => BlockStatement, |
| BreakStatement: () => BreakStatement, |
| CallExpression: () => CallExpression, |
| CatchClause: () => CatchClause, |
| ChainExpression: () => ChainExpression, |
| ClassBody: () => ClassBody, |
| ClassDeclaration: () => ClassDeclaration, |
| ClassExpression: () => ClassExpression, |
| ConditionalExpression: () => ConditionalExpression, |
| ContinueStatement: () => ContinueStatement, |
| DebuggerStatement: () => DebuggerStatement, |
| Decorator: () => Decorator, |
| Directive: () => Directive, |
| DoWhileStatement: () => DoWhileStatement, |
| EmptyStatement: () => EmptyStatement, |
| ExportAllDeclaration: () => ExportAllDeclaration, |
| ExportDefaultDeclaration: () => ExportDefaultDeclaration, |
| ExportNamedDeclaration: () => ExportNamedDeclaration, |
| ExportSpecifier: () => ExportSpecifier, |
| ExpressionStatement: () => ExpressionStatement, |
| ForInStatement: () => ForInStatement, |
| ForOfStatement: () => ForOfStatement, |
| ForStatement: () => ForStatement, |
| FunctionDeclaration: () => FunctionDeclaration, |
| FunctionExpression: () => FunctionExpression, |
| Identifier: () => Identifier, |
| IfStatement: () => IfStatement, |
| ImportAttribute: () => ImportAttribute, |
| ImportDeclaration: () => ImportDeclaration, |
| ImportDefaultSpecifier: () => ImportDefaultSpecifier, |
| ImportExpression: () => ImportExpression, |
| ImportNamespaceSpecifier: () => ImportNamespaceSpecifier, |
| ImportSpecifier: () => ImportSpecifier, |
| LabeledStatement: () => LabeledStatement, |
| Literal: () => Literal, |
| LogicalExpression: () => LogicalExpression, |
| MemberExpression: () => MemberExpression, |
| MetaProperty: () => MetaProperty, |
| MethodDefinition: () => MethodDefinition, |
| Module: () => Module, |
| NewExpression: () => NewExpression, |
| ObjectExpression: () => ObjectExpression, |
| ObjectPattern: () => ObjectPattern, |
| PrivateIdentifier: () => PrivateIdentifier, |
| Program: () => Program, |
| Property: () => Property, |
| PropertyDefinition: () => PropertyDefinition, |
| RegexLiteral: () => RegexLiteral, |
| RestElement: () => RestElement, |
| ReturnStatement: () => ReturnStatement, |
| Script: () => Script, |
| SequenceExpression: () => SequenceExpression, |
| SpreadElement: () => SpreadElement, |
| StaticBlock: () => StaticBlock, |
| Super: () => Super, |
| SwitchCase: () => SwitchCase, |
| SwitchStatement: () => SwitchStatement, |
| TaggedTemplateExpression: () => TaggedTemplateExpression, |
| TemplateElement: () => TemplateElement, |
| TemplateLiteral: () => TemplateLiteral, |
| ThisExpression: () => ThisExpression, |
| ThrowStatement: () => ThrowStatement, |
| TryStatement: () => TryStatement, |
| UnaryExpression: () => UnaryExpression, |
| UpdateExpression: () => UpdateExpression, |
| VariableDeclaration: () => VariableDeclaration, |
| VariableDeclarator: () => VariableDeclarator, |
| WhileStatement: () => WhileStatement, |
| WithStatement: () => WithStatement, |
| YieldExpression: () => YieldExpression |
| }); |
| var ArrayExpression = class { |
| type; |
| elements; |
| constructor(elements) { |
| this.type = "ArrayExpression" /* ArrayExpression */; |
| this.elements = elements; |
| } |
| }; |
| var ArrayPattern = class { |
| type; |
| elements; |
| constructor(elements) { |
| this.type = "ArrayPattern" /* ArrayPattern */; |
| this.elements = elements; |
| } |
| }; |
| var ArrowFunctionExpression = class { |
| type; |
| id; |
| params; |
| body; |
| generator; |
| expression; |
| async; |
| constructor(params, body, expression, isAsync) { |
| this.type = "ArrowFunctionExpression" /* ArrowFunctionExpression */; |
| this.id = null; |
| this.params = params; |
| this.body = body; |
| this.generator = false; |
| this.expression = expression; |
| this.async = isAsync; |
| } |
| }; |
| var AssignmentExpression = class { |
| type; |
| operator; |
| left; |
| right; |
| constructor(operator, left, right) { |
| this.type = "AssignmentExpression" /* AssignmentExpression */; |
| this.operator = operator; |
| this.left = left; |
| this.right = right; |
| } |
| }; |
| var AssignmentPattern = class { |
| type; |
| left; |
| right; |
| constructor(left, right) { |
| this.type = "AssignmentPattern" /* AssignmentPattern */; |
| this.left = left; |
| this.right = right; |
| } |
| }; |
| var AsyncFunctionDeclaration = class { |
| type; |
| id; |
| params; |
| body; |
| generator; |
| expression; |
| async; |
| constructor(id, params, body, generator) { |
| this.type = "FunctionDeclaration" /* FunctionDeclaration */; |
| this.id = id; |
| this.params = params; |
| this.body = body; |
| this.generator = generator; |
| this.expression = false; |
| this.async = true; |
| } |
| }; |
| var AwaitExpression = class { |
| type; |
| argument; |
| constructor(argument) { |
| this.type = "AwaitExpression" /* AwaitExpression */; |
| this.argument = argument; |
| } |
| }; |
| var BigIntLiteral = class { |
| type; |
| value; |
| raw; |
| bigint; |
| constructor(value, raw, bigint) { |
| this.type = "Literal" /* Literal */; |
| this.value = value; |
| this.raw = raw; |
| this.bigint = bigint; |
| } |
| }; |
| var BinaryExpression = class { |
| type; |
| operator; |
| left; |
| right; |
| constructor(operator, left, right) { |
| this.type = "BinaryExpression" /* BinaryExpression */; |
| this.operator = operator; |
| this.left = left; |
| this.right = right; |
| } |
| }; |
| var BlockStatement = class { |
| type; |
| body; |
| constructor(body) { |
| this.type = "BlockStatement" /* BlockStatement */; |
| this.body = body; |
| } |
| }; |
| var BreakStatement = class { |
| type; |
| label; |
| constructor(label) { |
| this.type = "BreakStatement" /* BreakStatement */; |
| this.label = label; |
| } |
| }; |
| var CallExpression = class { |
| type; |
| callee; |
| arguments; |
| optional; |
| constructor(callee, args, optional) { |
| this.type = "CallExpression" /* CallExpression */; |
| this.callee = callee; |
| this.arguments = args; |
| this.optional = optional; |
| } |
| }; |
| var CatchClause = class { |
| type; |
| param; |
| body; |
| constructor(param, body) { |
| this.type = "CatchClause" /* CatchClause */; |
| this.param = param; |
| this.body = body; |
| } |
| }; |
| var ChainExpression = class { |
| type; |
| expression; |
| constructor(expression) { |
| this.type = "ChainExpression" /* ChainExpression */; |
| this.expression = expression; |
| } |
| }; |
| var ClassBody = class { |
| type; |
| body; |
| constructor(body) { |
| this.type = "ClassBody" /* ClassBody */; |
| this.body = body; |
| } |
| }; |
| var ClassDeclaration = class { |
| type; |
| id; |
| superClass; |
| body; |
| decorators; |
| constructor(id, superClass, body, decorators) { |
| this.type = "ClassDeclaration" /* ClassDeclaration */; |
| this.id = id; |
| this.superClass = superClass; |
| this.body = body; |
| this.decorators = decorators; |
| } |
| }; |
| var ClassExpression = class { |
| type; |
| id; |
| superClass; |
| body; |
| decorators; |
| constructor(id, superClass, body, decorators) { |
| this.type = "ClassExpression" /* ClassExpression */; |
| this.id = id; |
| this.superClass = superClass; |
| this.body = body; |
| this.decorators = decorators; |
| } |
| }; |
| var ConditionalExpression = class { |
| type; |
| test; |
| consequent; |
| alternate; |
| constructor(test, consequent, alternate) { |
| this.type = "ConditionalExpression" /* ConditionalExpression */; |
| this.test = test; |
| this.consequent = consequent; |
| this.alternate = alternate; |
| } |
| }; |
| var ContinueStatement = class { |
| type; |
| label; |
| constructor(label) { |
| this.type = "ContinueStatement" /* ContinueStatement */; |
| this.label = label; |
| } |
| }; |
| var DebuggerStatement = class { |
| type; |
| constructor() { |
| this.type = "DebuggerStatement" /* DebuggerStatement */; |
| } |
| }; |
| var Decorator = class { |
| type; |
| expression; |
| constructor(expression) { |
| this.type = "Decorator" /* Decorator */; |
| this.expression = expression; |
| } |
| }; |
| var Directive = class { |
| type; |
| expression; |
| directive; |
| constructor(expression, directive) { |
| this.type = "ExpressionStatement" /* ExpressionStatement */; |
| this.expression = expression; |
| this.directive = directive; |
| } |
| }; |
| var DoWhileStatement = class { |
| type; |
| body; |
| test; |
| constructor(body, test) { |
| this.type = "DoWhileStatement" /* DoWhileStatement */; |
| this.body = body; |
| this.test = test; |
| } |
| }; |
| var EmptyStatement = class { |
| type; |
| constructor() { |
| this.type = "EmptyStatement" /* EmptyStatement */; |
| } |
| }; |
| var ExportAllDeclaration = class { |
| type; |
| source; |
| exported; |
| assertions; |
| constructor(source, exported, assertions) { |
| this.type = "ExportAllDeclaration" /* ExportAllDeclaration */; |
| this.source = source; |
| this.exported = exported; |
| this.assertions = assertions; |
| } |
| }; |
| var ExportDefaultDeclaration = class { |
| type; |
| declaration; |
| constructor(declaration) { |
| this.type = "ExportDefaultDeclaration" /* ExportDefaultDeclaration */; |
| this.declaration = declaration; |
| } |
| }; |
| var ExportNamedDeclaration = class { |
| type; |
| declaration; |
| specifiers; |
| source; |
| assertions; |
| constructor(declaration, specifiers, source, assertions) { |
| this.type = "ExportNamedDeclaration" /* ExportNamedDeclaration */; |
| this.declaration = declaration; |
| this.specifiers = specifiers; |
| this.source = source; |
| this.assertions = assertions; |
| } |
| }; |
| var ExportSpecifier = class { |
| type; |
| exported; |
| local; |
| constructor(local, exported) { |
| this.type = "ExportSpecifier" /* ExportSpecifier */; |
| this.exported = exported; |
| this.local = local; |
| } |
| }; |
| var ExpressionStatement = class { |
| type; |
| expression; |
| constructor(expression) { |
| this.type = "ExpressionStatement" /* ExpressionStatement */; |
| this.expression = expression; |
| } |
| }; |
| var ForInStatement = class { |
| type; |
| left; |
| right; |
| body; |
| each; |
| constructor(left, right, body) { |
| this.type = "ForInStatement" /* ForInStatement */; |
| this.left = left; |
| this.right = right; |
| this.body = body; |
| this.each = false; |
| } |
| }; |
| var ForOfStatement = class { |
| type; |
| await; |
| left; |
| right; |
| body; |
| constructor(left, right, body, _await) { |
| this.type = "ForOfStatement" /* ForOfStatement */; |
| this.await = _await; |
| this.left = left; |
| this.right = right; |
| this.body = body; |
| } |
| }; |
| var ForStatement = class { |
| type; |
| init; |
| test; |
| update; |
| body; |
| constructor(init, test, update, body) { |
| this.type = "ForStatement" /* ForStatement */; |
| this.init = init; |
| this.test = test; |
| this.update = update; |
| this.body = body; |
| } |
| }; |
| var FunctionDeclaration = class { |
| type; |
| id; |
| params; |
| body; |
| generator; |
| expression; |
| async; |
| constructor(id, params, body, generator) { |
| this.type = "FunctionDeclaration" /* FunctionDeclaration */; |
| this.id = id; |
| this.params = params; |
| this.body = body; |
| this.generator = generator; |
| this.expression = false; |
| this.async = false; |
| } |
| }; |
| var FunctionExpression = class { |
| type; |
| id; |
| params; |
| body; |
| generator; |
| expression; |
| async; |
| constructor(id, params, body, generator, isAsync) { |
| this.type = "FunctionExpression" /* FunctionExpression */; |
| this.id = id; |
| this.params = params; |
| this.body = body; |
| this.generator = generator; |
| this.expression = false; |
| this.async = isAsync; |
| } |
| }; |
| var Identifier = class { |
| type; |
| name; |
| constructor(name) { |
| this.type = "Identifier" /* Identifier */; |
| this.name = name; |
| } |
| }; |
| var IfStatement = class { |
| type; |
| test; |
| consequent; |
| alternate; |
| constructor(test, consequent, alternate) { |
| this.type = "IfStatement" /* IfStatement */; |
| this.test = test; |
| this.consequent = consequent; |
| this.alternate = alternate; |
| } |
| }; |
| var ImportAttribute = class { |
| type; |
| key; |
| value; |
| constructor(key, value) { |
| this.type = "ImportAttribute" /* ImportAttribute */; |
| this.key = key; |
| this.value = value; |
| } |
| }; |
| var ImportExpression = class { |
| type; |
| source; |
| attributes; |
| constructor(source, attributes) { |
| this.type = "ImportExpression" /* ImportExpression */; |
| this.source = source; |
| this.attributes = attributes; |
| } |
| }; |
| var ImportDeclaration = class { |
| type; |
| specifiers; |
| source; |
| assertions; |
| constructor(specifiers, source, assertions) { |
| this.type = "ImportDeclaration" /* ImportDeclaration */; |
| this.specifiers = specifiers; |
| this.source = source; |
| this.assertions = assertions; |
| } |
| }; |
| var ImportDefaultSpecifier = class { |
| type; |
| local; |
| constructor(local) { |
| this.type = "ImportDefaultSpecifier" /* ImportDefaultSpecifier */; |
| this.local = local; |
| } |
| }; |
| var ImportNamespaceSpecifier = class { |
| type; |
| local; |
| constructor(local) { |
| this.type = "ImportNamespaceSpecifier" /* ImportNamespaceSpecifier */; |
| this.local = local; |
| } |
| }; |
| var ImportSpecifier = class { |
| type; |
| local; |
| imported; |
| constructor(local, imported) { |
| this.type = "ImportSpecifier" /* ImportSpecifier */; |
| this.local = local; |
| this.imported = imported; |
| } |
| }; |
| var LabeledStatement = class { |
| type; |
| label; |
| body; |
| constructor(label, body) { |
| this.type = "LabeledStatement" /* LabeledStatement */; |
| this.label = label; |
| this.body = body; |
| } |
| }; |
| var Literal = class { |
| type; |
| value; |
| raw; |
| constructor(value, raw) { |
| this.type = "Literal" /* Literal */; |
| this.value = value; |
| this.raw = raw; |
| } |
| }; |
| var LogicalExpression = class { |
| type; |
| operator; |
| left; |
| right; |
| constructor(operator, left, right) { |
| this.type = "LogicalExpression" /* LogicalExpression */; |
| this.operator = operator; |
| this.left = left; |
| this.right = right; |
| } |
| }; |
| var MemberExpression = class { |
| type; |
| computed; |
| object; |
| property; |
| optional; |
| constructor(computed, object, property, optional) { |
| this.type = "MemberExpression" /* MemberExpression */; |
| this.computed = computed; |
| this.object = object; |
| this.property = property; |
| this.optional = optional; |
| } |
| }; |
| var MetaProperty = class { |
| type; |
| meta; |
| property; |
| constructor(meta, property) { |
| this.type = "MetaProperty" /* MetaProperty */; |
| this.meta = meta; |
| this.property = property; |
| } |
| }; |
| var MethodDefinition = class { |
| type; |
| key; |
| computed; |
| value; |
| kind; |
| static; |
| decorators; |
| constructor(key, computed, value, kind, isStatic, decorators) { |
| this.type = "MethodDefinition" /* MethodDefinition */; |
| this.key = key; |
| this.computed = computed; |
| this.value = value; |
| this.kind = kind; |
| this.static = isStatic; |
| this.decorators = decorators; |
| } |
| }; |
| var Module = class { |
| type; |
| body; |
| sourceType; |
| constructor(body) { |
| this.type = "Program" /* Program */; |
| this.body = body; |
| this.sourceType = "module"; |
| } |
| }; |
| var NewExpression = class { |
| type; |
| callee; |
| arguments; |
| constructor(callee, args) { |
| this.type = "NewExpression" /* NewExpression */; |
| this.callee = callee; |
| this.arguments = args; |
| } |
| }; |
| var ObjectExpression = class { |
| type; |
| properties; |
| constructor(properties) { |
| this.type = "ObjectExpression" /* ObjectExpression */; |
| this.properties = properties; |
| } |
| }; |
| var ObjectPattern = class { |
| type; |
| properties; |
| constructor(properties) { |
| this.type = "ObjectPattern" /* ObjectPattern */; |
| this.properties = properties; |
| } |
| }; |
| var PrivateIdentifier = class { |
| type; |
| name; |
| constructor(name) { |
| this.type = "PrivateIdentifier" /* PrivateIdentifier */; |
| this.name = name; |
| } |
| }; |
| var Program = class { |
| type; |
| body; |
| sourceType; |
| constructor(sourceType, body) { |
| this.type = "Program" /* Program */; |
| this.sourceType = sourceType; |
| this.body = body; |
| } |
| }; |
| var Property = class { |
| type; |
| key; |
| computed; |
| value; |
| kind; |
| method; |
| shorthand; |
| constructor(kind, key, computed, value, method, shorthand) { |
| this.type = "Property" /* Property */; |
| this.key = key; |
| this.computed = computed; |
| this.value = value; |
| this.kind = kind; |
| this.method = method; |
| this.shorthand = shorthand; |
| } |
| }; |
| var PropertyDefinition = class { |
| type; |
| key; |
| computed; |
| value; |
| static; |
| decorators; |
| constructor(key, computed, value, isStatic, decorators) { |
| this.type = "Property" /* Property */; |
| this.key = key; |
| this.computed = computed; |
| this.value = value; |
| this.static = isStatic; |
| this.decorators = decorators; |
| } |
| }; |
| var RegexLiteral = class { |
| type; |
| value; |
| raw; |
| regex; |
| constructor(value, raw, pattern, flags) { |
| this.type = "Literal" /* Literal */; |
| this.value = value; |
| this.raw = raw; |
| this.regex = { pattern, flags }; |
| } |
| }; |
| var RestElement = class { |
| type; |
| argument; |
| constructor(argument) { |
| this.type = "RestElement" /* RestElement */; |
| this.argument = argument; |
| } |
| }; |
| var ReturnStatement = class { |
| type; |
| argument; |
| constructor(argument) { |
| this.type = "ReturnStatement" /* ReturnStatement */; |
| this.argument = argument; |
| } |
| }; |
| var Script = class { |
| type; |
| body; |
| sourceType; |
| constructor(body) { |
| this.type = "Program" /* Program */; |
| this.body = body; |
| this.sourceType = "script"; |
| } |
| }; |
| var SequenceExpression = class { |
| type; |
| expressions; |
| constructor(expressions) { |
| this.type = "SequenceExpression" /* SequenceExpression */; |
| this.expressions = expressions; |
| } |
| }; |
| var SpreadElement = class { |
| type; |
| argument; |
| constructor(argument) { |
| this.type = "SpreadElement" /* SpreadElement */; |
| this.argument = argument; |
| } |
| }; |
| var StaticBlock = class { |
| type; |
| body; |
| constructor(body) { |
| this.type = "StaticBlock" /* StaticBlock */; |
| this.body = body; |
| } |
| }; |
| var Super = class { |
| type; |
| constructor() { |
| this.type = "Super" /* Super */; |
| } |
| }; |
| var SwitchCase = class { |
| type; |
| test; |
| consequent; |
| constructor(test, consequent) { |
| this.type = "SwitchCase" /* SwitchCase */; |
| this.test = test; |
| this.consequent = consequent; |
| } |
| }; |
| var SwitchStatement = class { |
| type; |
| discriminant; |
| cases; |
| constructor(discriminant, cases) { |
| this.type = "SwitchStatement" /* SwitchStatement */; |
| this.discriminant = discriminant; |
| this.cases = cases; |
| } |
| }; |
| var TaggedTemplateExpression = class { |
| type; |
| tag; |
| quasi; |
| constructor(tag, quasi) { |
| this.type = "TaggedTemplateExpression" /* TaggedTemplateExpression */; |
| this.tag = tag; |
| this.quasi = quasi; |
| } |
| }; |
| var TemplateElement = class { |
| type; |
| value; |
| tail; |
| constructor(value, tail) { |
| this.type = "TemplateElement" /* TemplateElement */; |
| this.value = value; |
| this.tail = tail; |
| } |
| }; |
| var TemplateLiteral = class { |
| type; |
| quasis; |
| expressions; |
| constructor(quasis, expressions) { |
| this.type = "TemplateLiteral" /* TemplateLiteral */; |
| this.quasis = quasis; |
| this.expressions = expressions; |
| } |
| }; |
| var ThisExpression = class { |
| type; |
| constructor() { |
| this.type = "ThisExpression" /* ThisExpression */; |
| } |
| }; |
| var ThrowStatement = class { |
| type; |
| argument; |
| constructor(argument) { |
| this.type = "ThrowStatement" /* ThrowStatement */; |
| this.argument = argument; |
| } |
| }; |
| var TryStatement = class { |
| type; |
| block; |
| handler; |
| finalizer; |
| constructor(block, handler, finalizer) { |
| this.type = "TryStatement" /* TryStatement */; |
| this.block = block; |
| this.handler = handler; |
| this.finalizer = finalizer; |
| } |
| }; |
| var UnaryExpression = class { |
| type; |
| operator; |
| argument; |
| prefix; |
| constructor(operator, argument) { |
| this.type = "UnaryExpression" /* UnaryExpression */; |
| this.operator = operator; |
| this.argument = argument; |
| this.prefix = true; |
| } |
| }; |
| var UpdateExpression = class { |
| type; |
| operator; |
| argument; |
| prefix; |
| constructor(operator, argument, prefix) { |
| this.type = "UpdateExpression" /* UpdateExpression */; |
| this.operator = operator; |
| this.argument = argument; |
| this.prefix = prefix; |
| } |
| }; |
| var VariableDeclaration = class { |
| type; |
| declarations; |
| kind; |
| constructor(declarations, kind) { |
| this.type = "VariableDeclaration" /* VariableDeclaration */; |
| this.declarations = declarations; |
| this.kind = kind; |
| } |
| }; |
| var VariableDeclarator = class { |
| type; |
| id; |
| init; |
| constructor(id, init) { |
| this.type = "VariableDeclarator" /* VariableDeclarator */; |
| this.id = id; |
| this.init = init; |
| } |
| }; |
| var WhileStatement = class { |
| type; |
| test; |
| body; |
| constructor(test, body) { |
| this.type = "WhileStatement" /* WhileStatement */; |
| this.test = test; |
| this.body = body; |
| } |
| }; |
| var WithStatement = class { |
| type; |
| object; |
| body; |
| constructor(object, body) { |
| this.type = "WithStatement" /* WithStatement */; |
| this.object = object; |
| this.body = body; |
| } |
| }; |
| var YieldExpression = class { |
| type; |
| argument; |
| delegate; |
| constructor(argument, delegate) { |
| this.type = "YieldExpression" /* YieldExpression */; |
| this.argument = argument; |
| this.delegate = delegate; |
| } |
| }; |
| |
| // src/assert.ts |
| function assert(condition, message) { |
| if (!condition) { |
| throw new Error("ASSERT: " + message); |
| } |
| } |
| |
| // src/error-handler.ts |
| var ErrorHandler = class { |
| errors; |
| tolerant; |
| constructor() { |
| this.errors = []; |
| this.tolerant = false; |
| } |
| recordError(error) { |
| this.errors.push(error); |
| } |
| tolerate(error) { |
| if (this.tolerant) { |
| this.recordError(error); |
| } else { |
| throw error; |
| } |
| } |
| constructError(msg, column) { |
| let error = new Error(msg); |
| try { |
| throw error; |
| } catch (base) { |
| if (Object.create && Object.defineProperty) { |
| error = Object.create(base); |
| Object.defineProperty(error, "column", { value: column }); |
| } |
| } |
| return error; |
| } |
| createError(index, line, col, description) { |
| const msg = "Line " + line + ": " + description; |
| const _error = this.constructError(msg, col); |
| _error.index = index; |
| _error.lineNumber = line; |
| _error.description = description; |
| const error = _error; |
| return error; |
| } |
| throwError(index, line, col, description) { |
| throw this.createError(index, line, col, description); |
| } |
| tolerateError(index, line, col, description) { |
| const error = this.createError(index, line, col, description); |
| if (this.tolerant) { |
| this.recordError(error); |
| } else { |
| throw error; |
| } |
| } |
| }; |
| |
| // src/messages.ts |
| var Messages = { |
| AsyncFunctionInSingleStatementContext: "Async functions can only be declared at the top level or inside a block.", |
| BadImportCallArity: "Unexpected token", |
| BadGetterArity: "Getter must not have any formal parameters", |
| BadSetterArity: "Setter must have exactly one formal parameter", |
| BadSetterRestParameter: "Setter function argument must not be a rest parameter", |
| CannotUseImportMetaOutsideAModule: "Cannot use 'import.meta' outside a module", |
| ConstructorIsAsync: "Class constructor may not be an async method", |
| ConstructorIsPrivate: "Class constructor may not be a private method", |
| ConstructorSpecialMethod: "Class constructor may not be an accessor", |
| DeclarationMissingInitializer: "Missing initializer in %0 declaration", |
| DefaultRestParameter: "Unexpected token =", |
| DefaultRestProperty: "Unexpected token =", |
| DuplicateBinding: "Duplicate binding %0", |
| DuplicateConstructor: "A class may only have one constructor", |
| DuplicateParameter: "Duplicate parameter name not allowed in this context", |
| DuplicateProtoProperty: "Duplicate __proto__ fields are not allowed in object literals", |
| ForInOfLoopInitializer: "%0 loop variable declaration may not have an initializer", |
| GeneratorInLegacyContext: "Generator declarations are not allowed in legacy contexts", |
| IllegalBreak: "Illegal break statement", |
| IllegalContinue: "Illegal continue statement", |
| IllegalExportDeclaration: "Unexpected token", |
| IllegalImportDeclaration: "Unexpected token", |
| IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list", |
| IllegalReturn: "Illegal return statement", |
| InvalidEscapedReservedWord: "Keyword must not contain escaped characters", |
| InvalidHexEscapeSequence: "Invalid hexadecimal escape sequence", |
| InvalidLHSInAssignment: "Invalid left-hand side in assignment", |
| InvalidLHSInForIn: "Invalid left-hand side in for-in", |
| InvalidLHSInForLoop: "Invalid left-hand side in for-loop", |
| InvalidModuleSpecifier: "Unexpected token", |
| InvalidRegExp: "Invalid regular expression", |
| InvalidTaggedTemplateOnOptionalChain: "Invalid tagged template on optional chain", |
| InvalidUnicodeEscapeSequence: "Invalid Unicode escape sequence", |
| LetInLexicalBinding: "let is disallowed as a lexically bound name", |
| MissingFromClause: "Unexpected token", |
| MultipleDefaultsInSwitch: "More than one default clause in switch statement", |
| NewlineAfterThrow: "Illegal newline after throw", |
| NoAsAfterImportNamespace: "Unexpected token", |
| NoAsAndFromEscapeSequences: "The `as` and `from` contextual keywords must not contain Unicode escape sequences.", |
| NoCatchOrFinally: "Missing catch or finally after try", |
| NoSemicolonAfterDecorator: "Decorators must not be followed by a semicolon.", |
| NumericSeperatorOneUnderscore: "Numeric separator must be exactly one underscore", |
| NumericSeperatorNotAllowedHere: "Numeric separator is not allowed here", |
| ParameterAfterRestParameter: "Rest parameter must be last formal parameter", |
| PropertyAfterRestProperty: "Unexpected token", |
| Redeclaration: "%0 '%1' has already been declared", |
| StaticPrototype: "Classes may not have static property named prototype", |
| StrictCatchVariable: "Catch variable may not be eval or arguments in strict mode", |
| StrictDelete: "Delete of an unqualified identifier in strict mode.", |
| StrictFunction: "In strict mode code, functions can only be declared at top level or inside a block", |
| StrictFunctionName: "Function name may not be eval or arguments in strict mode", |
| StrictLHSAssignment: "Assignment to eval or arguments is not allowed in strict mode", |
| StrictLHSPostfix: "Postfix increment/decrement may not have eval or arguments operand in strict mode", |
| StrictLHSPrefix: "Prefix increment/decrement may not have eval or arguments operand in strict mode", |
| StrictModeWith: "Strict mode code may not include a with statement", |
| StrictOctalLiteral: "Octal literals are not allowed in strict mode.", |
| StrictParamName: "Parameter name eval or arguments is not allowed in strict mode", |
| StrictReservedWord: "Use of future reserved word in strict mode", |
| StrictVarName: "Variable name may not be eval or arguments in strict mode", |
| TemplateOctalLiteral: "Octal literals are not allowed in template strings.", |
| TemplateEscape89: "\\8 and \\9 are not allowed in template strings.", |
| UnexpectedEOS: "Unexpected end of input", |
| UnexpectedIdentifier: "Unexpected identifier", |
| UnexpectedNumber: "Unexpected number", |
| UnexpectedReserved: "Unexpected reserved word", |
| UnexpectedString: "Unexpected string", |
| UnexpectedSuper: "'super' keyword unexpected here", |
| UnexpectedTemplate: "Unexpected quasi %0", |
| UnexpectedToken: "Unexpected token %0", |
| UnexpectedTokenIllegal: "Unexpected token ILLEGAL", |
| UnknownLabel: "Undefined label '%0'", |
| UnterminatedRegExp: "Invalid regular expression: missing /" |
| }; |
| |
| // src/token.ts |
| var TokenName = {}; |
| TokenName[1 /* BooleanLiteral */] = "Boolean"; |
| TokenName[2 /* EOF */] = "<end>"; |
| TokenName[3 /* Identifier */] = "Identifier"; |
| TokenName[4 /* Keyword */] = "Keyword"; |
| TokenName[5 /* NullLiteral */] = "Null"; |
| TokenName[6 /* NumericLiteral */] = "Numeric"; |
| TokenName[7 /* Punctuator */] = "Punctuator"; |
| TokenName[8 /* StringLiteral */] = "String"; |
| TokenName[9 /* RegularExpression */] = "RegularExpression"; |
| TokenName[10 /* Template */] = "Template"; |
| |
| // src/scanner.ts |
| function hexValue(ch) { |
| return "0123456789abcdef".indexOf(ch.toLowerCase()); |
| } |
| function octalValue(ch) { |
| return "01234567".indexOf(ch); |
| } |
| var Scanner = class { |
| source; |
| errorHandler; |
| trackComment; |
| isModule; |
| index; |
| lineNumber; |
| lineStart; |
| curlyStack; |
| length; |
| constructor(code, handler) { |
| this.source = code; |
| this.errorHandler = handler; |
| this.trackComment = false; |
| this.isModule = false; |
| this.length = code.length; |
| this.index = 0; |
| this.lineNumber = code.length > 0 ? 1 : 0; |
| this.lineStart = 0; |
| this.curlyStack = []; |
| } |
| saveState() { |
| return { |
| index: this.index, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| curlyStack: this.curlyStack.slice() |
| }; |
| } |
| restoreState(state) { |
| this.index = state.index; |
| this.lineNumber = state.lineNumber; |
| this.lineStart = state.lineStart; |
| this.curlyStack = state.curlyStack; |
| } |
| eof() { |
| return this.index >= this.length; |
| } |
| throwUnexpectedToken(message = Messages.UnexpectedTokenIllegal) { |
| return this.errorHandler.throwError( |
| this.index, |
| this.lineNumber, |
| this.index - this.lineStart + 1, |
| message |
| ); |
| } |
| tolerateUnexpectedToken(message = Messages.UnexpectedTokenIllegal) { |
| this.errorHandler.tolerateError( |
| this.index, |
| this.lineNumber, |
| this.index - this.lineStart + 1, |
| message |
| ); |
| } |
| // https://tc39.github.io/ecma262/#sec-comments |
| skipSingleLineComment(offset) { |
| let comments = []; |
| let start, loc; |
| if (this.trackComment) { |
| comments = []; |
| start = this.index - offset; |
| loc = { |
| start: { |
| line: this.lineNumber, |
| column: this.index - this.lineStart - offset |
| }, |
| end: {} |
| }; |
| } |
| while (!this.eof()) { |
| const ch = this.source.charCodeAt(this.index); |
| ++this.index; |
| if (Character.isLineTerminator(ch)) { |
| if (this.trackComment) { |
| loc.end = { |
| line: this.lineNumber, |
| column: this.index - this.lineStart - 1 |
| }; |
| const entry = { |
| multiLine: false, |
| slice: [start + offset, this.index - 1], |
| range: [start, this.index - 1], |
| loc |
| }; |
| comments.push(entry); |
| } |
| if (ch === 13 && this.source.charCodeAt(this.index) === 10) { |
| ++this.index; |
| } |
| ++this.lineNumber; |
| this.lineStart = this.index; |
| return comments; |
| } |
| } |
| if (this.trackComment) { |
| loc.end = { |
| line: this.lineNumber, |
| column: this.index - this.lineStart |
| }; |
| const entry = { |
| multiLine: false, |
| slice: [start + offset, this.index], |
| range: [start, this.index], |
| loc |
| }; |
| comments.push(entry); |
| } |
| return comments; |
| } |
| skipMultiLineComment() { |
| let comments = []; |
| let start, loc; |
| if (this.trackComment) { |
| comments = []; |
| start = this.index - 2; |
| loc = { |
| start: { |
| line: this.lineNumber, |
| column: this.index - this.lineStart - 2 |
| }, |
| end: {} |
| }; |
| } |
| while (!this.eof()) { |
| const ch = this.source.charCodeAt(this.index); |
| if (Character.isLineTerminator(ch)) { |
| if (ch === 13 && this.source.charCodeAt(this.index + 1) === 10) { |
| ++this.index; |
| } |
| ++this.lineNumber; |
| ++this.index; |
| this.lineStart = this.index; |
| } else if (ch === 42) { |
| if (this.source.charCodeAt(this.index + 1) === 47) { |
| this.index += 2; |
| if (this.trackComment) { |
| loc.end = { |
| line: this.lineNumber, |
| column: this.index - this.lineStart |
| }; |
| const entry = { |
| multiLine: true, |
| slice: [start + 2, this.index - 2], |
| range: [start, this.index], |
| loc |
| }; |
| comments.push(entry); |
| } |
| return comments; |
| } |
| ++this.index; |
| } else { |
| ++this.index; |
| } |
| } |
| if (this.trackComment) { |
| loc.end = { |
| line: this.lineNumber, |
| column: this.index - this.lineStart |
| }; |
| const entry = { |
| multiLine: true, |
| slice: [start + 2, this.index], |
| range: [start, this.index], |
| loc |
| }; |
| comments.push(entry); |
| } |
| this.tolerateUnexpectedToken(); |
| return comments; |
| } |
| scanComments() { |
| let comments; |
| if (this.trackComment) { |
| comments = []; |
| } |
| let start = this.index === 0; |
| while (!this.eof()) { |
| let ch = this.source.charCodeAt(this.index); |
| if (Character.isWhiteSpace(ch)) { |
| ++this.index; |
| } else if (Character.isLineTerminator(ch)) { |
| ++this.index; |
| if (ch === 13 && this.source.charCodeAt(this.index) === 10) { |
| ++this.index; |
| } |
| ++this.lineNumber; |
| this.lineStart = this.index; |
| start = true; |
| } else if (ch === 47) { |
| ch = this.source.charCodeAt(this.index + 1); |
| if (ch === 47) { |
| this.index += 2; |
| const comment = this.skipSingleLineComment(2); |
| if (this.trackComment) { |
| comments = comments.concat(comment); |
| } |
| start = true; |
| } else if (ch === 42) { |
| this.index += 2; |
| const comment = this.skipMultiLineComment(); |
| if (this.trackComment) { |
| comments = comments.concat(comment); |
| } |
| } else { |
| break; |
| } |
| } else if (start && ch === 45) { |
| if (this.source.charCodeAt(this.index + 1) === 45 && this.source.charCodeAt(this.index + 2) === 62) { |
| this.index += 3; |
| const comment = this.skipSingleLineComment(3); |
| if (this.trackComment) { |
| comments = comments.concat(comment); |
| } |
| } else { |
| break; |
| } |
| } else if (ch === 60 && !this.isModule) { |
| if (this.source.slice(this.index + 1, this.index + 4) === "!--") { |
| this.index += 4; |
| const comment = this.skipSingleLineComment(4); |
| if (this.trackComment) { |
| comments = comments.concat(comment); |
| } |
| } else { |
| break; |
| } |
| } else { |
| break; |
| } |
| } |
| return comments; |
| } |
| // https://tc39.github.io/ecma262/#sec-future-reserved-words |
| isFutureReservedWord(id) { |
| switch (id) { |
| case "enum": |
| case "export": |
| case "import": |
| case "super": |
| return true; |
| default: |
| return false; |
| } |
| } |
| isStrictModeReservedWord(id) { |
| switch (id) { |
| case "implements": |
| case "interface": |
| case "package": |
| case "private": |
| case "protected": |
| case "public": |
| case "static": |
| case "yield": |
| case "let": |
| return true; |
| default: |
| return false; |
| } |
| } |
| isRestrictedWord(id) { |
| return id === "eval" || id === "arguments"; |
| } |
| // https://tc39.github.io/ecma262/#sec-keywords |
| isKeyword(id) { |
| switch (id.length) { |
| case 2: |
| return id === "if" || id === "in" || id === "do"; |
| case 3: |
| return id === "var" || id === "for" || id === "new" || id === "try" || id === "let"; |
| case 4: |
| return id === "this" || id === "else" || id === "case" || id === "void" || id === "with" || id === "enum"; |
| case 5: |
| return id === "while" || id === "break" || id === "catch" || id === "throw" || id === "const" || id === "yield" || id === "class" || id === "super"; |
| case 6: |
| return id === "return" || id === "typeof" || id === "delete" || id === "switch" || id === "export" || id === "import"; |
| case 7: |
| return id === "default" || id === "finally" || id === "extends"; |
| case 8: |
| return id === "function" || id === "continue" || id === "debugger"; |
| case 10: |
| return id === "instanceof"; |
| default: |
| return false; |
| } |
| } |
| codePointAt(i) { |
| let cp = this.source.charCodeAt(i); |
| if (cp >= 55296 && cp <= 56319) { |
| const second = this.source.charCodeAt(i + 1); |
| if (second >= 56320 && second <= 57343) { |
| const first = cp; |
| cp = (first - 55296) * 1024 + second - 56320 + 65536; |
| } |
| } |
| return cp; |
| } |
| scanHexEscape(prefix) { |
| const len = prefix === "u" ? 4 : 2; |
| let code = 0; |
| for (let i = 0; i < len; ++i) { |
| if (!this.eof() && Character.isHexDigit(this.source.charCodeAt(this.index))) { |
| code = code * 16 + hexValue(this.source[this.index++]); |
| } else { |
| return null; |
| } |
| } |
| return String.fromCharCode(code); |
| } |
| tryToScanUnicodeCodePointEscape() { |
| let ch = this.source[this.index]; |
| let code = 0; |
| if (ch === "}") { |
| return null; |
| } |
| while (!this.eof()) { |
| ch = this.source[this.index++]; |
| if (!Character.isHexDigit(ch.charCodeAt(0))) { |
| break; |
| } |
| code = code * 16 + hexValue(ch); |
| } |
| if (code > 1114111 || ch !== "}") { |
| return null; |
| } |
| return Character.fromCodePoint(code); |
| } |
| scanUnicodeCodePointEscape() { |
| const result = this.tryToScanUnicodeCodePointEscape(); |
| if (result === null) { |
| return this.throwUnexpectedToken(); |
| } |
| return result; |
| } |
| getIdentifier() { |
| const start = this.index++; |
| while (!this.eof()) { |
| const ch = this.source.charCodeAt(this.index); |
| if (ch === 92) { |
| this.index = start; |
| return this.getComplexIdentifier(); |
| } else if (ch >= 55296 && ch < 57343) { |
| this.index = start; |
| return this.getComplexIdentifier(); |
| } |
| if (Character.isIdentifierPart(ch)) { |
| ++this.index; |
| } else { |
| break; |
| } |
| } |
| return this.source.slice(start, this.index); |
| } |
| getComplexIdentifier() { |
| let cp = this.codePointAt(this.index); |
| let id = Character.fromCodePoint(cp); |
| this.index += id.length; |
| let ch; |
| if (cp === 92) { |
| if (this.source.charCodeAt(this.index) !== 117) { |
| this.throwUnexpectedToken(); |
| } |
| ++this.index; |
| if (this.source[this.index] === "{") { |
| ++this.index; |
| ch = this.scanUnicodeCodePointEscape(); |
| } else { |
| ch = this.scanHexEscape("u"); |
| if (ch === null || ch === "\\" || !Character.isIdentifierStart(ch.charCodeAt(0))) { |
| this.throwUnexpectedToken(); |
| } |
| } |
| id = ch; |
| } |
| while (!this.eof()) { |
| cp = this.codePointAt(this.index); |
| if (!Character.isIdentifierPart(cp)) { |
| break; |
| } |
| ch = Character.fromCodePoint(cp); |
| id += ch; |
| this.index += ch.length; |
| if (cp === 92) { |
| id = id.substr(0, id.length - 1); |
| if (this.source.charCodeAt(this.index) !== 117) { |
| this.throwUnexpectedToken(); |
| } |
| ++this.index; |
| if (this.source[this.index] === "{") { |
| ++this.index; |
| ch = this.scanUnicodeCodePointEscape(); |
| } else { |
| ch = this.scanHexEscape("u"); |
| if (ch === null || ch === "\\" || !Character.isIdentifierPart(ch.charCodeAt(0))) { |
| this.throwUnexpectedToken(); |
| } |
| } |
| id += ch; |
| } |
| } |
| return id; |
| } |
| octalToDecimal(ch) { |
| let octal = ch !== "0"; |
| let code = octalValue(ch); |
| if (!this.eof() && Character.isOctalDigit(this.source.charCodeAt(this.index))) { |
| octal = true; |
| code = code * 8 + octalValue(this.source[this.index++]); |
| if ("0123".indexOf(ch) >= 0 && !this.eof() && Character.isOctalDigit(this.source.charCodeAt(this.index))) { |
| code = code * 8 + octalValue(this.source[this.index++]); |
| } |
| } |
| return { |
| code, |
| octal |
| }; |
| } |
| // https://tc39.github.io/ecma262/#sec-names-and-keywords |
| scanIdentifier() { |
| let type; |
| const start = this.index; |
| const escaped = this.source.charCodeAt(start) === 92; |
| const id = escaped ? this.getComplexIdentifier() : this.getIdentifier(); |
| if (id.length === 1) { |
| type = 3 /* Identifier */; |
| } else if (this.isKeyword(id)) { |
| type = 4 /* Keyword */; |
| } else if (id === "null") { |
| type = 5 /* NullLiteral */; |
| } else if (id === "true" || id === "false") { |
| type = 1 /* BooleanLiteral */; |
| } else { |
| type = 3 /* Identifier */; |
| } |
| if (type !== 3 /* Identifier */ && start + id.length !== this.index) { |
| const restore = this.index; |
| this.index = start; |
| this.tolerateUnexpectedToken(Messages.InvalidEscapedReservedWord); |
| this.index = restore; |
| } |
| return { |
| type, |
| value: id, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index, |
| escaped |
| }; |
| } |
| // https://tc39.github.io/ecma262/#sec-punctuators |
| scanPunctuator() { |
| const start = this.index; |
| let str = this.source[this.index]; |
| switch (str) { |
| case "(": |
| case "{": |
| if (str === "{") { |
| this.curlyStack.push("{"); |
| } |
| ++this.index; |
| break; |
| case ".": |
| ++this.index; |
| if (this.source[this.index] === "." && this.source[this.index + 1] === ".") { |
| this.index += 2; |
| str = "..."; |
| } |
| break; |
| case "}": |
| ++this.index; |
| this.curlyStack.pop(); |
| break; |
| case "?": |
| ++this.index; |
| if (this.source[this.index] === "?") { |
| ++this.index; |
| if (this.source[this.index] === "=") { |
| ++this.index; |
| str = "??="; |
| } else { |
| str = "??"; |
| } |
| } |
| if (this.source[this.index] === "." && !/^\d$/.test(this.source[this.index + 1])) { |
| ++this.index; |
| str = "?."; |
| } |
| break; |
| case "#": |
| case ")": |
| case ";": |
| case ",": |
| case "[": |
| case "]": |
| case ":": |
| case "~": |
| case "@": |
| ++this.index; |
| break; |
| default: |
| str = this.source.substr(this.index, 4); |
| if (str === ">>>=") { |
| this.index += 4; |
| } else { |
| str = str.substr(0, 3); |
| if (str === "===" || str === "!==" || str === ">>>" || str === "<<=" || str === ">>=" || str === "**=" || str === "&&=" || str === "||=") { |
| this.index += 3; |
| } else { |
| str = str.substr(0, 2); |
| if (str === "&&" || str === "||" || str === "==" || str === "!=" || str === "+=" || str === "-=" || str === "*=" || str === "/=" || str === "++" || str === "--" || str === "<<" || str === ">>" || str === "&=" || str === "|=" || str === "^=" || str === "%=" || str === "<=" || str === ">=" || str === "=>" || str === "**") { |
| this.index += 2; |
| } else { |
| str = this.source[this.index]; |
| if ("<>=!+-*%&|^/".indexOf(str) >= 0) { |
| ++this.index; |
| } |
| } |
| } |
| } |
| } |
| if (this.index === start) { |
| this.throwUnexpectedToken(); |
| } |
| return { |
| type: 7 /* Punctuator */, |
| value: str, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| // https://tc39.github.io/ecma262/#sec-literals-numeric-literals |
| scanHexLiteral(start) { |
| let num = this.scanLiteralPart(Character.isHexDigitChar); |
| if (num.length === 0) { |
| this.throwUnexpectedToken(); |
| } |
| if (this.source[this.index] === "n") { |
| this.index++; |
| return { |
| type: 6 /* NumericLiteral */, |
| value: BigInt("0x" + num), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| if (Character.isIdentifierStart(this.source.charCodeAt(this.index))) { |
| this.throwUnexpectedToken(); |
| } |
| return { |
| type: 6 /* NumericLiteral */, |
| value: parseInt("0x" + num, 16), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| scanBinaryLiteral(start) { |
| let ch; |
| let num = this.scanLiteralPart((c) => c === "0" || c === "1"); |
| if (num.length === 0) { |
| this.throwUnexpectedToken(); |
| } |
| if (this.source[this.index] === "n") { |
| this.index++; |
| return { |
| type: 6 /* NumericLiteral */, |
| value: BigInt("0b" + num), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| if (!this.eof()) { |
| ch = this.source.charCodeAt(this.index); |
| if (Character.isIdentifierStart(ch) || Character.isDecimalDigit(ch)) { |
| this.throwUnexpectedToken(); |
| } |
| } |
| return { |
| type: 6 /* NumericLiteral */, |
| value: parseInt(num, 2), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| scanOctalLiteral(prefix, start) { |
| let num = ""; |
| let octal = false; |
| if (Character.isOctalDigit(prefix.charCodeAt(0))) { |
| octal = true; |
| num = "0" + this.source[this.index++]; |
| } else { |
| ++this.index; |
| } |
| num += this.scanLiteralPart(Character.isOctalDigitChar); |
| if (!octal && num.length === 0) { |
| this.throwUnexpectedToken(); |
| } |
| if (this.source[this.index] === "n") { |
| this.index++; |
| return { |
| type: 6 /* NumericLiteral */, |
| value: BigInt("0o" + num), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| if (Character.isIdentifierStart(this.source.charCodeAt(this.index)) || Character.isDecimalDigit(this.source.charCodeAt(this.index))) { |
| this.throwUnexpectedToken(); |
| } |
| return { |
| type: 6 /* NumericLiteral */, |
| value: parseInt(num, 8), |
| octal, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| isImplicitOctalLiteral() { |
| for (let i = this.index + 1; i < this.length; ++i) { |
| const ch = this.source[i]; |
| if (ch === "8" || ch === "9" || ch === "n") { |
| return false; |
| } |
| if (!Character.isOctalDigit(ch.charCodeAt(0))) { |
| return true; |
| } |
| } |
| return true; |
| } |
| scanLiteralPart(check) { |
| let num = ""; |
| if (this.source[this.index] === "_") |
| this.throwUnexpectedToken(Messages.NumericSeperatorNotAllowedHere); |
| while (this.source[this.index] && (check(this.source[this.index]) || this.source[this.index] === "_")) { |
| if (this.source[this.index] !== "_") |
| num += this.source[this.index]; |
| this.index++; |
| if (this.source[this.index - 1] === "_" && this.source[this.index] === "_") |
| this.throwUnexpectedToken(Messages.NumericSeperatorOneUnderscore); |
| } |
| if (this.source[this.index - 1] === "_") |
| this.throwUnexpectedToken(Messages.NumericSeperatorNotAllowedHere); |
| return num; |
| } |
| scanNumericLiteral() { |
| const start = this.index; |
| let ch = this.source[start]; |
| assert( |
| Character.isDecimalDigit(ch.charCodeAt(0)) || ch === ".", |
| "Numeric literal must start with a decimal digit or a decimal point" |
| ); |
| let num = ""; |
| if (ch !== ".") { |
| num = this.source[this.index++]; |
| ch = this.source[this.index]; |
| if (num === "0") { |
| if (ch === "x" || ch === "X") { |
| ++this.index; |
| return this.scanHexLiteral(start); |
| } |
| if (ch === "b" || ch === "B") { |
| ++this.index; |
| return this.scanBinaryLiteral(start); |
| } |
| if (ch === "o" || ch === "O") { |
| return this.scanOctalLiteral(ch, start); |
| } |
| if (ch && Character.isOctalDigit(ch.charCodeAt(0))) { |
| if (this.isImplicitOctalLiteral()) { |
| return this.scanOctalLiteral(ch, start); |
| } |
| } |
| } |
| this.index--; |
| num = this.scanLiteralPart(Character.isDecimalDigitChar); |
| ch = this.source[this.index]; |
| } |
| if (ch === ".") { |
| num += this.source[this.index++]; |
| num += this.scanLiteralPart(Character.isDecimalDigitChar); |
| ch = this.source[this.index]; |
| } |
| if (ch === "e" || ch === "E") { |
| num += this.source[this.index++]; |
| ch = this.source[this.index]; |
| if (ch === "+" || ch === "-") { |
| num += this.source[this.index++]; |
| } |
| if (Character.isDecimalDigit(this.source.charCodeAt(this.index))) { |
| num += this.scanLiteralPart(Character.isDecimalDigitChar); |
| } else { |
| this.throwUnexpectedToken(); |
| } |
| } else if (ch === "n") { |
| if (num.length > 1 && num[0] === "0") { |
| this.throwUnexpectedToken(); |
| } |
| this.index++; |
| return { |
| type: 6 /* NumericLiteral */, |
| value: BigInt(num), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| if (Character.isIdentifierStart(this.source.charCodeAt(this.index))) { |
| this.throwUnexpectedToken(); |
| } |
| return { |
| type: 6 /* NumericLiteral */, |
| value: parseFloat(num), |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| // https://tc39.github.io/ecma262/#sec-literals-string-literals |
| scanStringLiteral() { |
| const start = this.index; |
| let quote = this.source[start]; |
| assert( |
| quote === "'" || quote === '"', |
| "String literal must starts with a quote" |
| ); |
| ++this.index; |
| let octal = false; |
| let str = ""; |
| while (!this.eof()) { |
| let ch = this.source[this.index++]; |
| if (ch === quote) { |
| quote = ""; |
| break; |
| } else if (ch === "\\") { |
| ch = this.source[this.index++]; |
| if (!ch || !Character.isLineTerminator(ch.charCodeAt(0))) { |
| switch (ch) { |
| case "u": |
| if (this.source[this.index] === "{") { |
| ++this.index; |
| str += this.scanUnicodeCodePointEscape(); |
| } else { |
| const unescapedChar = this.scanHexEscape(ch); |
| if (unescapedChar === null) { |
| this.throwUnexpectedToken(); |
| } |
| str += unescapedChar; |
| } |
| break; |
| case "x": |
| const unescaped = this.scanHexEscape(ch); |
| if (unescaped === null) { |
| this.throwUnexpectedToken(Messages.InvalidHexEscapeSequence); |
| } |
| str += unescaped; |
| break; |
| case "n": |
| str += "\n"; |
| break; |
| case "r": |
| str += "\r"; |
| break; |
| case "t": |
| str += " "; |
| break; |
| case "b": |
| str += "\b"; |
| break; |
| case "f": |
| str += "\f"; |
| break; |
| case "v": |
| str += "\v"; |
| break; |
| case "8": |
| case "9": |
| str += ch; |
| this.tolerateUnexpectedToken(); |
| break; |
| default: |
| if (ch && Character.isOctalDigit(ch.charCodeAt(0))) { |
| const octToDec = this.octalToDecimal(ch); |
| octal = octToDec.octal || octal; |
| str += String.fromCharCode(octToDec.code); |
| } else { |
| str += ch; |
| } |
| break; |
| } |
| } else { |
| ++this.lineNumber; |
| if (ch === "\r" && this.source[this.index] === "\n") { |
| ++this.index; |
| } |
| this.lineStart = this.index; |
| } |
| } else if (Character.isLineTerminator(ch.charCodeAt(0))) { |
| break; |
| } else { |
| str += ch; |
| } |
| } |
| if (quote !== "") { |
| this.index = start; |
| this.throwUnexpectedToken(); |
| } |
| return { |
| type: 8 /* StringLiteral */, |
| value: str, |
| octal, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| // https://tc39.github.io/ecma262/#sec-template-literal-lexical-components |
| scanTemplate() { |
| let cooked = ""; |
| let terminated = false; |
| const start = this.index; |
| const head = this.source[start] === "`"; |
| let tail = false; |
| let notEscapeSequenceHead = null; |
| let rawOffset = 2; |
| ++this.index; |
| while (!this.eof()) { |
| let ch = this.source[this.index++]; |
| if (ch === "`") { |
| rawOffset = 1; |
| tail = true; |
| terminated = true; |
| break; |
| } else if (ch === "$") { |
| if (this.source[this.index] === "{") { |
| this.curlyStack.push("${"); |
| ++this.index; |
| terminated = true; |
| break; |
| } |
| cooked += ch; |
| } else if (notEscapeSequenceHead !== null) { |
| continue; |
| } else if (ch === "\\") { |
| ch = this.source[this.index++]; |
| if (!Character.isLineTerminator(ch.charCodeAt(0))) { |
| switch (ch) { |
| case "n": |
| cooked += "\n"; |
| break; |
| case "r": |
| cooked += "\r"; |
| break; |
| case "t": |
| cooked += " "; |
| break; |
| case "u": |
| if (this.source[this.index] === "{") { |
| ++this.index; |
| const unicodeCodePointEscape = this.tryToScanUnicodeCodePointEscape(); |
| if (unicodeCodePointEscape === null) { |
| notEscapeSequenceHead = "u"; |
| } else { |
| cooked += unicodeCodePointEscape; |
| } |
| } else { |
| const unescapedChar = this.scanHexEscape(ch); |
| if (unescapedChar === null) { |
| notEscapeSequenceHead = "u"; |
| } else { |
| cooked += unescapedChar; |
| } |
| } |
| break; |
| case "x": |
| const unescaped = this.scanHexEscape(ch); |
| if (unescaped === null) { |
| notEscapeSequenceHead = "x"; |
| } else { |
| cooked += unescaped; |
| } |
| break; |
| case "b": |
| cooked += "\b"; |
| break; |
| case "f": |
| cooked += "\f"; |
| break; |
| case "v": |
| cooked += "\v"; |
| break; |
| default: |
| if (ch === "0") { |
| if (Character.isDecimalDigit(this.source.charCodeAt(this.index))) { |
| notEscapeSequenceHead = "0"; |
| } else { |
| cooked += "\0"; |
| } |
| } else if (Character.isDecimalDigitChar(ch)) { |
| notEscapeSequenceHead = ch; |
| } else { |
| cooked += ch; |
| } |
| break; |
| } |
| } else { |
| ++this.lineNumber; |
| if (ch === "\r" && this.source[this.index] === "\n") { |
| ++this.index; |
| } |
| this.lineStart = this.index; |
| } |
| } else if (Character.isLineTerminator(ch.charCodeAt(0))) { |
| ++this.lineNumber; |
| if (ch === "\r" && this.source[this.index] === "\n") { |
| ++this.index; |
| } |
| this.lineStart = this.index; |
| cooked += "\n"; |
| } else { |
| cooked += ch; |
| } |
| } |
| if (!terminated) { |
| this.throwUnexpectedToken(); |
| } |
| if (!head) { |
| this.curlyStack.pop(); |
| } |
| return { |
| type: 10 /* Template */, |
| value: this.source.slice(start + 1, this.index - rawOffset), |
| cooked: notEscapeSequenceHead === null ? cooked : null, |
| head, |
| tail, |
| notEscapeSequenceHead, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| // https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals |
| testRegExp(pattern, flags) { |
| const astralSubstitute = "\uFFFF"; |
| let tmp = pattern; |
| if (flags.indexOf("u") >= 0) { |
| tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, ($0, $1, $2) => { |
| const codePoint = parseInt($1 || $2, 16); |
| if (codePoint > 1114111) { |
| this.throwUnexpectedToken(Messages.InvalidRegExp); |
| } |
| if (codePoint <= 65535) { |
| return String.fromCharCode(codePoint); |
| } |
| return astralSubstitute; |
| }).replace( |
| /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, |
| astralSubstitute |
| ); |
| } |
| try { |
| RegExp(tmp); |
| } catch (e) { |
| this.throwUnexpectedToken(Messages.InvalidRegExp); |
| } |
| try { |
| return new RegExp(pattern, flags); |
| } catch (exception) { |
| return null; |
| } |
| } |
| scanRegExpBody() { |
| let ch = this.source[this.index]; |
| assert(ch === "/", "Regular expression literal must start with a slash"); |
| let str = this.source[this.index++]; |
| let classMarker = false; |
| let terminated = false; |
| while (!this.eof()) { |
| ch = this.source[this.index++]; |
| str += ch; |
| if (ch === "\\") { |
| ch = this.source[this.index++]; |
| if (Character.isLineTerminator(ch.charCodeAt(0))) { |
| this.throwUnexpectedToken(Messages.UnterminatedRegExp); |
| } |
| str += ch; |
| } else if (Character.isLineTerminator(ch.charCodeAt(0))) { |
| this.throwUnexpectedToken(Messages.UnterminatedRegExp); |
| } else if (classMarker) { |
| if (ch === "]") { |
| classMarker = false; |
| } |
| } else { |
| if (ch === "/") { |
| terminated = true; |
| break; |
| } else if (ch === "[") { |
| classMarker = true; |
| } |
| } |
| } |
| if (!terminated) { |
| this.throwUnexpectedToken(Messages.UnterminatedRegExp); |
| } |
| return str.substr(1, str.length - 2); |
| } |
| scanRegExpFlags() { |
| let str = ""; |
| let flags = ""; |
| while (!this.eof()) { |
| let ch = this.source[this.index]; |
| if (!Character.isIdentifierPart(ch.charCodeAt(0))) { |
| break; |
| } |
| ++this.index; |
| if (ch === "\\" && !this.eof()) { |
| ch = this.source[this.index]; |
| if (ch === "u") { |
| ++this.index; |
| let restore = this.index; |
| const char = this.scanHexEscape("u"); |
| if (char !== null) { |
| flags += char; |
| for (str += "\\u"; restore < this.index; ++restore) { |
| str += this.source[restore]; |
| } |
| } else { |
| this.index = restore; |
| flags += "u"; |
| str += "\\u"; |
| } |
| this.tolerateUnexpectedToken(); |
| } else { |
| str += "\\"; |
| this.tolerateUnexpectedToken(); |
| } |
| } else { |
| flags += ch; |
| str += ch; |
| } |
| } |
| return flags; |
| } |
| scanRegExp() { |
| const start = this.index; |
| const pattern = this.scanRegExpBody(); |
| const flags = this.scanRegExpFlags(); |
| const value = this.testRegExp(pattern, flags); |
| return { |
| type: 9 /* RegularExpression */, |
| value: "", |
| pattern, |
| flags, |
| regex: value, |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start, |
| end: this.index |
| }; |
| } |
| lex() { |
| if (this.eof()) { |
| return { |
| type: 2 /* EOF */, |
| value: "", |
| lineNumber: this.lineNumber, |
| lineStart: this.lineStart, |
| start: this.index, |
| end: this.index |
| }; |
| } |
| const cp = this.source.charCodeAt(this.index); |
| if (Character.isIdentifierStart(cp)) { |
| return this.scanIdentifier(); |
| } |
| if (cp === 40 || cp === 41 || cp === 59) { |
| return this.scanPunctuator(); |
| } |
| if (cp === 39 || cp === 34) { |
| return this.scanStringLiteral(); |
| } |
| if (cp === 46) { |
| if (Character.isDecimalDigit(this.source.charCodeAt(this.index + 1))) { |
| return this.scanNumericLiteral(); |
| } |
| return this.scanPunctuator(); |
| } |
| if (Character.isDecimalDigit(cp)) { |
| return this.scanNumericLiteral(); |
| } |
| if (cp === 96 || cp === 125 && this.curlyStack[this.curlyStack.length - 1] === "${") { |
| return this.scanTemplate(); |
| } |
| if (cp >= 55296 && cp < 57343) { |
| if (Character.isIdentifierStart(this.codePointAt(this.index))) { |
| return this.scanIdentifier(); |
| } |
| } |
| return this.scanPunctuator(); |
| } |
| }; |
| |
| // src/parser.ts |
| var ArrowParameterPlaceHolder = "ArrowParameterPlaceHolder"; |
| var Parser = class { |
| config; |
| delegate; |
| errorHandler; |
| scanner; |
| operatorPrecedence; |
| lookahead; |
| hasLineTerminator; |
| context; |
| tokens; |
| startMarker; |
| lastMarker; |
| constructor(code, options = {}, delegate) { |
| this.config = { |
| range: typeof options.range === "boolean" && options.range, |
| loc: typeof options.loc === "boolean" && options.loc, |
| source: null, |
| tokens: typeof options.tokens === "boolean" && options.tokens, |
| comment: typeof options.comment === "boolean" && options.comment, |
| tolerant: typeof options.tolerant === "boolean" && options.tolerant |
| }; |
| if (this.config.loc && options.source && options.source !== null) { |
| this.config.source = String(options.source); |
| } |
| this.delegate = delegate; |
| this.errorHandler = new ErrorHandler(); |
| this.errorHandler.tolerant = this.config.tolerant == true; |
| this.scanner = new Scanner(code, this.errorHandler); |
| this.scanner.trackComment = this.config.comment == true; |
| this.operatorPrecedence = { |
| ")": 0, |
| ";": 0, |
| ",": 0, |
| "=": 0, |
| "]": 0, |
| "??": 5, |
| "||": 6, |
| "&&": 7, |
| "|": 8, |
| "^": 9, |
| "&": 10, |
| "==": 11, |
| "!=": 11, |
| "===": 11, |
| "!==": 11, |
| "<": 12, |
| ">": 12, |
| "<=": 12, |
| ">=": 12, |
| "<<": 13, |
| ">>": 13, |
| ">>>": 13, |
| "+": 14, |
| "-": 14, |
| "*": 15, |
| "/": 15, |
| "%": 15 |
| }; |
| this.lookahead = { |
| type: 2 /* EOF */, |
| value: "", |
| lineNumber: this.scanner.lineNumber, |
| lineStart: 0, |
| start: 0, |
| end: 0 |
| }; |
| this.hasLineTerminator = false; |
| this.context = { |
| isModule: false, |
| isAsync: false, |
| allowIn: true, |
| allowStrictDirective: true, |
| allowSuper: false, |
| allowYield: true, |
| firstCoverInitializedNameError: null, |
| isAssignmentTarget: false, |
| isBindingElement: false, |
| inConstructor: false, |
| inFunctionBody: false, |
| inIteration: false, |
| inSwitch: false, |
| inClassConstructor: false, |
| labelSet: {}, |
| strict: false, |
| decorators: null |
| }; |
| this.tokens = []; |
| this.startMarker = { |
| index: 0, |
| line: this.scanner.lineNumber, |
| column: 0 |
| }; |
| this.lastMarker = { |
| index: 0, |
| line: this.scanner.lineNumber, |
| column: 0 |
| }; |
| this.nextToken(); |
| this.lastMarker = { |
| index: this.scanner.index, |
| line: this.scanner.lineNumber, |
| column: this.scanner.index - this.scanner.lineStart |
| }; |
| } |
| throwError(messageFormat, ...values) { |
| const args = values.slice(); |
| const msg = messageFormat.replace( |
| /%(\d)/g, |
| (whole, idx) => { |
| assert(idx < args.length, "Message reference must be in range"); |
| return args[idx]; |
| } |
| ); |
| const index = this.lastMarker.index; |
| const line = this.lastMarker.line; |
| const column = this.lastMarker.column + 1; |
| throw this.errorHandler.createError(index, line, column, msg); |
| } |
| tolerateError(messageFormat, ...values) { |
| const args = values.slice(); |
| const msg = messageFormat.replace( |
| /%(\d)/g, |
| (whole, idx) => { |
| assert(idx < args.length, "Message reference must be in range"); |
| return args[idx]; |
| } |
| ); |
| const index = this.lastMarker.index; |
| const line = this.scanner.lineNumber; |
| const column = this.lastMarker.column + 1; |
| this.errorHandler.tolerateError(index, line, column, msg); |
| } |
| // Throw an exception because of the token. |
| unexpectedTokenError(token, message) { |
| let msg = message || Messages.UnexpectedToken; |
| let value; |
| if (token) { |
| if (!message) { |
| msg = token.type === 2 /* EOF */ ? Messages.UnexpectedEOS : token.type === 3 /* Identifier */ ? Messages.UnexpectedIdentifier : token.type === 6 /* NumericLiteral */ ? Messages.UnexpectedNumber : token.type === 8 /* StringLiteral */ ? Messages.UnexpectedString : token.type === 10 /* Template */ ? Messages.UnexpectedTemplate : Messages.UnexpectedToken; |
| if (token.type === 4 /* Keyword */) { |
| if (this.scanner.isFutureReservedWord(token.value)) { |
| msg = Messages.UnexpectedReserved; |
| } else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) { |
| msg = Messages.StrictReservedWord; |
| } |
| } |
| } |
| value = token.value; |
| } else { |
| value = "ILLEGAL"; |
| } |
| msg = msg.replace("%0", value); |
| if (token && typeof token.lineNumber === "number") { |
| const index = token.start; |
| const line = token.lineNumber; |
| const lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column; |
| const column = token.start - lastMarkerLineStart + 1; |
| return this.errorHandler.createError(index, line, column, msg); |
| } else { |
| const index = this.lastMarker.index; |
| const line = this.lastMarker.line; |
| const column = this.lastMarker.column + 1; |
| return this.errorHandler.createError(index, line, column, msg); |
| } |
| } |
| throwUnexpectedToken(token, message) { |
| throw this.unexpectedTokenError(token, message); |
| } |
| tolerateUnexpectedToken(token, message) { |
| this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); |
| } |
| tolerateInvalidLoopStatement() { |
| if (this.matchKeyword("class") || this.matchKeyword("function")) { |
| this.tolerateError(Messages.UnexpectedToken, this.lookahead); |
| } |
| } |
| collectComments() { |
| if (!this.config.comment) { |
| this.scanner.scanComments(); |
| } else { |
| const comments = this.scanner.scanComments(); |
| if (comments.length > 0 && this.delegate) { |
| for (let i = 0; i < comments.length; ++i) { |
| const e = comments[i]; |
| const node = { |
| type: e.multiLine ? "BlockComment" : "LineComment", |
| value: this.scanner.source.slice(e.slice[0], e.slice[1]) |
| }; |
| if (this.config.range) { |
| node.range = e.range; |
| } |
| if (this.config.loc) { |
| node.loc = e.loc; |
| } |
| const metadata = { |
| start: { |
| line: e.loc.start.line, |
| column: e.loc.start.column, |
| offset: e.range[0] |
| }, |
| end: { |
| line: e.loc.end.line, |
| column: e.loc.end.column, |
| offset: e.range[1] |
| } |
| }; |
| this.delegate(node, metadata); |
| } |
| } |
| } |
| } |
| // From internal representation to an external structure |
| getTokenRaw(token) { |
| return this.scanner.source.slice(token.start, token.end); |
| } |
| convertToken(token) { |
| const t = { |
| type: TokenName[token.type], |
| value: this.getTokenRaw(token) |
| }; |
| if (this.config.range) { |
| t.range = [token.start, token.end]; |
| } |
| if (this.config.loc) { |
| t.loc = { |
| start: { |
| line: this.startMarker.line, |
| column: this.startMarker.column |
| }, |
| end: { |
| line: this.scanner.lineNumber, |
| column: this.scanner.index - this.scanner.lineStart |
| } |
| }; |
| } |
| if (token.type === 9 /* RegularExpression */) { |
| const pattern = token.pattern; |
| const flags = token.flags; |
| t.regex = { pattern, flags }; |
| } |
| return t; |
| } |
| nextToken() { |
| const token = this.lookahead; |
| this.lastMarker.index = this.scanner.index; |
| this.lastMarker.line = this.scanner.lineNumber; |
| this.lastMarker.column = this.scanner.index - this.scanner.lineStart; |
| this.collectComments(); |
| if (this.scanner.index !== this.startMarker.index) { |
| this.startMarker.index = this.scanner.index; |
| this.startMarker.line = this.scanner.lineNumber; |
| this.startMarker.column = this.scanner.index - this.scanner.lineStart; |
| } |
| const next = this.scanner.lex(); |
| this.hasLineTerminator = token.lineNumber !== next.lineNumber; |
| if (next && this.context.strict && next.type === 3 /* Identifier */) { |
| if (this.scanner.isStrictModeReservedWord(next.value)) { |
| next.type = 4 /* Keyword */; |
| } |
| } |
| this.lookahead = next; |
| if (this.config.tokens && next.type !== 2 /* EOF */) { |
| this.tokens.push(this.convertToken(next)); |
| } |
| return token; |
| } |
| nextRegexToken() { |
| this.collectComments(); |
| const token = this.scanner.scanRegExp(); |
| if (this.config.tokens) { |
| this.tokens.pop(); |
| this.tokens.push(this.convertToken(token)); |
| } |
| this.lookahead = token; |
| this.nextToken(); |
| return token; |
| } |
| createNode() { |
| return { |
| index: this.startMarker.index, |
| line: this.startMarker.line, |
| column: this.startMarker.column |
| }; |
| } |
| startNode(token, lastLineStart = 0) { |
| let column = token.start - token.lineStart; |
| let line = token.lineNumber; |
| if (column < 0) { |
| column += lastLineStart; |
| line--; |
| } |
| return { |
| index: token.start, |
| line, |
| column |
| }; |
| } |
| finalize(marker, node) { |
| if (this.config.range) { |
| node.range = [marker.index, this.lastMarker.index]; |
| } |
| if (this.config.loc) { |
| node.loc = { |
| start: { |
| line: marker.line, |
| column: marker.column |
| }, |
| end: { |
| line: this.lastMarker.line, |
| column: this.lastMarker.column |
| } |
| }; |
| if (this.config.source) { |
| node.loc.source = this.config.source; |
| } |
| } |
| if (this.delegate) { |
| const metadata = { |
| start: { |
| line: marker.line, |
| column: marker.column, |
| offset: marker.index |
| }, |
| end: { |
| line: this.lastMarker.line, |
| column: this.lastMarker.column, |
| offset: this.lastMarker.index |
| } |
| }; |
| this.delegate(node, metadata); |
| } |
| return node; |
| } |
| // Expect the next token to match the specified punctuator. |
| // If not, an exception will be thrown. |
| expect(value) { |
| const token = this.nextToken(); |
| if (token.type !== 7 /* Punctuator */ || token.value !== value) { |
| this.throwUnexpectedToken(token); |
| } |
| } |
| // Quietly expect a comma when in tolerant mode, otherwise delegates to expect(). |
| expectCommaSeparator() { |
| if (this.config.tolerant) { |
| const token = this.lookahead; |
| if (token.type === 7 /* Punctuator */ && token.value === ",") { |
| this.nextToken(); |
| } else if (token.type === 7 /* Punctuator */ && token.value === ";") { |
| this.nextToken(); |
| this.tolerateUnexpectedToken(token); |
| } else { |
| this.tolerateUnexpectedToken(token, Messages.UnexpectedToken); |
| } |
| } else { |
| this.expect(","); |
| } |
| } |
| // Expect the next token to match the specified keyword. |
| // If not, an exception will be thrown. |
| expectKeyword(keyword) { |
| const token = this.nextToken(); |
| if (token.type !== 4 /* Keyword */ || token.value !== keyword) { |
| this.throwUnexpectedToken(token); |
| } |
| } |
| // Return true if the next token matches the specified punctuator. |
| match(value) { |
| return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value; |
| } |
| // Return true if the next token matches the specified keyword |
| matchKeyword(keyword) { |
| return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword; |
| } |
| // Return true if the next token matches the specified contextual keyword |
| // (where an identifier is sometimes a keyword depending on the context) |
| matchContextualKeyword(keyword) { |
| return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword; |
| } |
| // Return true if the next token is an assignment operator |
| matchAssign() { |
| if (this.lookahead.type !== 7 /* Punctuator */) { |
| return false; |
| } |
| const op = this.lookahead.value; |
| return op === "=" || op === "*=" || op === "**=" || op === "/=" || op === "%=" || op === "+=" || op === "-=" || op === "<<=" || op === ">>=" || op === ">>>=" || op === "&=" || op === "^=" || op === "|=" || op === "&&=" || op === "||=" || op === "??="; |
| } |
| // Cover grammar support. |
| // |
| // When an assignment expression position starts with an left parenthesis, the determination of the type |
| // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) |
| // or the first comma. This situation also defers the determination of all the expressions nested in the pair. |
| // |
| // There are three productions that can be parsed in a parentheses pair that needs to be determined |
| // after the outermost pair is closed. They are: |
| // |
| // 1. AssignmentExpression |
| // 2. BindingElements |
| // 3. AssignmentTargets |
| // |
| // In order to avoid exponential backtracking, we use two flags to denote if the production can be |
| // binding element or assignment target. |
| // |
| // The three productions have the relationship: |
| // |
| // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression |
| // |
| // with a single exception that CoverInitializedName when used directly in an Expression, generates |
| // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the |
| // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. |
| // |
| // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not |
| // effect the current flags. This means the production the parser parses is only used as an expression. Therefore |
| // the CoverInitializedName check is conducted. |
| // |
| // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates |
| // the flags outside of the parser. This means the production the parser parses is used as a part of a potential |
| // pattern. The CoverInitializedName check is deferred. |
| isolateCoverGrammar(parseFunction) { |
| const previousIsBindingElement = this.context.isBindingElement; |
| const previousIsAssignmentTarget = this.context.isAssignmentTarget; |
| const previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; |
| this.context.isBindingElement = true; |
| this.context.isAssignmentTarget = true; |
| this.context.firstCoverInitializedNameError = null; |
| const result = parseFunction.call(this); |
| if (this.context.firstCoverInitializedNameError !== null) { |
| this.throwUnexpectedToken(this.context.firstCoverInitializedNameError); |
| } |
| this.context.isBindingElement = previousIsBindingElement; |
| this.context.isAssignmentTarget = previousIsAssignmentTarget; |
| this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; |
| return result; |
| } |
| inheritCoverGrammar(parseFunction) { |
| const previousIsBindingElement = this.context.isBindingElement; |
| const previousIsAssignmentTarget = this.context.isAssignmentTarget; |
| const previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; |
| this.context.isBindingElement = true; |
| this.context.isAssignmentTarget = true; |
| this.context.firstCoverInitializedNameError = null; |
| const result = parseFunction.call(this); |
| this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement; |
| this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget; |
| this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError; |
| return result; |
| } |
| consumeSemicolon() { |
| if (this.match(";")) { |
| this.nextToken(); |
| } else if (!this.hasLineTerminator) { |
| if (this.lookahead.type !== 2 /* EOF */ && !this.match("}")) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| this.lastMarker.index = this.startMarker.index; |
| this.lastMarker.line = this.startMarker.line; |
| this.lastMarker.column = this.startMarker.column; |
| } |
| } |
| // https://tc39.github.io/ecma262/#sec-primary-expression |
| parsePrimaryExpression() { |
| const node = this.createNode(); |
| let expr; |
| let token, raw; |
| switch (this.lookahead.type) { |
| case 3 /* Identifier */: |
| if ((this.context.isModule || this.context.isAsync) && this.lookahead.value === "await") { |
| this.tolerateUnexpectedToken(this.lookahead); |
| } |
| expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Identifier(this.nextToken().value)); |
| break; |
| case 6 /* NumericLiteral */: |
| case 8 /* StringLiteral */: |
| if (this.context.strict && this.lookahead.octal) { |
| this.tolerateUnexpectedToken(this.lookahead, Messages.StrictOctalLiteral); |
| } |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| token = this.nextToken(); |
| raw = this.getTokenRaw(token); |
| if (typeof token.value === "bigint") |
| expr = this.finalize(node, new BigIntLiteral(token.value, raw, token.value.toString())); |
| else |
| expr = this.finalize(node, new Literal(token.value, raw)); |
| break; |
| case 1 /* BooleanLiteral */: |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| token = this.nextToken(); |
| raw = this.getTokenRaw(token); |
| expr = this.finalize(node, new Literal(token.value === "true", raw)); |
| break; |
| case 5 /* NullLiteral */: |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| token = this.nextToken(); |
| raw = this.getTokenRaw(token); |
| expr = this.finalize(node, new Literal(null, raw)); |
| break; |
| case 10 /* Template */: |
| expr = this.parseTemplateLiteral({ isTagged: false }); |
| break; |
| case 7 /* Punctuator */: |
| switch (this.lookahead.value) { |
| case "(": |
| this.context.isBindingElement = false; |
| expr = this.inheritCoverGrammar(this.parseGroupExpression); |
| break; |
| case "[": |
| expr = this.inheritCoverGrammar(this.parseArrayInitializer); |
| break; |
| case "{": |
| expr = this.inheritCoverGrammar(this.parseObjectInitializer); |
| break; |
| case "/": |
| case "/=": |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| this.scanner.index = this.startMarker.index; |
| token = this.nextRegexToken(); |
| raw = this.getTokenRaw(token); |
| expr = this.finalize(node, new RegexLiteral(token.regex, raw, token.pattern, token.flags)); |
| break; |
| case "#": |
| this.nextToken(); |
| expr = this.finalize(node, new PrivateIdentifier(this.nextToken().value)); |
| break; |
| case "@": |
| let decorators = this.parseDecorators(); |
| this.context.decorators = decorators; |
| let expression = this.parsePrimaryExpression(); |
| this.context.decorators = null; |
| expr = this.finalize(node, new PrivateIdentifier(this.nextToken().value)); |
| break; |
| default: |
| expr = this.throwUnexpectedToken(this.nextToken()); |
| } |
| break; |
| case 4 /* Keyword */: |
| if (!this.context.strict && this.context.allowYield && this.matchKeyword("yield")) { |
| expr = this.parseIdentifierName(); |
| } else if (!this.context.strict && this.matchKeyword("let")) { |
| expr = this.finalize(node, new Identifier(this.nextToken().value)); |
| } else { |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| if (this.matchKeyword("function")) { |
| expr = this.parseFunctionExpression(); |
| } else if (this.matchKeyword("this")) { |
| this.nextToken(); |
| expr = this.finalize(node, new ThisExpression()); |
| } else if (this.matchKeyword("class")) { |
| expr = this.parseClassExpression(); |
| } else if (this.matchKeyword("new")) { |
| expr = this.parseNewExpression(); |
| } else if (this.matchImportCall()) { |
| expr = this.parseImportCall(); |
| } else if (this.matchImportMeta()) { |
| if (!this.context.isModule) { |
| this.tolerateUnexpectedToken(this.lookahead, Messages.CannotUseImportMetaOutsideAModule); |
| } |
| expr = this.parseImportMeta(); |
| } else { |
| expr = this.throwUnexpectedToken(this.nextToken()); |
| } |
| } |
| break; |
| default: |
| expr = this.throwUnexpectedToken(this.nextToken()); |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-array-initializer |
| parseSpreadElement() { |
| const node = this.createNode(); |
| this.expect("..."); |
| const arg = this.inheritCoverGrammar(this.parseAssignmentExpression); |
| return this.finalize(node, new SpreadElement(arg)); |
| } |
| parseArrayInitializer() { |
| const node = this.createNode(); |
| const elements = []; |
| this.expect("["); |
| while (!this.match("]")) { |
| if (this.match(",")) { |
| this.nextToken(); |
| elements.push(null); |
| } else if (this.match("...")) { |
| const element = this.parseSpreadElement(); |
| if (!this.match("]")) { |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| this.expect(","); |
| } |
| elements.push(element); |
| } else { |
| elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); |
| if (!this.match("]")) { |
| this.expect(","); |
| } |
| } |
| } |
| this.expect("]"); |
| return this.finalize(node, new ArrayExpression(elements)); |
| } |
| // https://tc39.github.io/ecma262/#sec-object-initializer |
| parsePropertyMethod(params) { |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| const previousStrict = this.context.strict; |
| const previousAllowStrictDirective = this.context.allowStrictDirective; |
| this.context.allowStrictDirective = params.simple; |
| const body = this.isolateCoverGrammar(this.parseFunctionSourceElements); |
| if (this.context.strict && params.firstRestricted) { |
| this.tolerateUnexpectedToken(params.firstRestricted, params.message); |
| } |
| if (this.context.strict && params.stricted) { |
| this.tolerateUnexpectedToken(params.stricted, params.message); |
| } |
| this.context.strict = previousStrict; |
| this.context.allowStrictDirective = previousAllowStrictDirective; |
| return body; |
| } |
| parsePropertyMethodFunction(isGenerator) { |
| const node = this.createNode(); |
| const previousAllowYield = this.context.allowYield; |
| this.context.allowYield = true; |
| const params = this.parseFormalParameters(); |
| const method = this.parsePropertyMethod(params); |
| this.context.allowYield = previousAllowYield; |
| return this.finalize(node, new FunctionExpression(null, params.params, method, isGenerator, false)); |
| } |
| parsePropertyMethodAsyncFunction(isGenerator) { |
| const node = this.createNode(); |
| const previousAllowYield = this.context.allowYield; |
| const previousIsAsync = this.context.isAsync; |
| this.context.allowYield = false; |
| this.context.isAsync = true; |
| const params = this.parseFormalParameters(); |
| const method = this.parsePropertyMethod(params); |
| this.context.allowYield = previousAllowYield; |
| this.context.isAsync = previousIsAsync; |
| return this.finalize(node, new FunctionExpression(null, params.params, method, isGenerator, true)); |
| } |
| parseObjectPropertyKey(isPrivate = false) { |
| const node = this.createNode(); |
| const token = this.nextToken(); |
| let key; |
| switch (token.type) { |
| case 8 /* StringLiteral */: |
| case 6 /* NumericLiteral */: |
| if (this.context.strict && token.octal) { |
| this.tolerateUnexpectedToken(token, Messages.StrictOctalLiteral); |
| } |
| const raw = this.getTokenRaw(token); |
| if (typeof token.value === "bigint") |
| key = this.finalize(node, new BigIntLiteral(token.value, raw, token.value.toString())); |
| else |
| key = this.finalize(node, new Literal(token.value, raw)); |
| break; |
| case 3 /* Identifier */: |
| case 1 /* BooleanLiteral */: |
| case 5 /* NullLiteral */: |
| case 4 /* Keyword */: |
| key = this.finalize(node, isPrivate ? new PrivateIdentifier(token.value) : new Identifier(token.value)); |
| break; |
| case 7 /* Punctuator */: |
| if (token.value === "[") { |
| key = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| this.expect("]"); |
| } else { |
| key = this.throwUnexpectedToken(token); |
| } |
| break; |
| default: |
| key = this.throwUnexpectedToken(token); |
| } |
| return key; |
| } |
| isPropertyKey(key, value) { |
| return key.type === "Identifier" /* Identifier */ && key.name === value || key.type === "Literal" /* Literal */ && key.value === value; |
| } |
| parseObjectProperty(hasProto) { |
| const node = this.createNode(); |
| const token = this.lookahead; |
| let kind; |
| let key = null; |
| let value = null; |
| let computed = false; |
| let method = false; |
| let shorthand = false; |
| let isAsync = false; |
| let isGenerator = false; |
| if (token.type === 3 /* Identifier */) { |
| const id = token.value; |
| this.nextToken(); |
| computed = this.match("["); |
| isAsync = !this.hasLineTerminator && id === "async" && !this.match(":") && !this.match("(") && !this.match(","); |
| isGenerator = this.match("*"); |
| if (isGenerator) { |
| this.nextToken(); |
| } |
| key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Identifier(id)); |
| } else if (this.match("*")) { |
| this.nextToken(); |
| } else { |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(); |
| } |
| const lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); |
| if (token.type === 3 /* Identifier */ && !isAsync && token.value === "get" && lookaheadPropertyKey) { |
| kind = "get"; |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(); |
| this.context.allowYield = false; |
| value = this.parseGetterMethod(); |
| } else if (token.type === 3 /* Identifier */ && !isAsync && token.value === "set" && lookaheadPropertyKey) { |
| kind = "set"; |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(); |
| value = this.parseSetterMethod(); |
| } else if (token.type === 7 /* Punctuator */ && token.value === "*" && lookaheadPropertyKey) { |
| kind = "init"; |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(); |
| value = this.parseGeneratorMethod(false); |
| method = true; |
| } else { |
| if (!key) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| kind = "init"; |
| if (this.match(":") && !isAsync) { |
| if (!computed && this.isPropertyKey(key, "__proto__")) { |
| if (hasProto.value) { |
| this.tolerateError(Messages.DuplicateProtoProperty); |
| } |
| hasProto.value = true; |
| } |
| this.nextToken(); |
| value = this.inheritCoverGrammar(this.parseAssignmentExpression); |
| } else if (this.match("(")) { |
| value = isAsync ? this.parsePropertyMethodAsyncFunction(isGenerator) : this.parsePropertyMethodFunction(isGenerator); |
| method = true; |
| } else if (token.type === 3 /* Identifier */) { |
| const id = this.finalize(node, new Identifier(token.value)); |
| if (this.match("=")) { |
| this.context.firstCoverInitializedNameError = this.lookahead; |
| this.nextToken(); |
| shorthand = true; |
| const init = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| value = this.finalize(node, new AssignmentPattern(id, init)); |
| } else { |
| shorthand = true; |
| value = id; |
| } |
| } else { |
| this.throwUnexpectedToken(this.nextToken()); |
| } |
| } |
| return this.finalize(node, new Property(kind, key, computed, value, method, shorthand)); |
| } |
| parseObjectInitializer() { |
| const node = this.createNode(); |
| this.expect("{"); |
| const properties = []; |
| const hasProto = { value: false }; |
| while (!this.match("}")) { |
| const property = this.match("...") ? this.parseSpreadElement() : this.parseObjectProperty(hasProto); |
| properties.push(property); |
| if (!this.match("}") && (!property.method || this.match(","))) { |
| this.expectCommaSeparator(); |
| } |
| } |
| this.expect("}"); |
| return this.finalize(node, new ObjectExpression(properties)); |
| } |
| // https://tc39.es/proposal-template-literal-revision/#sec-static-semantics-template-early-errors |
| throwTemplateLiteralEarlyErrors(token) { |
| switch (token.notEscapeSequenceHead) { |
| case "u": |
| return this.throwUnexpectedToken(token, Messages.InvalidUnicodeEscapeSequence); |
| case "x": |
| return this.throwUnexpectedToken(token, Messages.InvalidHexEscapeSequence); |
| case "8": |
| case "9": |
| return this.throwUnexpectedToken(token, Messages.TemplateEscape89); |
| default: |
| return this.throwUnexpectedToken(token, Messages.TemplateOctalLiteral); |
| } |
| } |
| // https://tc39.github.io/ecma262/#sec-template-literals |
| parseTemplateHead(options) { |
| assert(this.lookahead.head, "Template literal must start with a template head"); |
| const node = this.createNode(); |
| const token = this.nextToken(); |
| if (!options.isTagged && token.notEscapeSequenceHead !== null) { |
| this.throwTemplateLiteralEarlyErrors(token); |
| } |
| const raw = token.value; |
| const cooked = token.cooked; |
| return this.finalize(node, new TemplateElement({ raw, cooked }, token.tail)); |
| } |
| parseTemplateElement(options) { |
| if (this.lookahead.type !== 10 /* Template */) { |
| this.throwUnexpectedToken(); |
| } |
| const node = this.createNode(); |
| const token = this.nextToken(); |
| if (!options.isTagged && token.notEscapeSequenceHead !== null) { |
| this.throwTemplateLiteralEarlyErrors(token); |
| } |
| const raw = token.value; |
| const cooked = token.cooked; |
| return this.finalize(node, new TemplateElement({ raw, cooked }, token.tail)); |
| } |
| parseTemplateLiteral(options) { |
| const node = this.createNode(); |
| const expressions = []; |
| const quasis = []; |
| let quasi = this.parseTemplateHead(options); |
| quasis.push(quasi); |
| while (!quasi.tail) { |
| expressions.push(this.parseExpression()); |
| quasi = this.parseTemplateElement(options); |
| quasis.push(quasi); |
| } |
| return this.finalize(node, new TemplateLiteral(quasis, expressions)); |
| } |
| // https://tc39.github.io/ecma262/#sec-grouping-operator |
| reinterpretExpressionAsPattern(expr) { |
| switch (expr.type) { |
| case "Identifier" /* Identifier */: |
| case "MemberExpression" /* MemberExpression */: |
| case "RestElement" /* RestElement */: |
| case "AssignmentPattern" /* AssignmentPattern */: |
| break; |
| case "SpreadElement" /* SpreadElement */: |
| expr.type = "RestElement" /* RestElement */; |
| this.reinterpretExpressionAsPattern(expr.argument); |
| break; |
| case "ArrayExpression" /* ArrayExpression */: |
| expr.type = "ArrayPattern" /* ArrayPattern */; |
| for (let i = 0; i < expr.elements.length; i++) { |
| if (expr.elements[i] !== null) { |
| this.reinterpretExpressionAsPattern(expr.elements[i]); |
| } |
| } |
| break; |
| case "ObjectExpression" /* ObjectExpression */: |
| expr.type = "ObjectPattern" /* ObjectPattern */; |
| for (let i = 0; i < expr.properties.length; i++) { |
| const property = expr.properties[i]; |
| this.reinterpretExpressionAsPattern(property.type === "SpreadElement" /* SpreadElement */ ? property : property.value); |
| } |
| break; |
| case "AssignmentExpression" /* AssignmentExpression */: |
| expr.type = "AssignmentPattern" /* AssignmentPattern */; |
| delete expr.operator; |
| this.reinterpretExpressionAsPattern(expr.left); |
| break; |
| default: |
| break; |
| } |
| } |
| parseGroupExpression() { |
| let expr; |
| this.expect("("); |
| if (this.match(")")) { |
| this.nextToken(); |
| if (!this.match("=>")) { |
| this.expect("=>"); |
| } |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: [], |
| async: false |
| }; |
| } else { |
| const startToken = this.lookahead; |
| const params = []; |
| if (this.match("...")) { |
| expr = this.parseRestElement(params); |
| this.expect(")"); |
| if (!this.match("=>")) { |
| this.expect("=>"); |
| } |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: [expr], |
| async: false |
| }; |
| } else { |
| let arrow = false; |
| this.context.isBindingElement = true; |
| expr = this.inheritCoverGrammar(this.parseAssignmentExpression); |
| if (this.match(",")) { |
| const expressions = []; |
| this.context.isAssignmentTarget = false; |
| expressions.push(expr); |
| while (this.lookahead.type !== 2 /* EOF */) { |
| if (!this.match(",")) { |
| break; |
| } |
| this.nextToken(); |
| if (this.match(")")) { |
| this.nextToken(); |
| for (let i = 0; i < expressions.length; i++) { |
| this.reinterpretExpressionAsPattern(expressions[i]); |
| } |
| arrow = true; |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: expressions, |
| async: false |
| }; |
| } else if (this.match("...")) { |
| if (!this.context.isBindingElement) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| expressions.push(this.parseRestElement(params)); |
| this.expect(")"); |
| if (!this.match("=>")) { |
| this.expect("=>"); |
| } |
| this.context.isBindingElement = false; |
| for (let i = 0; i < expressions.length; i++) { |
| this.reinterpretExpressionAsPattern(expressions[i]); |
| } |
| arrow = true; |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: expressions, |
| async: false |
| }; |
| } else { |
| expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); |
| } |
| if (arrow) { |
| break; |
| } |
| } |
| if (!arrow) { |
| expr = this.finalize(this.startNode(startToken), new SequenceExpression(expressions)); |
| } |
| } |
| if (!arrow) { |
| this.expect(")"); |
| if (this.match("=>")) { |
| if (expr.type === "Identifier" /* Identifier */ && expr.name === "yield") { |
| arrow = true; |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: [expr], |
| async: false |
| }; |
| } |
| if (!arrow) { |
| if (!this.context.isBindingElement) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| if (expr.type === "SequenceExpression" /* SequenceExpression */) { |
| for (let i = 0; i < expr.expressions.length; i++) { |
| this.reinterpretExpressionAsPattern(expr.expressions[i]); |
| } |
| } else { |
| this.reinterpretExpressionAsPattern(expr); |
| } |
| const parameters = expr.type === "SequenceExpression" /* SequenceExpression */ ? expr.expressions : [expr]; |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: parameters, |
| async: false |
| }; |
| } |
| } |
| this.context.isBindingElement = false; |
| } |
| } |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions |
| parseArguments() { |
| this.expect("("); |
| const args = []; |
| if (!this.match(")")) { |
| while (true) { |
| const expr = this.match("...") ? this.parseSpreadElement() : this.isolateCoverGrammar(this.parseAssignmentExpression); |
| args.push(expr); |
| if (this.match(")")) { |
| break; |
| } |
| this.expectCommaSeparator(); |
| if (this.match(")")) { |
| break; |
| } |
| } |
| } |
| this.expect(")"); |
| return args; |
| } |
| isIdentifierName(token) { |
| return token.type === 3 /* Identifier */ || token.type === 4 /* Keyword */ || token.type === 1 /* BooleanLiteral */ || token.type === 5 /* NullLiteral */; |
| } |
| parseIdentifierName(allowPrivateField = false) { |
| let isPrivateField = false; |
| let node = this.createNode(); |
| let token = this.nextToken(); |
| if (token.value === "#" && allowPrivateField) { |
| token = this.nextToken(); |
| isPrivateField = true; |
| } |
| if (!this.isIdentifierName(token)) { |
| this.throwUnexpectedToken(token); |
| } |
| return this.finalize(node, isPrivateField ? new PrivateIdentifier(token.value) : new Identifier(token.value)); |
| } |
| parseNewExpression() { |
| const node = this.createNode(); |
| const id = this.parseIdentifierName(); |
| assert(id.name === "new", "New expression must start with `new`"); |
| let expr; |
| if (this.match(".")) { |
| this.nextToken(); |
| if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === "target") { |
| const property = this.parseIdentifierName(); |
| expr = new MetaProperty(id, property); |
| } else { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| } else if (this.matchKeyword("import")) { |
| this.throwUnexpectedToken(this.lookahead); |
| } else { |
| const callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression); |
| const args = this.match("(") ? this.parseArguments() : []; |
| expr = new NewExpression(callee, args); |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| } |
| return this.finalize(node, expr); |
| } |
| parseAsyncArgument() { |
| const arg = this.parseAssignmentExpression(); |
| this.context.firstCoverInitializedNameError = null; |
| return arg; |
| } |
| parseAsyncArguments() { |
| this.expect("("); |
| const args = []; |
| if (!this.match(")")) { |
| while (true) { |
| const expr = this.match("...") ? this.parseSpreadElement() : this.isolateCoverGrammar(this.parseAsyncArgument); |
| args.push(expr); |
| if (this.match(")")) { |
| break; |
| } |
| this.expectCommaSeparator(); |
| if (this.match(")")) { |
| break; |
| } |
| } |
| } |
| this.expect(")"); |
| return args; |
| } |
| matchImportCall() { |
| let match = this.matchKeyword("import"); |
| if (match) { |
| const state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| const next = this.scanner.lex(); |
| this.scanner.restoreState(state); |
| match = next.type === 7 /* Punctuator */ && next.value === "("; |
| } |
| return match; |
| } |
| parseImportCall() { |
| const node = this.createNode(); |
| this.expectKeyword("import"); |
| this.expect("("); |
| var previousIsAssignmentTarget = this.context.isAssignmentTarget; |
| this.context.isAssignmentTarget = true; |
| const source = this.parseAssignmentExpression(); |
| let attributes = null; |
| if (this.match(",")) { |
| this.nextToken(); |
| if (!this.match(")")) |
| attributes = this.parseAssignmentExpression(); |
| } |
| this.context.isAssignmentTarget = previousIsAssignmentTarget; |
| if (!this.match(")")) { |
| if (this.match(",")) { |
| this.nextToken(); |
| } |
| this.expect(")"); |
| } else { |
| this.nextToken(); |
| } |
| return this.finalize(node, new ImportExpression(source, attributes)); |
| } |
| matchImportMeta() { |
| let match = this.matchKeyword("import"); |
| if (match) { |
| const state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| const dot = this.scanner.lex(); |
| if (dot.type === 7 /* Punctuator */ && dot.value === ".") { |
| this.scanner.scanComments(); |
| const meta = this.scanner.lex(); |
| match = meta.type === 3 /* Identifier */ && meta.value === "meta"; |
| if (match) { |
| if (meta.end - meta.start !== "meta".length) { |
| this.tolerateUnexpectedToken(meta, Messages.InvalidEscapedReservedWord); |
| } |
| } |
| } else { |
| match = false; |
| } |
| this.scanner.restoreState(state); |
| } |
| return match; |
| } |
| parseImportMeta() { |
| const node = this.createNode(); |
| const id = this.parseIdentifierName(); |
| this.expect("."); |
| const property = this.parseIdentifierName(); |
| this.context.isAssignmentTarget = false; |
| return this.finalize(node, new MetaProperty(id, property)); |
| } |
| parseLeftHandSideExpressionAllowCall() { |
| const startToken = this.lookahead; |
| const maybeAsync = this.matchContextualKeyword("async"); |
| const previousAllowIn = this.context.allowIn; |
| this.context.allowIn = true; |
| let expr; |
| const isSuper = this.matchKeyword("super"); |
| if (isSuper && this.context.inFunctionBody) { |
| expr = this.createNode(); |
| this.nextToken(); |
| expr = this.finalize(expr, new Super()); |
| if (!this.match("(") && !this.match(".") && !this.match("[")) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| } else { |
| expr = this.inheritCoverGrammar(this.matchKeyword("new") ? this.parseNewExpression : this.parsePrimaryExpression); |
| } |
| if (isSuper && this.match("(") && (!this.context.inClassConstructor || !this.context.allowSuper)) { |
| this.tolerateError(Messages.UnexpectedSuper); |
| } |
| let hasOptional = false; |
| while (true) { |
| let optional = false; |
| if (this.match("?.")) { |
| optional = true; |
| hasOptional = true; |
| this.expect("?."); |
| } |
| if (this.match("(")) { |
| const asyncArrow = maybeAsync && startToken.lineNumber === this.lookahead.lineNumber; |
| this.context.isBindingElement = false; |
| this.context.isAssignmentTarget = false; |
| const args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments(); |
| if (expr.type === "ImportExpression" /* ImportExpression */ && args.length !== 1) { |
| this.tolerateError(Messages.BadImportCallArity); |
| } |
| expr = this.finalize(this.startNode(startToken), new CallExpression(expr, args, optional)); |
| if (asyncArrow && this.match("=>")) { |
| for (let i = 0; i < args.length; ++i) { |
| this.reinterpretExpressionAsPattern(args[i]); |
| } |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: args, |
| async: true |
| }; |
| } |
| } else if (this.match("[")) { |
| this.context.isBindingElement = false; |
| this.context.isAssignmentTarget = !optional; |
| this.expect("["); |
| const property = this.isolateCoverGrammar(this.parseExpression); |
| this.expect("]"); |
| expr = this.finalize(this.startNode(startToken), new MemberExpression(true, expr, property, optional)); |
| } else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { |
| if (optional) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| if (hasOptional) { |
| this.throwError(Messages.InvalidTaggedTemplateOnOptionalChain); |
| } |
| const quasi = this.parseTemplateLiteral({ isTagged: true }); |
| expr = this.finalize(this.startNode(startToken), new TaggedTemplateExpression(expr, quasi)); |
| } else if (this.match(".") || optional) { |
| this.context.isBindingElement = false; |
| this.context.isAssignmentTarget = !optional; |
| if (!optional) { |
| this.expect("."); |
| } |
| const property = this.parseIdentifierName(true); |
| expr = this.finalize(this.startNode(startToken), new MemberExpression(false, expr, property, optional)); |
| } else { |
| break; |
| } |
| } |
| this.context.allowIn = previousAllowIn; |
| if (hasOptional) { |
| expr = this.finalize(this.startNode(startToken), new ChainExpression(expr)); |
| } |
| return expr; |
| } |
| parseSuper() { |
| const node = this.createNode(); |
| this.expectKeyword("super"); |
| if (!this.match("[") && !this.match(".")) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| return this.finalize(node, new Super()); |
| } |
| parseLeftHandSideExpression() { |
| assert(this.context.allowIn, "callee of new expression always allow in keyword."); |
| const node = this.startNode(this.lookahead); |
| let expr = this.matchKeyword("super") && this.context.inFunctionBody ? this.parseSuper() : this.inheritCoverGrammar(this.matchKeyword("new") ? this.parseNewExpression : this.parsePrimaryExpression); |
| let hasOptional = false; |
| while (true) { |
| let optional = false; |
| if (this.match("?.")) { |
| optional = true; |
| hasOptional = true; |
| this.expect("?."); |
| } |
| if (this.match("[")) { |
| this.context.isBindingElement = false; |
| this.context.isAssignmentTarget = !optional; |
| this.expect("["); |
| const property = this.isolateCoverGrammar(this.parseExpression); |
| this.expect("]"); |
| expr = this.finalize(node, new MemberExpression(true, expr, property, optional)); |
| } else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { |
| if (optional) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| if (hasOptional) { |
| this.throwError(Messages.InvalidTaggedTemplateOnOptionalChain); |
| } |
| const quasi = this.parseTemplateLiteral({ isTagged: true }); |
| expr = this.finalize(node, new TaggedTemplateExpression(expr, quasi)); |
| } else if (this.match(".") || optional) { |
| this.context.isBindingElement = false; |
| this.context.isAssignmentTarget = !optional; |
| if (!optional) { |
| this.expect("."); |
| } |
| const property = this.parseIdentifierName(); |
| expr = this.finalize(node, new MemberExpression(false, expr, property, optional)); |
| } else { |
| break; |
| } |
| } |
| if (hasOptional) { |
| expr = this.finalize(node, new ChainExpression(expr)); |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-update-expressions |
| parseUpdateExpression() { |
| let expr; |
| const startToken = this.lookahead; |
| if (this.match("++") || this.match("--")) { |
| const node = this.startNode(startToken); |
| const token = this.nextToken(); |
| expr = this.inheritCoverGrammar(this.parseUnaryExpression); |
| if (this.context.strict && expr.type === "Identifier" /* Identifier */ && this.scanner.isRestrictedWord(expr.name)) { |
| this.tolerateError(Messages.StrictLHSPrefix); |
| } |
| if (!this.context.isAssignmentTarget) { |
| this.tolerateError(Messages.InvalidLHSInAssignment); |
| } |
| const prefix = true; |
| expr = this.finalize(node, new UpdateExpression(token.value, expr, prefix)); |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| } else { |
| expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall); |
| if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) { |
| if (this.match("++") || this.match("--")) { |
| if (this.context.strict && expr.type === "Identifier" /* Identifier */ && this.scanner.isRestrictedWord(expr.name)) { |
| this.tolerateError(Messages.StrictLHSPostfix); |
| } |
| if (!this.context.isAssignmentTarget) { |
| this.tolerateError(Messages.InvalidLHSInAssignment); |
| } |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| const operator = this.nextToken().value; |
| const prefix = false; |
| expr = this.finalize(this.startNode(startToken), new UpdateExpression(operator, expr, prefix)); |
| } |
| } |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-unary-operators |
| parseAwaitExpression() { |
| const node = this.createNode(); |
| this.nextToken(); |
| const argument = this.parseUnaryExpression(); |
| return this.finalize(node, new AwaitExpression(argument)); |
| } |
| parseUnaryExpression() { |
| let expr; |
| if (this.match("+") || this.match("-") || this.match("~") || this.match("!") || this.matchKeyword("delete") || this.matchKeyword("void") || this.matchKeyword("typeof")) { |
| const node = this.startNode(this.lookahead); |
| const token = this.nextToken(); |
| expr = this.inheritCoverGrammar(this.parseUnaryExpression); |
| expr = this.finalize(node, new UnaryExpression(token.value, expr)); |
| if (this.context.strict && expr.operator === "delete" && expr.argument.type === "Identifier" /* Identifier */) { |
| this.tolerateError(Messages.StrictDelete); |
| } |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| } else if ((this.context.isModule && !this.context.inFunctionBody || this.context.isAsync) && this.matchContextualKeyword("await")) { |
| expr = this.parseAwaitExpression(); |
| } else { |
| expr = this.parseUpdateExpression(); |
| } |
| return expr; |
| } |
| parseExponentiationExpression() { |
| const startToken = this.lookahead; |
| const isLeftParenthesized = this.match("("); |
| let expr = this.inheritCoverGrammar(this.parseUnaryExpression); |
| const exponentAllowed = expr.type !== "UnaryExpression" /* UnaryExpression */ || isLeftParenthesized; |
| if (exponentAllowed && this.match("**")) { |
| this.nextToken(); |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| const left = expr; |
| const right = this.isolateCoverGrammar(this.parseExponentiationExpression); |
| expr = this.finalize(this.startNode(startToken), new BinaryExpression("**", left, right)); |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-exp-operator |
| // https://tc39.github.io/ecma262/#sec-multiplicative-operators |
| // https://tc39.github.io/ecma262/#sec-additive-operators |
| // https://tc39.github.io/ecma262/#sec-bitwise-shift-operators |
| // https://tc39.github.io/ecma262/#sec-relational-operators |
| // https://tc39.github.io/ecma262/#sec-equality-operators |
| // https://tc39.github.io/ecma262/#sec-binary-bitwise-operators |
| // https://tc39.github.io/ecma262/#sec-binary-logical-operators |
| binaryPrecedence(token) { |
| const op = token.value; |
| let precedence; |
| if (token.type === 7 /* Punctuator */) { |
| precedence = this.operatorPrecedence[op] || 0; |
| } else if (token.type === 4 /* Keyword */) { |
| precedence = op === "instanceof" || this.context.allowIn && op === "in" ? 12 : 0; |
| } else { |
| precedence = 0; |
| } |
| return precedence; |
| } |
| parseBinaryExpression() { |
| const startToken = this.lookahead; |
| let expr = this.inheritCoverGrammar(this.parseExponentiationExpression); |
| let allowAndOr = true; |
| let allowNullishCoalescing = true; |
| const updateNullishCoalescingRestrictions = (token2) => { |
| if (token2.value === "&&" || token2.value === "||") { |
| allowNullishCoalescing = false; |
| } |
| if (token2.value === "??") { |
| allowAndOr = false; |
| } |
| }; |
| const token = this.lookahead; |
| let prec = this.binaryPrecedence(token); |
| if (prec > 0) { |
| updateNullishCoalescingRestrictions(token); |
| this.nextToken(); |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| const markers = [startToken, this.lookahead]; |
| let left = expr; |
| let right = this.isolateCoverGrammar(this.parseExponentiationExpression); |
| const stack = [left, token.value, right]; |
| const precedences = [prec]; |
| while (true) { |
| prec = this.binaryPrecedence(this.lookahead); |
| if (prec <= 0) { |
| break; |
| } |
| if (!allowAndOr && (this.lookahead.value === "&&" || this.lookahead.value === "||") || !allowNullishCoalescing && this.lookahead.value === "??") { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| updateNullishCoalescingRestrictions(this.lookahead); |
| while (stack.length > 2 && prec <= precedences[precedences.length - 1]) { |
| right = stack.pop(); |
| const operator = stack.pop(); |
| precedences.pop(); |
| left = stack.pop(); |
| markers.pop(); |
| const marker = markers[markers.length - 1]; |
| const node = this.startNode(marker, marker.lineStart); |
| const logical = operator === "||" || operator === "&&" || operator === "??"; |
| stack.push(this.finalize(node, logical ? new LogicalExpression(operator, left, right) : new BinaryExpression(operator, left, right))); |
| } |
| stack.push(this.nextToken().value); |
| precedences.push(prec); |
| markers.push(this.lookahead); |
| stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression)); |
| } |
| let i = stack.length - 1; |
| expr = stack[i]; |
| let lastMarker = markers.pop(); |
| while (i > 1) { |
| const marker = markers.pop(); |
| const lastLineStart = lastMarker && lastMarker.lineStart; |
| const node = this.startNode(marker, lastLineStart); |
| const operator = stack[i - 1]; |
| const logical = operator === "||" || operator === "&&" || operator === "??"; |
| expr = this.finalize(node, logical ? new LogicalExpression(operator, stack[i - 2], expr) : new BinaryExpression(operator, stack[i - 2], expr)); |
| i -= 2; |
| lastMarker = marker; |
| } |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-conditional-operator |
| parseConditionalExpression() { |
| const startToken = this.lookahead; |
| let expr = this.inheritCoverGrammar(this.parseBinaryExpression); |
| if (this.match("?")) { |
| this.nextToken(); |
| const previousAllowIn = this.context.allowIn; |
| this.context.allowIn = true; |
| const consequent = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| this.context.allowIn = previousAllowIn; |
| this.expect(":"); |
| const alternate = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| expr = this.finalize(this.startNode(startToken), new ConditionalExpression(expr, consequent, alternate)); |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-assignment-operators |
| checkPatternParam(options, param) { |
| switch (param.type) { |
| case "Identifier" /* Identifier */: |
| this.validateParam(options, param, param.name); |
| break; |
| case "RestElement" /* RestElement */: |
| this.checkPatternParam(options, param.argument); |
| break; |
| case "AssignmentPattern" /* AssignmentPattern */: |
| this.checkPatternParam(options, param.left); |
| break; |
| case "ArrayPattern" /* ArrayPattern */: |
| for (let i = 0; i < param.elements.length; i++) { |
| if (param.elements[i] !== null) { |
| this.checkPatternParam(options, param.elements[i]); |
| } |
| } |
| break; |
| case "ObjectPattern" /* ObjectPattern */: |
| for (let i = 0; i < param.properties.length; i++) { |
| const property = param.properties[i]; |
| this.checkPatternParam(options, property.type === "RestElement" /* RestElement */ ? property : property.value); |
| } |
| break; |
| default: |
| break; |
| } |
| options.simple = options.simple && param instanceof Identifier; |
| } |
| reinterpretAsCoverFormalsList(expr) { |
| let params = [expr]; |
| const options = { |
| simple: true, |
| paramSet: {} |
| }; |
| let asyncArrow = false; |
| switch (expr.type) { |
| case "Identifier" /* Identifier */: |
| break; |
| case ArrowParameterPlaceHolder: |
| params = expr.params; |
| asyncArrow = expr.async; |
| break; |
| default: |
| return null; |
| } |
| for (let i = 0; i < params.length; ++i) { |
| const param = params[i]; |
| if (param.type === "AssignmentPattern" /* AssignmentPattern */) { |
| if (param.right.type === "YieldExpression" /* YieldExpression */) { |
| if (param.right.argument) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| param.right.type = "Identifier" /* Identifier */; |
| param.right.name = "yield"; |
| delete param.right.argument; |
| delete param.right.delegate; |
| } |
| } else if (asyncArrow && param.type === "Identifier" /* Identifier */ && param.name === "await") { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| this.checkPatternParam(options, param); |
| params[i] = param; |
| } |
| if (this.context.strict || !this.context.allowYield) { |
| for (let i = 0; i < params.length; ++i) { |
| const param = params[i]; |
| if (param.type === "YieldExpression" /* YieldExpression */) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| } |
| } |
| if (options.hasDuplicateParameterNames) { |
| const token = this.context.strict ? options.stricted : options.firstRestricted; |
| this.throwUnexpectedToken(token, Messages.DuplicateParameter); |
| } |
| return { |
| simple: options.simple, |
| params, |
| stricted: options.stricted, |
| firstRestricted: options.firstRestricted, |
| message: options.message |
| }; |
| } |
| parseAssignmentExpression() { |
| let expr; |
| if (!this.context.allowYield && this.matchKeyword("yield")) { |
| expr = this.parseYieldExpression(); |
| } else { |
| const startToken = this.lookahead; |
| let token = startToken; |
| expr = this.parseConditionalExpression(); |
| if (token.type === 3 /* Identifier */ && token.lineNumber === this.lookahead.lineNumber && token.value === "async") { |
| if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword("yield")) { |
| const arg = this.parsePrimaryExpression(); |
| this.reinterpretExpressionAsPattern(arg); |
| expr = { |
| type: ArrowParameterPlaceHolder, |
| params: [arg], |
| async: true |
| }; |
| } |
| } |
| if (expr.type === ArrowParameterPlaceHolder || this.match("=>")) { |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| const isAsync = expr.async; |
| const list = this.reinterpretAsCoverFormalsList(expr); |
| if (list) { |
| if (this.hasLineTerminator) { |
| this.tolerateUnexpectedToken(this.lookahead); |
| } |
| this.context.firstCoverInitializedNameError = null; |
| const previousStrict = this.context.strict; |
| const previousAllowStrictDirective = this.context.allowStrictDirective; |
| this.context.allowStrictDirective = list.simple; |
| const previousAllowYield = this.context.allowYield; |
| const previousIsAsync = this.context.isAsync; |
| this.context.allowYield = true; |
| this.context.isAsync = isAsync; |
| const node = this.startNode(startToken); |
| this.expect("=>"); |
| let body; |
| if (this.match("{")) { |
| const previousAllowIn = this.context.allowIn; |
| this.context.allowIn = true; |
| body = this.parseFunctionSourceElements(); |
| this.context.allowIn = previousAllowIn; |
| } else { |
| body = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| } |
| const expression = body.type !== "BlockStatement" /* BlockStatement */; |
| if (this.context.strict && list.firstRestricted) { |
| this.throwUnexpectedToken(list.firstRestricted, list.message); |
| } |
| if (this.context.strict && list.stricted) { |
| this.tolerateUnexpectedToken(list.stricted, list.message); |
| } |
| expr = this.finalize(node, new ArrowFunctionExpression(list.params, body, expression, isAsync)); |
| this.context.strict = previousStrict; |
| this.context.allowStrictDirective = previousAllowStrictDirective; |
| this.context.allowYield = previousAllowYield; |
| this.context.isAsync = previousIsAsync; |
| } |
| } else { |
| if (this.matchAssign()) { |
| if (!this.context.isAssignmentTarget) { |
| this.tolerateError(Messages.InvalidLHSInAssignment); |
| } |
| if (this.context.strict && expr.type === "Identifier" /* Identifier */) { |
| const id = expr; |
| if (this.scanner.isRestrictedWord(id.name)) { |
| this.tolerateUnexpectedToken(token, Messages.StrictLHSAssignment); |
| } |
| if (this.scanner.isStrictModeReservedWord(id.name)) { |
| this.tolerateUnexpectedToken(token, Messages.StrictReservedWord); |
| } |
| } |
| if (!this.match("=")) { |
| this.context.isAssignmentTarget = false; |
| this.context.isBindingElement = false; |
| } else { |
| this.reinterpretExpressionAsPattern(expr); |
| } |
| token = this.nextToken(); |
| const operator = token.value; |
| const right = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| expr = this.finalize(this.startNode(startToken), new AssignmentExpression(operator, expr, right)); |
| this.context.firstCoverInitializedNameError = null; |
| } |
| } |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-comma-operator |
| parseExpression() { |
| const startToken = this.lookahead; |
| let expr = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| if (this.match(",")) { |
| const expressions = []; |
| expressions.push(expr); |
| while (this.lookahead.type !== 2 /* EOF */) { |
| if (!this.match(",")) { |
| break; |
| } |
| this.nextToken(); |
| expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); |
| } |
| expr = this.finalize(this.startNode(startToken), new SequenceExpression(expressions)); |
| } |
| return expr; |
| } |
| // https://tc39.github.io/ecma262/#sec-block |
| parseStatementListItem() { |
| let statement; |
| this.context.isAssignmentTarget = true; |
| this.context.isBindingElement = true; |
| if (this.lookahead.type === 4 /* Keyword */) { |
| switch (this.lookahead.value) { |
| case "export": |
| if (!this.context.isModule) { |
| this.tolerateUnexpectedToken(this.lookahead, Messages.IllegalExportDeclaration); |
| } |
| statement = this.parseExportDeclaration(); |
| break; |
| case "import": |
| if (this.matchImportCall()) { |
| statement = this.parseExpressionStatement(); |
| } else if (this.matchImportMeta()) { |
| statement = this.parseStatement(); |
| } else { |
| if (!this.context.isModule) { |
| this.tolerateUnexpectedToken(this.lookahead, Messages.IllegalImportDeclaration); |
| } |
| statement = this.parseImportDeclaration(); |
| } |
| break; |
| case "const": |
| statement = this.parseLexicalDeclaration({ inFor: false }); |
| break; |
| case "function": |
| statement = this.parseFunctionDeclaration(); |
| break; |
| case "class": |
| statement = this.parseClassDeclaration(); |
| break; |
| case "let": |
| statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement(); |
| break; |
| default: |
| statement = this.parseStatement(); |
| break; |
| } |
| } else { |
| statement = this.parseStatement(); |
| } |
| return statement; |
| } |
| parseBlock() { |
| const node = this.createNode(); |
| this.expect("{"); |
| const block = []; |
| while (true) { |
| if (this.match("}")) { |
| break; |
| } |
| block.push(this.parseStatementListItem()); |
| } |
| this.expect("}"); |
| return this.finalize(node, new BlockStatement(block)); |
| } |
| // https://tc39.github.io/ecma262/#sec-let-and-const-declarations |
| parseLexicalBinding(kind, options) { |
| const node = this.createNode(); |
| const params = []; |
| const id = this.parsePattern(params, kind); |
| if (this.context.strict && id.type === "Identifier" /* Identifier */) { |
| if (this.scanner.isRestrictedWord(id.name)) { |
| this.tolerateError(Messages.StrictVarName); |
| } |
| } |
| let init = null; |
| if (kind === "const") { |
| if (!this.matchKeyword("in") && !this.matchContextualKeyword("of")) { |
| if (this.match("=")) { |
| this.nextToken(); |
| init = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| } else { |
| this.throwError(Messages.DeclarationMissingInitializer, "const"); |
| } |
| } |
| } else if (!options.inFor && id.type !== "Identifier" /* Identifier */ || this.match("=")) { |
| this.expect("="); |
| init = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| } |
| return this.finalize(node, new VariableDeclarator(id, init)); |
| } |
| parseBindingList(kind, options) { |
| const list = [this.parseLexicalBinding(kind, options)]; |
| while (this.match(",")) { |
| this.nextToken(); |
| list.push(this.parseLexicalBinding(kind, options)); |
| } |
| return list; |
| } |
| isLexicalDeclaration() { |
| const state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| const next = this.scanner.lex(); |
| this.scanner.restoreState(state); |
| return next.type === 3 /* Identifier */ || next.type === 7 /* Punctuator */ && next.value === "[" || next.type === 7 /* Punctuator */ && next.value === "{" || next.type === 4 /* Keyword */ && next.value === "let" || next.type === 4 /* Keyword */ && next.value === "yield"; |
| } |
| parseLexicalDeclaration(options) { |
| const node = this.createNode(); |
| const kind = this.nextToken().value; |
| assert(kind === "let" || kind === "const", "Lexical declaration must be either let or const"); |
| const declarations = this.parseBindingList(kind, options); |
| this.consumeSemicolon(); |
| return this.finalize(node, new VariableDeclaration(declarations, kind)); |
| } |
| /** |
| * This function checks to see if a property is initialized in a Class |
| * e.g. |
| * publicProp = 123; |
| * @returns {Boolean} |
| */ |
| isInitializedProperty() { |
| let state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| let next = this.scanner.lex(); |
| this.scanner.restoreState(state); |
| return this.lookahead.type === 3 && next.value === "="; |
| } |
| /** |
| * This function checks to see if a property is declared in a Class |
| * e.g. |
| * publicProp; |
| * @returns {Boolean} |
| */ |
| isDeclaredProperty() { |
| let state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| let next = this.scanner.lex(); |
| this.scanner.restoreState(state); |
| return this.lookahead.type === 3 && next.value === ";" || this.lookahead.type === 3 && next.lineNumber !== this.startMarker.line; |
| } |
| // https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns |
| parseBindingRestElement(params, kind) { |
| const node = this.createNode(); |
| this.expect("..."); |
| const arg = this.parsePattern(params, kind); |
| return this.finalize(node, new RestElement(arg)); |
| } |
| parseArrayPattern(params, kind) { |
| const node = this.createNode(); |
| this.expect("["); |
| const elements = []; |
| while (!this.match("]")) { |
| if (this.match(",")) { |
| this.nextToken(); |
| elements.push(null); |
| } else { |
| if (this.match("...")) { |
| elements.push(this.parseBindingRestElement(params, kind)); |
| break; |
| } else { |
| elements.push(this.parsePatternWithDefault(params, kind)); |
| } |
| if (!this.match("]")) { |
| this.expect(","); |
| } |
| } |
| } |
| this.expect("]"); |
| return this.finalize(node, new ArrayPattern(elements)); |
| } |
| parsePropertyPattern(params, kind) { |
| const node = this.createNode(); |
| let computed = false; |
| let shorthand = false; |
| const method = false; |
| let key; |
| let value; |
| if (this.lookahead.type === 3 /* Identifier */) { |
| const keyToken = this.lookahead; |
| key = this.parseVariableIdentifier(); |
| const init = this.finalize(node, new Identifier(keyToken.value)); |
| if (this.match("=")) { |
| params.push(keyToken); |
| shorthand = true; |
| this.nextToken(); |
| const expr = this.parseAssignmentExpression(); |
| value = this.finalize(this.startNode(keyToken), new AssignmentPattern(init, expr)); |
| } else if (!this.match(":")) { |
| params.push(keyToken); |
| shorthand = true; |
| value = init; |
| } else { |
| this.expect(":"); |
| value = this.parsePatternWithDefault(params, kind); |
| } |
| } else { |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(); |
| this.expect(":"); |
| value = this.parsePatternWithDefault(params, kind); |
| } |
| return this.finalize(node, new Property("init", key, computed, value, method, shorthand)); |
| } |
| parseRestProperty(params) { |
| const node = this.createNode(); |
| this.expect("..."); |
| const arg = this.parsePattern(params); |
| if (this.match("=")) { |
| this.throwError(Messages.DefaultRestProperty); |
| } |
| if (!this.match("}")) { |
| this.throwError(Messages.PropertyAfterRestProperty); |
| } |
| return this.finalize(node, new RestElement(arg)); |
| } |
| parseObjectPattern(params, kind) { |
| const node = this.createNode(); |
| const properties = []; |
| this.expect("{"); |
| while (!this.match("}")) { |
| properties.push(this.match("...") ? this.parseRestProperty(params) : this.parsePropertyPattern(params, kind)); |
| if (!this.match("}")) { |
| this.expect(","); |
| } |
| } |
| this.expect("}"); |
| return this.finalize(node, new ObjectPattern(properties)); |
| } |
| parsePattern(params, kind) { |
| let pattern; |
| if (this.match("[")) { |
| pattern = this.parseArrayPattern(params, kind); |
| } else if (this.match("{")) { |
| pattern = this.parseObjectPattern(params, kind); |
| } else { |
| if (this.matchKeyword("let") && (kind === "const" || kind === "let")) { |
| this.tolerateUnexpectedToken(this.lookahead, Messages.LetInLexicalBinding); |
| } |
| params.push(this.lookahead); |
| pattern = this.parseVariableIdentifier(kind); |
| } |
| return pattern; |
| } |
| parsePatternWithDefault(params, kind) { |
| const startToken = this.lookahead; |
| let pattern = this.parsePattern(params, kind); |
| if (this.match("=")) { |
| this.nextToken(); |
| const previousAllowYield = this.context.allowYield; |
| this.context.allowYield = true; |
| const right = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| this.context.allowYield = previousAllowYield; |
| pattern = this.finalize(this.startNode(startToken), new AssignmentPattern(pattern, right)); |
| } |
| return pattern; |
| } |
| // https://tc39.github.io/ecma262/#sec-variable-statement |
| parseVariableIdentifier(kind) { |
| const node = this.createNode(); |
| const token = this.nextToken(); |
| if (token.type === 4 /* Keyword */ && token.value === "yield") { |
| if (this.context.strict) { |
| this.tolerateUnexpectedToken(token, Messages.StrictReservedWord); |
| } else if (!this.context.allowYield) { |
| this.throwUnexpectedToken(token); |
| } |
| } else if (token.type !== 3 /* Identifier */) { |
| if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) { |
| this.tolerateUnexpectedToken(token, Messages.StrictReservedWord); |
| } else { |
| if (this.context.strict || token.value !== "let" || kind !== "var") { |
| this.throwUnexpectedToken(token); |
| } |
| } |
| } else if ((this.context.isModule || this.context.isAsync) && token.type === 3 /* Identifier */ && token.value === "await") { |
| this.tolerateUnexpectedToken(token); |
| } |
| return this.finalize(node, new Identifier(token.value)); |
| } |
| parseVariableDeclaration(options) { |
| const node = this.createNode(); |
| const params = []; |
| const id = this.parsePattern(params, "var"); |
| if (this.context.strict && id.type === "Identifier" /* Identifier */) { |
| if (this.scanner.isRestrictedWord(id.name)) { |
| this.tolerateError(Messages.StrictVarName); |
| } |
| } |
| let init = null; |
| if (this.match("=")) { |
| this.nextToken(); |
| init = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| } else if (id.type !== "Identifier" /* Identifier */ && !options.inFor) { |
| this.expect("="); |
| } |
| return this.finalize(node, new VariableDeclarator(id, init)); |
| } |
| parseVariableDeclarationList(options) { |
| const opt = { inFor: options.inFor }; |
| const list = []; |
| list.push(this.parseVariableDeclaration(opt)); |
| while (this.match(",")) { |
| this.nextToken(); |
| list.push(this.parseVariableDeclaration(opt)); |
| } |
| return list; |
| } |
| parseVariableStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("var"); |
| const declarations = this.parseVariableDeclarationList({ inFor: false }); |
| this.consumeSemicolon(); |
| return this.finalize(node, new VariableDeclaration(declarations, "var")); |
| } |
| // https://tc39.github.io/ecma262/#sec-empty-statement |
| parseEmptyStatement() { |
| const node = this.createNode(); |
| this.expect(";"); |
| return this.finalize(node, new EmptyStatement()); |
| } |
| // https://tc39.github.io/ecma262/#sec-expression-statement |
| parseExpressionStatement() { |
| const node = this.createNode(); |
| const expr = this.parseExpression(); |
| this.consumeSemicolon(); |
| return this.finalize(node, new ExpressionStatement(expr)); |
| } |
| // https://tc39.github.io/ecma262/#sec-if-statement |
| parseIfClause() { |
| if (this.context.strict && this.matchKeyword("function")) { |
| this.tolerateError(Messages.StrictFunction); |
| } |
| return this.parseStatement(); |
| } |
| parseIfStatement() { |
| const node = this.createNode(); |
| let consequent; |
| let alternate = null; |
| this.expectKeyword("if"); |
| this.expect("("); |
| const test = this.parseExpression(); |
| if (!this.match(")") && this.config.tolerant) { |
| this.tolerateUnexpectedToken(this.nextToken()); |
| consequent = this.finalize(this.createNode(), new EmptyStatement()); |
| } else { |
| this.expect(")"); |
| consequent = this.parseIfClause(); |
| if (this.matchKeyword("else")) { |
| this.nextToken(); |
| alternate = this.parseIfClause(); |
| } |
| } |
| return this.finalize(node, new IfStatement(test, consequent, alternate)); |
| } |
| // https://tc39.github.io/ecma262/#sec-do-while-statement |
| parseDoWhileStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("do"); |
| this.tolerateInvalidLoopStatement(); |
| const previousInIteration = this.context.inIteration; |
| this.context.inIteration = true; |
| const body = this.parseStatement(); |
| this.context.inIteration = previousInIteration; |
| this.expectKeyword("while"); |
| this.expect("("); |
| const test = this.parseExpression(); |
| if (!this.match(")") && this.config.tolerant) { |
| this.tolerateUnexpectedToken(this.nextToken()); |
| } else { |
| this.expect(")"); |
| if (this.match(";")) { |
| this.nextToken(); |
| } |
| } |
| return this.finalize(node, new DoWhileStatement(body, test)); |
| } |
| // https://tc39.github.io/ecma262/#sec-while-statement |
| parseWhileStatement() { |
| const node = this.createNode(); |
| let body; |
| this.expectKeyword("while"); |
| this.expect("("); |
| const test = this.parseExpression(); |
| if (!this.match(")") && this.config.tolerant) { |
| this.tolerateUnexpectedToken(this.nextToken()); |
| body = this.finalize(this.createNode(), new EmptyStatement()); |
| } else { |
| this.expect(")"); |
| const previousInIteration = this.context.inIteration; |
| this.context.inIteration = true; |
| body = this.parseStatement(); |
| this.context.inIteration = previousInIteration; |
| } |
| return this.finalize(node, new WhileStatement(test, body)); |
| } |
| // https://tc39.github.io/ecma262/#sec-for-statement |
| // https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements |
| parseForStatement() { |
| let init = null; |
| let test = null; |
| let update = null; |
| let forIn = true; |
| let left, right; |
| let _await = false; |
| const node = this.createNode(); |
| this.expectKeyword("for"); |
| if (this.matchContextualKeyword("await")) { |
| if (!this.context.isAsync) { |
| this.tolerateUnexpectedToken(this.lookahead); |
| } |
| _await = true; |
| this.nextToken(); |
| } |
| this.expect("("); |
| if (this.match(";")) { |
| this.nextToken(); |
| } else { |
| if (this.matchKeyword("var")) { |
| init = this.createNode(); |
| this.nextToken(); |
| const previousAllowIn = this.context.allowIn; |
| this.context.allowIn = false; |
| const declarations = this.parseVariableDeclarationList({ inFor: true }); |
| this.context.allowIn = previousAllowIn; |
| if (!_await && declarations.length === 1 && this.matchKeyword("in")) { |
| const decl = declarations[0]; |
| if (decl.init && (decl.id.type === "ArrayPattern" /* ArrayPattern */ || decl.id.type === "ObjectPattern" /* ObjectPattern */ || this.context.strict)) { |
| this.tolerateError(Messages.ForInOfLoopInitializer, "for-in"); |
| } |
| init = this.finalize(init, new VariableDeclaration(declarations, "var")); |
| this.nextToken(); |
| left = init; |
| right = this.parseExpression(); |
| init = null; |
| } else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword("of")) { |
| init = this.finalize(init, new VariableDeclaration(declarations, "var")); |
| this.nextToken(); |
| left = init; |
| right = this.parseAssignmentExpression(); |
| init = null; |
| forIn = false; |
| } else { |
| init = this.finalize(init, new VariableDeclaration(declarations, "var")); |
| this.expect(";"); |
| } |
| } else if (this.matchKeyword("const") || this.matchKeyword("let")) { |
| init = this.createNode(); |
| const kind = this.nextToken().value; |
| if (!this.context.strict && this.lookahead.value === "in") { |
| init = this.finalize(init, new Identifier(kind)); |
| this.nextToken(); |
| left = init; |
| right = this.parseExpression(); |
| init = null; |
| } else { |
| const previousAllowIn = this.context.allowIn; |
| this.context.allowIn = false; |
| const declarations = this.parseBindingList(kind, { inFor: true }); |
| this.context.allowIn = previousAllowIn; |
| if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword("in")) { |
| init = this.finalize(init, new VariableDeclaration(declarations, kind)); |
| this.nextToken(); |
| left = init; |
| right = this.parseExpression(); |
| init = null; |
| } else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword("of")) { |
| init = this.finalize(init, new VariableDeclaration(declarations, kind)); |
| this.nextToken(); |
| left = init; |
| right = this.parseAssignmentExpression(); |
| init = null; |
| forIn = false; |
| } else { |
| this.consumeSemicolon(); |
| init = this.finalize(init, new VariableDeclaration(declarations, kind)); |
| } |
| } |
| } else { |
| const initStartToken = this.lookahead; |
| const previousIsBindingElement = this.context.isBindingElement; |
| const previousIsAssignmentTarget = this.context.isAssignmentTarget; |
| const previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; |
| const previousAllowIn = this.context.allowIn; |
| this.context.allowIn = false; |
| init = this.inheritCoverGrammar(this.parseAssignmentExpression); |
| this.context.allowIn = previousAllowIn; |
| if (this.matchKeyword("in")) { |
| if (!this.context.isAssignmentTarget || init.type === "AssignmentExpression" /* AssignmentExpression */) { |
| this.tolerateError(Messages.InvalidLHSInForIn); |
| } |
| this.nextToken(); |
| this.reinterpretExpressionAsPattern(init); |
| left = init; |
| right = this.parseExpression(); |
| init = null; |
| } else if (this.matchContextualKeyword("of")) { |
| if (!this.context.isAssignmentTarget || init.type === "AssignmentExpression" /* AssignmentExpression */) { |
| this.tolerateError(Messages.InvalidLHSInForLoop); |
| } |
| this.nextToken(); |
| this.reinterpretExpressionAsPattern(init); |
| left = init; |
| right = this.parseAssignmentExpression(); |
| init = null; |
| forIn = false; |
| } else { |
| this.context.isBindingElement = previousIsBindingElement; |
| this.context.isAssignmentTarget = previousIsAssignmentTarget; |
| this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; |
| if (this.match(",")) { |
| const initSeq = [init]; |
| while (this.match(",")) { |
| this.nextToken(); |
| initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); |
| } |
| init = this.finalize(this.startNode(initStartToken), new SequenceExpression(initSeq)); |
| } |
| this.expect(";"); |
| } |
| } |
| } |
| if (typeof left === "undefined") { |
| if (!this.match(";")) { |
| test = this.isolateCoverGrammar(this.parseExpression); |
| } |
| this.expect(";"); |
| if (!this.match(")")) { |
| update = this.isolateCoverGrammar(this.parseExpression); |
| } |
| } |
| let body; |
| if (!this.match(")") && this.config.tolerant) { |
| this.tolerateUnexpectedToken(this.nextToken()); |
| body = this.finalize(this.createNode(), new EmptyStatement()); |
| } else { |
| this.expect(")"); |
| this.tolerateInvalidLoopStatement(); |
| const previousInIteration = this.context.inIteration; |
| this.context.inIteration = true; |
| body = this.isolateCoverGrammar(this.parseStatement); |
| this.context.inIteration = previousInIteration; |
| } |
| return typeof left === "undefined" ? this.finalize(node, new ForStatement(init, test, update, body)) : forIn ? this.finalize(node, new ForInStatement(left, right, body)) : this.finalize(node, new ForOfStatement(left, right, body, _await)); |
| } |
| // https://tc39.github.io/ecma262/#sec-continue-statement |
| parseContinueStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("continue"); |
| let label = null; |
| if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { |
| const id = this.parseVariableIdentifier(); |
| label = id; |
| const key = "$" + id.name; |
| if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { |
| this.throwError(Messages.UnknownLabel, id.name); |
| } |
| } |
| this.consumeSemicolon(); |
| if (label === null && !this.context.inIteration) { |
| this.throwError(Messages.IllegalContinue); |
| } |
| return this.finalize(node, new ContinueStatement(label)); |
| } |
| // https://tc39.github.io/ecma262/#sec-break-statement |
| parseBreakStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("break"); |
| let label = null; |
| if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { |
| const id = this.parseVariableIdentifier(); |
| const key = "$" + id.name; |
| if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { |
| this.throwError(Messages.UnknownLabel, id.name); |
| } |
| label = id; |
| } |
| this.consumeSemicolon(); |
| if (label === null && !this.context.inIteration && !this.context.inSwitch) { |
| this.throwError(Messages.IllegalBreak); |
| } |
| return this.finalize(node, new BreakStatement(label)); |
| } |
| // https://tc39.github.io/ecma262/#sec-return-statement |
| parseReturnStatement() { |
| if (!this.context.inFunctionBody) { |
| this.tolerateError(Messages.IllegalReturn); |
| } |
| const node = this.createNode(); |
| this.expectKeyword("return"); |
| const hasArgument = !this.match(";") && !this.match("}") && !this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */ || this.lookahead.type === 8 /* StringLiteral */ || this.lookahead.type === 10 /* Template */; |
| const argument = hasArgument ? this.parseExpression() : null; |
| this.consumeSemicolon(); |
| return this.finalize(node, new ReturnStatement(argument)); |
| } |
| // https://tc39.github.io/ecma262/#sec-with-statement |
| parseWithStatement() { |
| if (this.context.strict) { |
| this.tolerateError(Messages.StrictModeWith); |
| } |
| const node = this.createNode(); |
| let body; |
| this.expectKeyword("with"); |
| this.expect("("); |
| const object = this.parseExpression(); |
| if (!this.match(")") && this.config.tolerant) { |
| this.tolerateUnexpectedToken(this.nextToken()); |
| body = this.finalize(this.createNode(), new EmptyStatement()); |
| } else { |
| this.expect(")"); |
| body = this.parseStatement(); |
| } |
| return this.finalize(node, new WithStatement(object, body)); |
| } |
| // https://tc39.github.io/ecma262/#sec-switch-statement |
| parseSwitchCase() { |
| const node = this.createNode(); |
| let test; |
| if (this.matchKeyword("default")) { |
| this.nextToken(); |
| test = null; |
| } else { |
| this.expectKeyword("case"); |
| test = this.parseExpression(); |
| } |
| this.expect(":"); |
| const consequent = []; |
| while (true) { |
| if (this.match("}") || this.matchKeyword("default") || this.matchKeyword("case")) { |
| break; |
| } |
| consequent.push(this.parseStatementListItem()); |
| } |
| return this.finalize(node, new SwitchCase(test, consequent)); |
| } |
| parseSwitchStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("switch"); |
| this.expect("("); |
| const discriminant = this.parseExpression(); |
| this.expect(")"); |
| const previousInSwitch = this.context.inSwitch; |
| this.context.inSwitch = true; |
| const cases = []; |
| let defaultFound = false; |
| this.expect("{"); |
| while (true) { |
| if (this.match("}")) { |
| break; |
| } |
| const clause = this.parseSwitchCase(); |
| if (clause.test === null) { |
| if (defaultFound) { |
| this.throwError(Messages.MultipleDefaultsInSwitch); |
| } |
| defaultFound = true; |
| } |
| cases.push(clause); |
| } |
| this.expect("}"); |
| this.context.inSwitch = previousInSwitch; |
| return this.finalize(node, new SwitchStatement(discriminant, cases)); |
| } |
| // https://tc39.github.io/ecma262/#sec-labelled-statements |
| parseLabelledStatement() { |
| const node = this.createNode(); |
| const expr = this.parseExpression(); |
| let statement; |
| if (expr.type === "Identifier" /* Identifier */ && this.match(":")) { |
| this.nextToken(); |
| const id = expr; |
| const key = "$" + id.name; |
| if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { |
| this.throwError(Messages.Redeclaration, "Label", id.name); |
| } |
| this.context.labelSet[key] = true; |
| let body; |
| if (this.matchKeyword("class")) { |
| this.tolerateUnexpectedToken(this.lookahead); |
| body = this.parseClassDeclaration(); |
| } else if (this.matchKeyword("function")) { |
| const token = this.lookahead; |
| const declaration = this.parseFunctionDeclaration(); |
| if (this.context.strict) { |
| this.tolerateUnexpectedToken(token, Messages.StrictFunction); |
| } else if (declaration.generator) { |
| this.tolerateUnexpectedToken(token, Messages.GeneratorInLegacyContext); |
| } |
| body = declaration; |
| } else { |
| body = this.parseStatement(); |
| } |
| delete this.context.labelSet[key]; |
| statement = new LabeledStatement(id, body); |
| } else { |
| this.consumeSemicolon(); |
| statement = new ExpressionStatement(expr); |
| } |
| return this.finalize(node, statement); |
| } |
| // https://tc39.github.io/ecma262/#sec-throw-statement |
| parseThrowStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("throw"); |
| if (this.hasLineTerminator) { |
| this.throwError(Messages.NewlineAfterThrow); |
| } |
| const argument = this.parseExpression(); |
| this.consumeSemicolon(); |
| return this.finalize(node, new ThrowStatement(argument)); |
| } |
| // https://tc39.github.io/ecma262/#sec-try-statement |
| parseCatchClause() { |
| const node = this.createNode(); |
| this.expectKeyword("catch"); |
| let param = null; |
| if (this.match("(")) { |
| this.expect("("); |
| if (this.match(")")) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| const params = []; |
| param = this.parsePattern(params); |
| const paramMap = {}; |
| for (let i = 0; i < params.length; i++) { |
| const key = "$" + params[i].value; |
| if (Object.prototype.hasOwnProperty.call(paramMap, key)) { |
| this.tolerateError(Messages.DuplicateBinding, params[i].value); |
| } |
| paramMap[key] = true; |
| } |
| if (this.context.strict && param.type === "Identifier" /* Identifier */) { |
| if (this.scanner.isRestrictedWord(param.name)) { |
| this.tolerateError(Messages.StrictCatchVariable); |
| } |
| } |
| this.expect(")"); |
| } |
| const body = this.parseBlock(); |
| return this.finalize(node, new CatchClause(param, body)); |
| } |
| parseFinallyClause() { |
| this.expectKeyword("finally"); |
| return this.parseBlock(); |
| } |
| parseTryStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("try"); |
| const block = this.parseBlock(); |
| const handler = this.matchKeyword("catch") ? this.parseCatchClause() : null; |
| const finalizer = this.matchKeyword("finally") ? this.parseFinallyClause() : null; |
| if (!handler && !finalizer) { |
| this.throwError(Messages.NoCatchOrFinally); |
| } |
| return this.finalize(node, new TryStatement(block, handler, finalizer)); |
| } |
| // https://tc39.github.io/ecma262/#sec-debugger-statement |
| parseDebuggerStatement() { |
| const node = this.createNode(); |
| this.expectKeyword("debugger"); |
| this.consumeSemicolon(); |
| return this.finalize(node, new DebuggerStatement()); |
| } |
| // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations |
| parseStatement() { |
| let statement; |
| switch (this.lookahead.type) { |
| case 1 /* BooleanLiteral */: |
| case 5 /* NullLiteral */: |
| case 6 /* NumericLiteral */: |
| case 8 /* StringLiteral */: |
| case 10 /* Template */: |
| case 9 /* RegularExpression */: |
| statement = this.parseExpressionStatement(); |
| break; |
| case 7 /* Punctuator */: |
| const value = this.lookahead.value; |
| if (value === "{") { |
| statement = this.parseBlock(); |
| } else if (value === "(") { |
| statement = this.parseExpressionStatement(); |
| } else if (value === ";") { |
| statement = this.parseEmptyStatement(); |
| } else { |
| statement = this.parseExpressionStatement(); |
| } |
| break; |
| case 3 /* Identifier */: |
| statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement(); |
| break; |
| case 4 /* Keyword */: |
| switch (this.lookahead.value) { |
| case "break": |
| statement = this.parseBreakStatement(); |
| break; |
| case "continue": |
| statement = this.parseContinueStatement(); |
| break; |
| case "debugger": |
| statement = this.parseDebuggerStatement(); |
| break; |
| case "do": |
| statement = this.parseDoWhileStatement(); |
| break; |
| case "for": |
| statement = this.parseForStatement(); |
| break; |
| case "function": |
| statement = this.parseFunctionDeclaration(); |
| break; |
| case "if": |
| statement = this.parseIfStatement(); |
| break; |
| case "return": |
| statement = this.parseReturnStatement(); |
| break; |
| case "switch": |
| statement = this.parseSwitchStatement(); |
| break; |
| case "throw": |
| statement = this.parseThrowStatement(); |
| break; |
| case "try": |
| statement = this.parseTryStatement(); |
| break; |
| case "var": |
| statement = this.parseVariableStatement(); |
| break; |
| case "while": |
| statement = this.parseWhileStatement(); |
| break; |
| case "with": |
| statement = this.parseWithStatement(); |
| break; |
| default: |
| statement = this.parseExpressionStatement(); |
| break; |
| } |
| break; |
| default: |
| statement = this.throwUnexpectedToken(this.lookahead); |
| } |
| return statement; |
| } |
| // https://tc39.github.io/ecma262/#sec-function-definitions |
| parseFunctionSourceElements() { |
| const node = this.createNode(); |
| this.expect("{"); |
| const body = this.parseDirectivePrologues(); |
| const previousLabelSet = this.context.labelSet; |
| const previousInIteration = this.context.inIteration; |
| const previousInSwitch = this.context.inSwitch; |
| const previousInFunctionBody = this.context.inFunctionBody; |
| this.context.labelSet = {}; |
| this.context.inIteration = false; |
| this.context.inSwitch = false; |
| this.context.inFunctionBody = true; |
| while (this.lookahead.type !== 2 /* EOF */) { |
| if (this.match("}")) { |
| break; |
| } |
| body.push(this.parseStatementListItem()); |
| } |
| this.expect("}"); |
| this.context.labelSet = previousLabelSet; |
| this.context.inIteration = previousInIteration; |
| this.context.inSwitch = previousInSwitch; |
| this.context.inFunctionBody = previousInFunctionBody; |
| return this.finalize(node, new BlockStatement(body)); |
| } |
| validateParam(options, param, name) { |
| const key = "$" + name; |
| if (this.context.strict) { |
| if (this.scanner.isRestrictedWord(name)) { |
| options.stricted = param; |
| options.message = Messages.StrictParamName; |
| } |
| if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { |
| options.stricted = param; |
| options.hasDuplicateParameterNames = true; |
| } |
| } else if (!options.firstRestricted) { |
| if (this.scanner.isRestrictedWord(name)) { |
| options.firstRestricted = param; |
| options.message = Messages.StrictParamName; |
| } else if (this.scanner.isStrictModeReservedWord(name)) { |
| options.firstRestricted = param; |
| options.message = Messages.StrictReservedWord; |
| } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { |
| options.stricted = param; |
| options.hasDuplicateParameterNames = true; |
| } |
| } |
| if (typeof Object.defineProperty === "function") { |
| Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true }); |
| } else { |
| options.paramSet[key] = true; |
| } |
| } |
| parseRestElement(params) { |
| const node = this.createNode(); |
| this.expect("..."); |
| const arg = this.parsePattern(params); |
| if (this.match("=")) { |
| this.throwError(Messages.DefaultRestParameter); |
| } |
| if (!this.match(")")) { |
| this.throwError(Messages.ParameterAfterRestParameter); |
| } |
| return this.finalize(node, new RestElement(arg)); |
| } |
| parseFormalParameter(options) { |
| const params = []; |
| const param = this.match("...") ? this.parseRestElement(params) : this.parsePatternWithDefault(params); |
| for (let i = 0; i < params.length; i++) { |
| this.validateParam(options, params[i], params[i].value); |
| } |
| options.simple = options.simple && param instanceof Identifier; |
| options.params.push(param); |
| } |
| parseFormalParameters(firstRestricted) { |
| const options = { |
| simple: true, |
| hasDuplicateParameterNames: false, |
| params: [], |
| firstRestricted |
| }; |
| this.expect("("); |
| if (!this.match(")")) { |
| options.paramSet = {}; |
| while (this.lookahead.type !== 2 /* EOF */) { |
| this.parseFormalParameter(options); |
| if (this.match(")")) { |
| break; |
| } |
| this.expect(","); |
| if (this.match(")")) { |
| break; |
| } |
| } |
| } |
| this.expect(")"); |
| if (options.hasDuplicateParameterNames) { |
| if (this.context.strict || this.context.isAsync || !options.simple) { |
| this.throwError(Messages.DuplicateParameter); |
| } |
| } |
| return { |
| simple: options.simple, |
| params: options.params, |
| stricted: options.stricted, |
| firstRestricted: options.firstRestricted, |
| message: options.message |
| }; |
| } |
| matchAsyncFunction() { |
| let match = this.matchContextualKeyword("async"); |
| if (match) { |
| const state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| const next = this.scanner.lex(); |
| this.scanner.restoreState(state); |
| match = state.lineNumber === next.lineNumber && next.type === 4 /* Keyword */ && next.value === "function"; |
| } |
| return match; |
| } |
| parseFunctionDeclaration(identifierIsOptional) { |
| const node = this.createNode(); |
| const isAsync = this.matchContextualKeyword("async"); |
| if (isAsync) { |
| if (this.context.inIteration) { |
| this.tolerateError(Messages.AsyncFunctionInSingleStatementContext); |
| } |
| this.nextToken(); |
| } |
| this.expectKeyword("function"); |
| const isGenerator = this.match("*"); |
| if (isGenerator) { |
| this.nextToken(); |
| } |
| let message; |
| let id = null; |
| let firstRestricted = null; |
| if (!identifierIsOptional || !this.match("(")) { |
| const token = this.lookahead; |
| id = this.parseVariableIdentifier(); |
| if (this.context.strict) { |
| if (this.scanner.isRestrictedWord(token.value)) { |
| this.tolerateUnexpectedToken(token, Messages.StrictFunctionName); |
| } |
| } else { |
| if (this.scanner.isRestrictedWord(token.value)) { |
| firstRestricted = token; |
| message = Messages.StrictFunctionName; |
| } else if (this.scanner.isStrictModeReservedWord(token.value)) { |
| firstRestricted = token; |
| message = Messages.StrictReservedWord; |
| } |
| } |
| } |
| const previousIsAsync = this.context.isAsync; |
| const previousAllowYield = this.context.allowYield; |
| this.context.isAsync = isAsync; |
| this.context.allowYield = !isGenerator; |
| const formalParameters = this.parseFormalParameters(firstRestricted); |
| const params = formalParameters.params; |
| const stricted = formalParameters.stricted; |
| firstRestricted = formalParameters.firstRestricted; |
| if (formalParameters.message) { |
| message = formalParameters.message; |
| } |
| const previousStrict = this.context.strict; |
| const previousAllowStrictDirective = this.context.allowStrictDirective; |
| this.context.allowStrictDirective = formalParameters.simple; |
| const body = this.parseFunctionSourceElements(); |
| if (this.context.strict && firstRestricted) { |
| this.throwUnexpectedToken(firstRestricted, message); |
| } |
| if (this.context.strict && stricted) { |
| this.tolerateUnexpectedToken(stricted, message); |
| } |
| this.context.strict = previousStrict; |
| this.context.allowStrictDirective = previousAllowStrictDirective; |
| this.context.isAsync = previousIsAsync; |
| this.context.allowYield = previousAllowYield; |
| return isAsync ? this.finalize(node, new AsyncFunctionDeclaration(id, params, body, isGenerator)) : this.finalize(node, new FunctionDeclaration(id, params, body, isGenerator)); |
| } |
| parseFunctionExpression() { |
| const node = this.createNode(); |
| const isAsync = this.matchContextualKeyword("async"); |
| if (isAsync) { |
| this.nextToken(); |
| } |
| this.expectKeyword("function"); |
| const isGenerator = this.match("*"); |
| if (isGenerator) { |
| this.nextToken(); |
| } |
| let message; |
| let id = null; |
| let firstRestricted; |
| const previousIsAsync = this.context.isAsync; |
| const previousAllowYield = this.context.allowYield; |
| this.context.isAsync = isAsync; |
| this.context.allowYield = !isGenerator; |
| if (!this.match("(")) { |
| const token = this.lookahead; |
| id = !this.context.strict && !isGenerator && this.matchKeyword("yield") ? this.parseIdentifierName() : this.parseVariableIdentifier(); |
| if (this.context.strict) { |
| if (this.scanner.isRestrictedWord(token.value)) { |
| this.tolerateUnexpectedToken(token, Messages.StrictFunctionName); |
| } |
| } else { |
| if (this.scanner.isRestrictedWord(token.value)) { |
| firstRestricted = token; |
| message = Messages.StrictFunctionName; |
| } else if (this.scanner.isStrictModeReservedWord(token.value)) { |
| firstRestricted = token; |
| message = Messages.StrictReservedWord; |
| } |
| } |
| } |
| const formalParameters = this.parseFormalParameters(firstRestricted); |
| const params = formalParameters.params; |
| const stricted = formalParameters.stricted; |
| firstRestricted = formalParameters.firstRestricted; |
| if (formalParameters.message) { |
| message = formalParameters.message; |
| } |
| const previousStrict = this.context.strict; |
| const previousAllowStrictDirective = this.context.allowStrictDirective; |
| this.context.allowStrictDirective = formalParameters.simple; |
| const body = this.parseFunctionSourceElements(); |
| if (this.context.strict && firstRestricted) { |
| this.throwUnexpectedToken(firstRestricted, message); |
| } |
| if (this.context.strict && stricted) { |
| this.tolerateUnexpectedToken(stricted, message); |
| } |
| this.context.strict = previousStrict; |
| this.context.allowStrictDirective = previousAllowStrictDirective; |
| this.context.isAsync = previousIsAsync; |
| this.context.allowYield = previousAllowYield; |
| return this.finalize(node, new FunctionExpression(id, params, body, isGenerator, isAsync)); |
| } |
| // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive |
| parseDirective() { |
| const token = this.lookahead; |
| const node = this.createNode(); |
| const expr = this.parseExpression(); |
| const directive = expr.type === "Literal" /* Literal */ ? this.getTokenRaw(token).slice(1, -1) : null; |
| this.consumeSemicolon(); |
| return this.finalize(node, directive ? new Directive(expr, directive) : new ExpressionStatement(expr)); |
| } |
| parseDirectivePrologues() { |
| let firstRestricted = null; |
| const body = []; |
| while (true) { |
| const token = this.lookahead; |
| if (token.type !== 8 /* StringLiteral */) { |
| break; |
| } |
| const statement = this.parseDirective(); |
| body.push(statement); |
| const directive = statement.directive; |
| if (typeof directive !== "string") { |
| break; |
| } |
| if (directive === "use strict") { |
| this.context.strict = true; |
| if (firstRestricted) { |
| this.tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); |
| } |
| if (!this.context.allowStrictDirective) { |
| this.tolerateUnexpectedToken(token, Messages.IllegalLanguageModeDirective); |
| } |
| } else { |
| if (!firstRestricted && token.octal) { |
| firstRestricted = token; |
| } |
| } |
| } |
| return body; |
| } |
| // https://tc39.github.io/ecma262/#sec-method-definitions |
| qualifiedPropertyName(token) { |
| switch (token.type) { |
| case 3 /* Identifier */: |
| case 8 /* StringLiteral */: |
| case 1 /* BooleanLiteral */: |
| case 5 /* NullLiteral */: |
| case 6 /* NumericLiteral */: |
| case 4 /* Keyword */: |
| return true; |
| case 7 /* Punctuator */: |
| return token.value === "[" || token.value === "#"; |
| default: |
| break; |
| } |
| return false; |
| } |
| parseGetterMethod() { |
| const node = this.createNode(); |
| const isGenerator = false; |
| const previousAllowYield = this.context.allowYield; |
| this.context.allowYield = !isGenerator; |
| const formalParameters = this.parseFormalParameters(); |
| if (formalParameters.params.length > 0) { |
| this.tolerateError(Messages.BadGetterArity); |
| } |
| const method = this.parsePropertyMethod(formalParameters); |
| this.context.allowYield = previousAllowYield; |
| return this.finalize(node, new FunctionExpression(null, formalParameters.params, method, isGenerator, false)); |
| } |
| parseSetterMethod() { |
| const node = this.createNode(); |
| const isGenerator = false; |
| const previousAllowYield = this.context.allowYield; |
| this.context.allowYield = !isGenerator; |
| const formalParameters = this.parseFormalParameters(); |
| if (formalParameters.params.length !== 1) { |
| this.tolerateError(Messages.BadSetterArity); |
| } else if (formalParameters.params[0] instanceof RestElement) { |
| this.tolerateError(Messages.BadSetterRestParameter); |
| } |
| const method = this.parsePropertyMethod(formalParameters); |
| this.context.allowYield = previousAllowYield; |
| return this.finalize(node, new FunctionExpression(null, formalParameters.params, method, isGenerator, false)); |
| } |
| parseGeneratorMethod(isAsync) { |
| const node = this.createNode(); |
| const isGenerator = true; |
| const previousAllowYield = this.context.allowYield; |
| this.context.allowYield = true; |
| const params = this.parseFormalParameters(); |
| this.context.allowYield = false; |
| const method = this.parsePropertyMethod(params); |
| this.context.allowYield = previousAllowYield; |
| return this.finalize(node, new FunctionExpression(null, params.params, method, isGenerator, isAsync)); |
| } |
| // https://tc39.github.io/ecma262/#sec-generator-function-definitions |
| isStartOfExpression() { |
| let start = true; |
| const value = this.lookahead.value; |
| switch (this.lookahead.type) { |
| case 7 /* Punctuator */: |
| start = value === "[" || value === "(" || value === "{" || value === "+" || value === "-" || value === "!" || value === "~" || value === "++" || value === "--" || value === "/" || value === "/="; |
| break; |
| case 4 /* Keyword */: |
| start = value === "class" || value === "delete" || value === "function" || value === "let" || value === "new" || value === "super" || value === "this" || value === "typeof" || value === "void" || value === "yield"; |
| break; |
| default: |
| break; |
| } |
| return start; |
| } |
| parseYieldExpression() { |
| const node = this.createNode(); |
| this.expectKeyword("yield"); |
| let argument = null; |
| let delegate = false; |
| if (!this.hasLineTerminator) { |
| const previousAllowYield = this.context.allowYield; |
| this.context.allowYield = false; |
| delegate = this.match("*"); |
| if (delegate) { |
| this.nextToken(); |
| argument = this.parseAssignmentExpression(); |
| } else if (this.isStartOfExpression()) { |
| argument = this.parseAssignmentExpression(); |
| } |
| this.context.allowYield = previousAllowYield; |
| } |
| return this.finalize(node, new YieldExpression(argument, delegate)); |
| } |
| // https://tc39.github.io/ecma262/#sec-class-definitions |
| parseStaticBlock() { |
| const node = this.createNode(); |
| this.expect("{"); |
| const block = []; |
| while (true) { |
| if (this.match("}")) { |
| break; |
| } |
| block.push(this.parseStatementListItem()); |
| } |
| this.expect("}"); |
| return this.finalize(node, new StaticBlock(block)); |
| } |
| parseDecorator() { |
| const node = this.createNode(); |
| this.expect("@"); |
| const previousStrict = this.context.strict; |
| const previousAllowYield = this.context.allowYield; |
| const previousIsAsync = this.context.isAsync; |
| this.context.strict = false; |
| this.context.allowYield = true; |
| this.context.isAsync = false; |
| const expression = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); |
| this.context.strict = previousStrict; |
| this.context.allowYield = previousAllowYield; |
| this.context.isAsync = previousIsAsync; |
| if (this.match(";")) { |
| this.throwError(Messages.NoSemicolonAfterDecorator); |
| } |
| return this.finalize(node, new Decorator(expression)); |
| } |
| parseDecorators() { |
| let decorators = null; |
| while (this.match("@")) { |
| if (decorators == null) |
| decorators = []; |
| decorators.push(this.parseDecorator()); |
| } |
| return decorators; |
| } |
| parseClassElement(hasConstructor) { |
| let token = this.lookahead; |
| const node = this.createNode(); |
| const previousInConstructor = this.context.inConstructor; |
| let kind = ""; |
| let key = null; |
| let value = null; |
| let computed = false; |
| let method = false; |
| let isStatic = false; |
| let isAsync = false; |
| let isGenerator = false; |
| let isPrivate = false; |
| const decorators = this.parseDecorators(); |
| if (decorators) { |
| token = this.lookahead; |
| } |
| if (this.match("*")) { |
| this.nextToken(); |
| } else { |
| computed = this.match("["); |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| token = this.lookahead; |
| } |
| key = this.parseObjectPropertyKey(isPrivate); |
| const id = key; |
| this.context.inConstructor = token.type === 3 /* Identifier */ && token.value === "constructor"; |
| if (id.name === "static" && (this.qualifiedPropertyName(this.lookahead) || this.match("*"))) { |
| token = this.lookahead; |
| isStatic = true; |
| computed = this.match("["); |
| if (this.match("*")) { |
| this.nextToken(); |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| token = this.lookahead; |
| } |
| } else { |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| token = this.lookahead; |
| } |
| key = this.parseObjectPropertyKey(isPrivate); |
| } |
| } |
| if (id.name === "static" && this.match("{")) { |
| return this.parseStaticBlock(); |
| } |
| if (token.type === 3 /* Identifier */ && !this.hasLineTerminator && token.value === "async") { |
| const punctuator = this.lookahead.value; |
| if (punctuator !== ":" && punctuator !== "(") { |
| isAsync = true; |
| isGenerator = this.match("*"); |
| if (isGenerator) { |
| this.nextToken(); |
| } |
| token = this.lookahead; |
| computed = this.match("["); |
| if (this.match("*")) { |
| this.nextToken(); |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| } |
| } else { |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| token = this.lookahead; |
| } |
| key = this.parseObjectPropertyKey(isPrivate); |
| } |
| if (token.type === 3 /* Identifier */ && token.value === "constructor" && !isStatic) { |
| this.tolerateUnexpectedToken(token, Messages.ConstructorIsAsync); |
| } |
| } |
| } |
| } |
| if (token.type === 3 /* Identifier */ && token.value === "constructor" && isPrivate) { |
| this.tolerateUnexpectedToken(token, Messages.ConstructorIsPrivate); |
| } |
| const lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); |
| if (token.type === 3 /* Identifier */ || token.type === 8 /* StringLiteral */) { |
| if (token.value === "get" && lookaheadPropertyKey) { |
| kind = "get"; |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| token = this.lookahead; |
| } |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(isPrivate); |
| this.context.allowYield = false; |
| value = this.parseGetterMethod(); |
| } else if (token.value === "set" && lookaheadPropertyKey) { |
| kind = "set"; |
| if (this.match("#")) { |
| isPrivate = true; |
| this.nextToken(); |
| token = this.lookahead; |
| } |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(isPrivate); |
| value = this.parseSetterMethod(); |
| } else if (!this.match("(")) { |
| kind = "property"; |
| computed = false; |
| if (this.match("=")) { |
| this.nextToken(); |
| value = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| } |
| } |
| } else if (token.type === 7 /* Punctuator */ && token.value === "*" && lookaheadPropertyKey) { |
| kind = "init"; |
| computed = this.match("["); |
| key = this.parseObjectPropertyKey(isPrivate); |
| value = this.parseGeneratorMethod(isAsync); |
| method = true; |
| } else if (token.type === 7 /* Punctuator */ && token.value === "[" && !this.match("(")) { |
| kind = "property"; |
| computed = true; |
| if (this.match("=")) { |
| this.nextToken(); |
| value = this.isolateCoverGrammar(this.parseAssignmentExpression); |
| } |
| } |
| if (!kind && key && this.match("(")) { |
| const previousInClassConstructor = this.context.inClassConstructor; |
| this.context.inClassConstructor = token.value === "constructor"; |
| kind = "init"; |
| value = isAsync ? this.parsePropertyMethodAsyncFunction(isGenerator) : this.parsePropertyMethodFunction(isGenerator); |
| this.context.inClassConstructor = previousInClassConstructor; |
| method = true; |
| } |
| if (!kind) { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| if (kind === "init") { |
| kind = "method"; |
| } |
| if (!computed) { |
| if (isStatic && this.isPropertyKey(key, "prototype")) { |
| this.throwUnexpectedToken(token, Messages.StaticPrototype); |
| } |
| if (!isStatic && this.isPropertyKey(key, "constructor")) { |
| if (kind !== "method" || !method || value && value.generator) { |
| this.throwUnexpectedToken(token, Messages.ConstructorSpecialMethod); |
| } |
| if (hasConstructor.value) { |
| this.throwUnexpectedToken(token, Messages.DuplicateConstructor); |
| } else { |
| hasConstructor.value = true; |
| } |
| kind = "constructor"; |
| } |
| } |
| this.context.inConstructor = previousInConstructor; |
| if (kind === "property") { |
| this.consumeSemicolon(); |
| return this.finalize(node, new PropertyDefinition(key, computed, value, isStatic, decorators)); |
| } else |
| return this.finalize(node, new MethodDefinition(key, computed, value, kind, isStatic, decorators)); |
| } |
| parseClassElementList() { |
| const body = []; |
| const hasConstructor = { value: false }; |
| this.expect("{"); |
| while (!this.match("}")) { |
| if (this.match(";")) { |
| this.nextToken(); |
| } else { |
| body.push(this.parseClassElement(hasConstructor)); |
| } |
| } |
| this.expect("}"); |
| return body; |
| } |
| parseClassBody() { |
| const node = this.createNode(); |
| const elementList = this.parseClassElementList(); |
| return this.finalize(node, new ClassBody(elementList)); |
| } |
| parseClassDeclaration(identifierIsOptional) { |
| const node = this.createNode(); |
| const previousStrict = this.context.strict; |
| const previousAllowSuper = this.context.allowSuper; |
| this.context.strict = true; |
| this.expectKeyword("class"); |
| const id = identifierIsOptional && this.lookahead.type !== 3 /* Identifier */ ? null : this.parseVariableIdentifier(); |
| let superClass = null; |
| if (this.matchKeyword("extends")) { |
| this.nextToken(); |
| superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); |
| this.context.allowSuper = true; |
| } |
| const classBody = this.parseClassBody(); |
| this.context.allowSuper = previousAllowSuper; |
| this.context.strict = previousStrict; |
| return this.finalize(node, new ClassDeclaration(id, superClass, classBody, this.context.decorators)); |
| } |
| parseClassExpression() { |
| const node = this.createNode(); |
| const previousStrict = this.context.strict; |
| this.context.strict = true; |
| this.expectKeyword("class"); |
| const id = this.lookahead.type === 3 /* Identifier */ ? this.parseVariableIdentifier() : null; |
| let superClass = null; |
| if (this.matchKeyword("extends")) { |
| this.nextToken(); |
| superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); |
| this.context.allowSuper = true; |
| } |
| const classBody = this.parseClassBody(); |
| this.context.strict = previousStrict; |
| return this.finalize(node, new ClassExpression(id, superClass, classBody, this.context.decorators)); |
| } |
| // https://tc39.github.io/ecma262/#sec-scripts |
| // https://tc39.github.io/ecma262/#sec-modules |
| parseModule() { |
| this.context.strict = true; |
| this.context.isModule = true; |
| this.scanner.isModule = true; |
| const node = this.createNode(); |
| const body = this.parseDirectivePrologues(); |
| while (this.lookahead.type !== 2 /* EOF */) { |
| body.push(this.parseStatementListItem()); |
| } |
| return this.finalize(node, new Module(body)); |
| } |
| parseScript() { |
| const node = this.createNode(); |
| const body = this.parseDirectivePrologues(); |
| while (this.lookahead.type !== 2 /* EOF */) { |
| body.push(this.parseStatementListItem()); |
| } |
| return this.finalize(node, new Script(body)); |
| } |
| // https://tc39.github.io/ecma262/#sec-imports |
| parseImportAttributes() { |
| if (this.lookahead.value === "assert") { |
| this.nextToken(); |
| this.expect("{"); |
| const attributes = []; |
| while (!this.match("}")) { |
| attributes.push(this.parseImportAttribute()); |
| if (!this.match("}")) { |
| this.expectCommaSeparator(); |
| } |
| } |
| this.expect("}"); |
| return attributes; |
| } |
| return null; |
| } |
| parseImportAttribute() { |
| const node = this.createNode(); |
| if (this.lookahead.type !== 3 /* Identifier */) { |
| this.throwUnexpectedToken(this.nextToken()); |
| } |
| const key = this.parseIdentifierName(); |
| if (!this.match(":")) { |
| this.throwUnexpectedToken(this.nextToken()); |
| } |
| this.nextToken(); |
| const literalToken = this.nextToken(); |
| const raw = this.getTokenRaw(literalToken); |
| const value = this.finalize(node, new Literal(literalToken.value, raw)); |
| return this.finalize(node, new ImportAttribute(key, value)); |
| } |
| parseModuleSpecifier() { |
| const node = this.createNode(); |
| if (this.lookahead.type !== 8 /* StringLiteral */) { |
| this.throwError(Messages.InvalidModuleSpecifier); |
| } |
| const token = this.nextToken(); |
| const raw = this.getTokenRaw(token); |
| if (!Character.isStringWellFormedUnicode(token.value)) { |
| this.throwError(Messages.InvalidModuleSpecifier); |
| } |
| return this.finalize(node, new Literal(token.value, raw)); |
| } |
| // import {<foo as bar>} ...; |
| parseImportSpecifier() { |
| const node = this.createNode(); |
| let imported; |
| let local; |
| if (this.lookahead.type === 3 /* Identifier */) { |
| imported = this.parseVariableIdentifier(); |
| local = imported; |
| if (this.matchContextualKeyword("as")) { |
| this.nextToken(); |
| local = this.parseVariableIdentifier(); |
| } |
| } else { |
| imported = this.lookahead.type == 8 /* StringLiteral */ ? this.parseModuleSpecifier() : this.parseIdentifierName(); |
| local = imported; |
| if (this.matchContextualKeyword("as")) { |
| this.nextToken(); |
| local = this.parseVariableIdentifier(); |
| } else { |
| this.throwUnexpectedToken(this.nextToken()); |
| } |
| } |
| return this.finalize(node, new ImportSpecifier(local, imported)); |
| } |
| // {foo, bar as bas} |
| parseNamedImports() { |
| this.expect("{"); |
| const specifiers = []; |
| while (!this.match("}")) { |
| specifiers.push(this.parseImportSpecifier()); |
| if (!this.match("}")) { |
| this.expect(","); |
| } |
| } |
| this.expect("}"); |
| return specifiers; |
| } |
| // import <foo> ...; |
| parseImportDefaultSpecifier() { |
| const node = this.createNode(); |
| const local = this.parseIdentifierName(); |
| return this.finalize(node, new ImportDefaultSpecifier(local)); |
| } |
| // import <* as foo> ...; |
| parseImportNamespaceSpecifier() { |
| const node = this.createNode(); |
| this.expect("*"); |
| if (!this.matchContextualKeyword("as")) { |
| this.throwError(Messages.NoAsAfterImportNamespace); |
| } |
| if (this.lookahead.escaped) { |
| this.throwError(Messages.NoAsAndFromEscapeSequences); |
| } |
| this.nextToken(); |
| const local = this.parseIdentifierName(); |
| return this.finalize(node, new ImportNamespaceSpecifier(local)); |
| } |
| parseImportDeclaration() { |
| if (this.context.inFunctionBody) { |
| this.throwError(Messages.IllegalImportDeclaration); |
| } |
| const node = this.createNode(); |
| this.expectKeyword("import"); |
| let src; |
| let specifiers = []; |
| if (this.lookahead.type === 8 /* StringLiteral */) { |
| src = this.parseModuleSpecifier(); |
| } else { |
| if (this.match("{")) { |
| specifiers = specifiers.concat(this.parseNamedImports()); |
| } else if (this.match("*")) { |
| specifiers.push(this.parseImportNamespaceSpecifier()); |
| } else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword("default")) { |
| specifiers.push(this.parseImportDefaultSpecifier()); |
| if (this.match(",")) { |
| this.nextToken(); |
| if (this.match("*")) { |
| specifiers.push(this.parseImportNamespaceSpecifier()); |
| } else if (this.match("{")) { |
| specifiers = specifiers.concat(this.parseNamedImports()); |
| } else { |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| } |
| } else { |
| this.throwUnexpectedToken(this.nextToken()); |
| } |
| if (!this.matchContextualKeyword("from")) { |
| const message = this.lookahead.value ? Messages.UnexpectedToken : Messages.MissingFromClause; |
| this.throwError(message, this.lookahead.value); |
| } |
| this.nextToken(); |
| src = this.parseModuleSpecifier(); |
| } |
| const attributes = this.parseImportAttributes(); |
| this.consumeSemicolon(); |
| return this.finalize(node, new ImportDeclaration(specifiers, src, attributes)); |
| } |
| // https://tc39.github.io/ecma262/#sec-exports |
| parseExportSpecifier() { |
| const node = this.createNode(); |
| const local = this.lookahead.type == 8 /* StringLiteral */ ? this.parseModuleSpecifier() : this.parseIdentifierName(); |
| let exported = local; |
| if (this.matchContextualKeyword("as")) { |
| if (this.lookahead.escaped) { |
| this.throwError(Messages.NoAsAndFromEscapeSequences); |
| } |
| this.nextToken(); |
| exported = this.lookahead.type == 8 /* StringLiteral */ ? this.parseModuleSpecifier() : this.parseIdentifierName(); |
| } |
| return this.finalize(node, new ExportSpecifier(local, exported)); |
| } |
| parseExportDeclaration() { |
| if (this.context.inFunctionBody) { |
| this.throwError(Messages.IllegalExportDeclaration); |
| } |
| const node = this.createNode(); |
| this.expectKeyword("export"); |
| let exportDeclaration; |
| if (this.matchKeyword("default")) { |
| this.nextToken(); |
| if (this.matchKeyword("function")) { |
| const declaration = this.parseFunctionDeclaration(true); |
| exportDeclaration = this.finalize(node, new ExportDefaultDeclaration(declaration)); |
| } else if (this.matchKeyword("class")) { |
| const declaration = this.parseClassDeclaration(true); |
| exportDeclaration = this.finalize(node, new ExportDefaultDeclaration(declaration)); |
| } else if (this.matchContextualKeyword("async")) { |
| const declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression(); |
| exportDeclaration = this.finalize(node, new ExportDefaultDeclaration(declaration)); |
| } else { |
| if (this.matchContextualKeyword("from")) { |
| this.throwError(Messages.UnexpectedToken, this.lookahead.value); |
| } |
| const declaration = this.match("{") ? this.parseObjectInitializer() : this.match("[") ? this.parseArrayInitializer() : this.parseAssignmentExpression(); |
| this.consumeSemicolon(); |
| exportDeclaration = this.finalize(node, new ExportDefaultDeclaration(declaration)); |
| } |
| } else if (this.match("*")) { |
| this.nextToken(); |
| let exported = null; |
| if (this.matchContextualKeyword("as")) { |
| if (this.lookahead.escaped) { |
| this.throwError(Messages.NoAsAndFromEscapeSequences); |
| } |
| this.nextToken(); |
| exported = this.lookahead.type == 8 /* StringLiteral */ ? this.parseModuleSpecifier() : this.parseIdentifierName(); |
| } |
| if (!this.matchContextualKeyword("from")) { |
| const message = this.lookahead.value ? Messages.UnexpectedToken : Messages.MissingFromClause; |
| this.throwError(message, this.lookahead.value); |
| } |
| if (this.lookahead.escaped) { |
| this.throwError(Messages.NoAsAndFromEscapeSequences); |
| } |
| this.nextToken(); |
| const src = this.parseModuleSpecifier(); |
| const attributes = this.parseImportAttributes(); |
| this.consumeSemicolon(); |
| exportDeclaration = this.finalize(node, new ExportAllDeclaration(src, exported, attributes)); |
| } else if (this.lookahead.type === 4 /* Keyword */) { |
| let declaration; |
| switch (this.lookahead.value) { |
| case "let": |
| case "const": |
| declaration = this.parseLexicalDeclaration({ inFor: false }); |
| break; |
| case "var": |
| case "class": |
| case "function": |
| declaration = this.parseStatementListItem(); |
| break; |
| default: |
| this.throwUnexpectedToken(this.lookahead); |
| } |
| exportDeclaration = this.finalize(node, new ExportNamedDeclaration(declaration, [], null, null)); |
| } else if (this.matchAsyncFunction()) { |
| const declaration = this.parseFunctionDeclaration(); |
| exportDeclaration = this.finalize(node, new ExportNamedDeclaration(declaration, [], null, null)); |
| } else { |
| const specifiers = []; |
| let source = null; |
| let isExportFromIdentifier = false; |
| let attributes = null; |
| this.expect("{"); |
| while (!this.match("}")) { |
| isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword("default"); |
| specifiers.push(this.parseExportSpecifier()); |
| if (!this.match("}")) { |
| this.expect(","); |
| } |
| } |
| this.expect("}"); |
| if (this.matchContextualKeyword("from")) { |
| if (this.lookahead.escaped) { |
| this.throwError(Messages.NoAsAndFromEscapeSequences); |
| } |
| this.nextToken(); |
| source = this.parseModuleSpecifier(); |
| attributes = this.parseImportAttributes(); |
| this.consumeSemicolon(); |
| } else if (isExportFromIdentifier) { |
| const message = this.lookahead.value ? Messages.UnexpectedToken : Messages.MissingFromClause; |
| this.throwError(message, this.lookahead.value); |
| } else { |
| attributes = this.parseImportAttributes(); |
| this.consumeSemicolon(); |
| } |
| exportDeclaration = this.finalize(node, new ExportNamedDeclaration(null, specifiers, source, attributes)); |
| } |
| return exportDeclaration; |
| } |
| }; |
| |
| // src/xhtml-entities.ts |
| var XHTMLEntities = { |
| quot: '"', |
| amp: "&", |
| apos: "'", |
| gt: ">", |
| nbsp: "\xA0", |
| iexcl: "\xA1", |
| cent: "\xA2", |
| pound: "\xA3", |
| curren: "\xA4", |
| yen: "\xA5", |
| brvbar: "\xA6", |
| sect: "\xA7", |
| uml: "\xA8", |
| copy: "\xA9", |
| ordf: "\xAA", |
| laquo: "\xAB", |
| not: "\xAC", |
| shy: "\xAD", |
| reg: "\xAE", |
| macr: "\xAF", |
| deg: "\xB0", |
| plusmn: "\xB1", |
| sup2: "\xB2", |
| sup3: "\xB3", |
| acute: "\xB4", |
| micro: "\xB5", |
| para: "\xB6", |
| middot: "\xB7", |
| cedil: "\xB8", |
| sup1: "\xB9", |
| ordm: "\xBA", |
| raquo: "\xBB", |
| frac14: "\xBC", |
| frac12: "\xBD", |
| frac34: "\xBE", |
| iquest: "\xBF", |
| Agrave: "\xC0", |
| Aacute: "\xC1", |
| Acirc: "\xC2", |
| Atilde: "\xC3", |
| Auml: "\xC4", |
| Aring: "\xC5", |
| AElig: "\xC6", |
| Ccedil: "\xC7", |
| Egrave: "\xC8", |
| Eacute: "\xC9", |
| Ecirc: "\xCA", |
| Euml: "\xCB", |
| Igrave: "\xCC", |
| Iacute: "\xCD", |
| Icirc: "\xCE", |
| Iuml: "\xCF", |
| ETH: "\xD0", |
| Ntilde: "\xD1", |
| Ograve: "\xD2", |
| Oacute: "\xD3", |
| Ocirc: "\xD4", |
| Otilde: "\xD5", |
| Ouml: "\xD6", |
| times: "\xD7", |
| Oslash: "\xD8", |
| Ugrave: "\xD9", |
| Uacute: "\xDA", |
| Ucirc: "\xDB", |
| Uuml: "\xDC", |
| Yacute: "\xDD", |
| THORN: "\xDE", |
| szlig: "\xDF", |
| agrave: "\xE0", |
| aacute: "\xE1", |
| acirc: "\xE2", |
| atilde: "\xE3", |
| auml: "\xE4", |
| aring: "\xE5", |
| aelig: "\xE6", |
| ccedil: "\xE7", |
| egrave: "\xE8", |
| eacute: "\xE9", |
| ecirc: "\xEA", |
| euml: "\xEB", |
| igrave: "\xEC", |
| iacute: "\xED", |
| icirc: "\xEE", |
| iuml: "\xEF", |
| eth: "\xF0", |
| ntilde: "\xF1", |
| ograve: "\xF2", |
| oacute: "\xF3", |
| ocirc: "\xF4", |
| otilde: "\xF5", |
| ouml: "\xF6", |
| divide: "\xF7", |
| oslash: "\xF8", |
| ugrave: "\xF9", |
| uacute: "\xFA", |
| ucirc: "\xFB", |
| uuml: "\xFC", |
| yacute: "\xFD", |
| thorn: "\xFE", |
| yuml: "\xFF", |
| OElig: "\u0152", |
| oelig: "\u0153", |
| Scaron: "\u0160", |
| scaron: "\u0161", |
| Yuml: "\u0178", |
| fnof: "\u0192", |
| circ: "\u02C6", |
| tilde: "\u02DC", |
| Alpha: "\u0391", |
| Beta: "\u0392", |
| Gamma: "\u0393", |
| Delta: "\u0394", |
| Epsilon: "\u0395", |
| Zeta: "\u0396", |
| Eta: "\u0397", |
| Theta: "\u0398", |
| Iota: "\u0399", |
| Kappa: "\u039A", |
| Lambda: "\u039B", |
| Mu: "\u039C", |
| Nu: "\u039D", |
| Xi: "\u039E", |
| Omicron: "\u039F", |
| Pi: "\u03A0", |
| Rho: "\u03A1", |
| Sigma: "\u03A3", |
| Tau: "\u03A4", |
| Upsilon: "\u03A5", |
| Phi: "\u03A6", |
| Chi: "\u03A7", |
| Psi: "\u03A8", |
| Omega: "\u03A9", |
| alpha: "\u03B1", |
| beta: "\u03B2", |
| gamma: "\u03B3", |
| delta: "\u03B4", |
| epsilon: "\u03B5", |
| zeta: "\u03B6", |
| eta: "\u03B7", |
| theta: "\u03B8", |
| iota: "\u03B9", |
| kappa: "\u03BA", |
| lambda: "\u03BB", |
| mu: "\u03BC", |
| nu: "\u03BD", |
| xi: "\u03BE", |
| omicron: "\u03BF", |
| pi: "\u03C0", |
| rho: "\u03C1", |
| sigmaf: "\u03C2", |
| sigma: "\u03C3", |
| tau: "\u03C4", |
| upsilon: "\u03C5", |
| phi: "\u03C6", |
| chi: "\u03C7", |
| psi: "\u03C8", |
| omega: "\u03C9", |
| thetasym: "\u03D1", |
| upsih: "\u03D2", |
| piv: "\u03D6", |
| ensp: "\u2002", |
| emsp: "\u2003", |
| thinsp: "\u2009", |
| zwnj: "\u200C", |
| zwj: "\u200D", |
| lrm: "\u200E", |
| rlm: "\u200F", |
| ndash: "\u2013", |
| mdash: "\u2014", |
| lsquo: "\u2018", |
| rsquo: "\u2019", |
| sbquo: "\u201A", |
| ldquo: "\u201C", |
| rdquo: "\u201D", |
| bdquo: "\u201E", |
| dagger: "\u2020", |
| Dagger: "\u2021", |
| bull: "\u2022", |
| hellip: "\u2026", |
| permil: "\u2030", |
| prime: "\u2032", |
| Prime: "\u2033", |
| lsaquo: "\u2039", |
| rsaquo: "\u203A", |
| oline: "\u203E", |
| frasl: "\u2044", |
| euro: "\u20AC", |
| image: "\u2111", |
| weierp: "\u2118", |
| real: "\u211C", |
| trade: "\u2122", |
| alefsym: "\u2135", |
| larr: "\u2190", |
| uarr: "\u2191", |
| rarr: "\u2192", |
| darr: "\u2193", |
| harr: "\u2194", |
| crarr: "\u21B5", |
| lArr: "\u21D0", |
| uArr: "\u21D1", |
| rArr: "\u21D2", |
| dArr: "\u21D3", |
| hArr: "\u21D4", |
| forall: "\u2200", |
| part: "\u2202", |
| exist: "\u2203", |
| empty: "\u2205", |
| nabla: "\u2207", |
| isin: "\u2208", |
| notin: "\u2209", |
| ni: "\u220B", |
| prod: "\u220F", |
| sum: "\u2211", |
| minus: "\u2212", |
| lowast: "\u2217", |
| radic: "\u221A", |
| prop: "\u221D", |
| infin: "\u221E", |
| ang: "\u2220", |
| and: "\u2227", |
| or: "\u2228", |
| cap: "\u2229", |
| cup: "\u222A", |
| int: "\u222B", |
| there4: "\u2234", |
| sim: "\u223C", |
| cong: "\u2245", |
| asymp: "\u2248", |
| ne: "\u2260", |
| equiv: "\u2261", |
| le: "\u2264", |
| ge: "\u2265", |
| sub: "\u2282", |
| sup: "\u2283", |
| nsub: "\u2284", |
| sube: "\u2286", |
| supe: "\u2287", |
| oplus: "\u2295", |
| otimes: "\u2297", |
| perp: "\u22A5", |
| sdot: "\u22C5", |
| lceil: "\u2308", |
| rceil: "\u2309", |
| lfloor: "\u230A", |
| rfloor: "\u230B", |
| loz: "\u25CA", |
| spades: "\u2660", |
| clubs: "\u2663", |
| hearts: "\u2665", |
| diams: "\u2666", |
| lang: "\u27E8", |
| rang: "\u27E9" |
| }; |
| |
| // src/jsx-parser.ts |
| TokenName[100 /* Identifier */] = "JSXIdentifier"; |
| TokenName[101 /* Text */] = "JSXText"; |
| function getQualifiedElementName(elementName) { |
| let qualifiedName; |
| switch (elementName.type) { |
| case "JSXIdentifier" /* JSXIdentifier */: |
| const id = elementName; |
| qualifiedName = id.name; |
| break; |
| case "JSXNamespacedName" /* JSXNamespacedName */: |
| const ns = elementName; |
| qualifiedName = getQualifiedElementName(ns.namespace) + ":" + getQualifiedElementName(ns.name); |
| break; |
| case "JSXMemberExpression" /* JSXMemberExpression */: |
| const expr = elementName; |
| qualifiedName = getQualifiedElementName(expr.object) + "." + getQualifiedElementName(expr.property); |
| break; |
| default: |
| break; |
| } |
| return qualifiedName; |
| } |
| var JSXParser = class extends Parser { |
| constructor(code, options, delegate) { |
| super(code, options, delegate); |
| } |
| //@ts-ignore |
| parsePrimaryExpression() { |
| return this.match("<") ? this.parseJSXRoot() : super.parsePrimaryExpression(); |
| } |
| startJSX() { |
| this.scanner.index = this.startMarker.index; |
| this.scanner.lineNumber = this.startMarker.line; |
| this.scanner.lineStart = this.startMarker.index - this.startMarker.column; |
| } |
| finishJSX() { |
| this.nextToken(); |
| } |
| reenterJSX() { |
| this.startJSX(); |
| this.expectJSX("}"); |
| if (this.config.tokens) { |
| this.tokens.pop(); |
| } |
| } |
| createJSXNode() { |
| this.collectComments(); |
| return { |
| index: this.scanner.index, |
| line: this.scanner.lineNumber, |
| column: this.scanner.index - this.scanner.lineStart |
| }; |
| } |
| createJSXChildNode() { |
| return { |
| index: this.scanner.index, |
| line: this.scanner.lineNumber, |
| column: this.scanner.index - this.scanner.lineStart |
| }; |
| } |
| scanXHTMLEntity(quote) { |
| let result = "&"; |
| let valid = true; |
| let terminated = false; |
| let numeric = false; |
| let hex = false; |
| while (!this.scanner.eof() && valid && !terminated) { |
| const ch = this.scanner.source[this.scanner.index]; |
| if (ch === quote) { |
| break; |
| } |
| terminated = ch === ";"; |
| result += ch; |
| ++this.scanner.index; |
| if (!terminated) { |
| switch (result.length) { |
| case 2: |
| numeric = ch === "#"; |
| break; |
| case 3: |
| if (numeric) { |
| hex = ch === "x"; |
| valid = hex || Character.isDecimalDigit(ch.charCodeAt(0)); |
| numeric = numeric && !hex; |
| } |
| break; |
| default: |
| valid = valid && !(numeric && !Character.isDecimalDigit(ch.charCodeAt(0))); |
| valid = valid && !(hex && !Character.isHexDigit(ch.charCodeAt(0))); |
| break; |
| } |
| } |
| } |
| if (valid && terminated && result.length > 2) { |
| const str = result.substr(1, result.length - 2); |
| if (numeric && str.length > 1) { |
| result = String.fromCharCode(parseInt(str.substr(1), 10)); |
| } else if (hex && str.length > 2) { |
| result = String.fromCharCode(parseInt("0" + str.substr(1), 16)); |
| } else if (!numeric && !hex && XHTMLEntities[str]) { |
| result = XHTMLEntities[str]; |
| } |
| } |
| return result; |
| } |
| // Scan the next JSX token. This replaces Scanner#lex when in JSX mode. |
| lexJSX() { |
| const cp = this.scanner.source.charCodeAt(this.scanner.index); |
| if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) { |
| const value = this.scanner.source[this.scanner.index++]; |
| return { |
| type: 7 /* Punctuator */, |
| value, |
| lineNumber: this.scanner.lineNumber, |
| lineStart: this.scanner.lineStart, |
| start: this.scanner.index - 1, |
| end: this.scanner.index |
| }; |
| } |
| if (cp === 34 || cp === 39) { |
| const start = this.scanner.index; |
| const quote = this.scanner.source[this.scanner.index++]; |
| let str = ""; |
| while (!this.scanner.eof()) { |
| const ch = this.scanner.source[this.scanner.index++]; |
| if (ch === quote) { |
| break; |
| } else if (ch === "&") { |
| str += this.scanXHTMLEntity(quote); |
| } else { |
| str += ch; |
| } |
| } |
| return { |
| type: 8 /* StringLiteral */, |
| value: str, |
| lineNumber: this.scanner.lineNumber, |
| lineStart: this.scanner.lineStart, |
| start, |
| end: this.scanner.index |
| }; |
| } |
| if (cp === 46) { |
| const n1 = this.scanner.source.charCodeAt(this.scanner.index + 1); |
| const n2 = this.scanner.source.charCodeAt(this.scanner.index + 2); |
| const value = n1 === 46 && n2 === 46 ? "..." : "."; |
| const start = this.scanner.index; |
| this.scanner.index += value.length; |
| return { |
| type: 7 /* Punctuator */, |
| value, |
| lineNumber: this.scanner.lineNumber, |
| lineStart: this.scanner.lineStart, |
| start, |
| end: this.scanner.index |
| }; |
| } |
| if (cp === 96) { |
| return { |
| type: 10 /* Template */, |
| value: "", |
| lineNumber: this.scanner.lineNumber, |
| lineStart: this.scanner.lineStart, |
| start: this.scanner.index, |
| end: this.scanner.index |
| }; |
| } |
| if (Character.isIdentifierStart(cp) && cp !== 92) { |
| const start = this.scanner.index; |
| ++this.scanner.index; |
| while (!this.scanner.eof()) { |
| const ch = this.scanner.source.charCodeAt(this.scanner.index); |
| if (Character.isIdentifierPart(ch) && ch !== 92) { |
| ++this.scanner.index; |
| } else if (ch === 45) { |
| ++this.scanner.index; |
| } else { |
| break; |
| } |
| } |
| const id = this.scanner.source.slice(start, this.scanner.index); |
| return { |
| type: 100 /* Identifier */, |
| value: id, |
| lineNumber: this.scanner.lineNumber, |
| lineStart: this.scanner.lineStart, |
| start, |
| end: this.scanner.index |
| }; |
| } |
| return this.scanner.lex(); |
| } |
| nextJSXToken() { |
| this.collectComments(); |
| this.startMarker.index = this.scanner.index; |
| this.startMarker.line = this.scanner.lineNumber; |
| this.startMarker.column = this.scanner.index - this.scanner.lineStart; |
| const token = this.lexJSX(); |
| this.lastMarker.index = this.scanner.index; |
| this.lastMarker.line = this.scanner.lineNumber; |
| this.lastMarker.column = this.scanner.index - this.scanner.lineStart; |
| if (this.config.tokens) { |
| this.tokens.push(this.convertToken(token)); |
| } |
| return token; |
| } |
| nextJSXText() { |
| this.startMarker.index = this.scanner.index; |
| this.startMarker.line = this.scanner.lineNumber; |
| this.startMarker.column = this.scanner.index - this.scanner.lineStart; |
| const start = this.scanner.index; |
| let text = ""; |
| while (!this.scanner.eof()) { |
| const ch = this.scanner.source[this.scanner.index]; |
| if (ch === "{" || ch === "<") { |
| break; |
| } |
| ++this.scanner.index; |
| text += ch; |
| if (Character.isLineTerminator(ch.charCodeAt(0))) { |
| ++this.scanner.lineNumber; |
| if (ch === "\r" && this.scanner.source[this.scanner.index] === "\n") { |
| ++this.scanner.index; |
| } |
| this.scanner.lineStart = this.scanner.index; |
| } |
| } |
| this.lastMarker.index = this.scanner.index; |
| this.lastMarker.line = this.scanner.lineNumber; |
| this.lastMarker.column = this.scanner.index - this.scanner.lineStart; |
| const token = { |
| type: 101 /* Text */, |
| value: text, |
| lineNumber: this.scanner.lineNumber, |
| lineStart: this.scanner.lineStart, |
| start, |
| end: this.scanner.index |
| }; |
| if (text.length > 0 && this.config.tokens) { |
| this.tokens.push(this.convertToken(token)); |
| } |
| return token; |
| } |
| peekJSXToken() { |
| const state = this.scanner.saveState(); |
| this.scanner.scanComments(); |
| const next = this.lexJSX(); |
| this.scanner.restoreState(state); |
| return next; |
| } |
| // Expect the next JSX token to match the specified punctuator. |
| // If not, an exception will be thrown. |
| expectJSX(value) { |
| const token = this.nextJSXToken(); |
| if (token.type !== 7 /* Punctuator */ || token.value !== value) { |
| this.throwUnexpectedToken(token); |
| } |
| } |
| // Return true if the next JSX token matches the specified punctuator. |
| matchJSX(value) { |
| const next = this.peekJSXToken(); |
| return next.type === 7 /* Punctuator */ && next.value === value; |
| } |
| parseJSXIdentifier() { |
| const node = this.createJSXNode(); |
| const token = this.nextJSXToken(); |
| if (token.type !== 100 /* Identifier */) { |
| this.throwUnexpectedToken(token); |
| } |
| return this.finalize(node, new JSXIdentifier(token.value)); |
| } |
| parseJSXElementName() { |
| const node = this.createJSXNode(); |
| let elementName = this.parseJSXIdentifier(); |
| if (this.matchJSX(":")) { |
| const namespace = elementName; |
| this.expectJSX(":"); |
| const name = this.parseJSXIdentifier(); |
| elementName = this.finalize(node, new JSXNamespacedName(namespace, name)); |
| } else if (this.matchJSX(".")) { |
| while (this.matchJSX(".")) { |
| const object = elementName; |
| this.expectJSX("."); |
| const property = this.parseJSXIdentifier(); |
| elementName = this.finalize(node, new JSXMemberExpression(object, property)); |
| } |
| } |
| return elementName; |
| } |
| parseJSXAttributeName() { |
| const node = this.createJSXNode(); |
| let attributeName; |
| const identifier = this.parseJSXIdentifier(); |
| if (this.matchJSX(":")) { |
| const namespace = identifier; |
| this.expectJSX(":"); |
| const name = this.parseJSXIdentifier(); |
| attributeName = this.finalize(node, new JSXNamespacedName(namespace, name)); |
| } else { |
| attributeName = identifier; |
| } |
| return attributeName; |
| } |
| parseJSXStringLiteralAttribute() { |
| const node = this.createJSXNode(); |
| const token = this.nextJSXToken(); |
| if (token.type !== 8 /* StringLiteral */) { |
| this.throwUnexpectedToken(token); |
| } |
| const raw = this.getTokenRaw(token); |
| return this.finalize(node, new Literal(token.value, raw)); |
| } |
| parseJSXExpressionAttribute() { |
| const node = this.createJSXNode(); |
| this.expectJSX("{"); |
| this.finishJSX(); |
| if (this.match("}")) { |
| this.tolerateError("JSX attributes must only be assigned a non-empty expression"); |
| } |
| const expression = this.parseAssignmentExpression(); |
| this.reenterJSX(); |
| return this.finalize(node, new JSXExpressionContainer(expression)); |
| } |
| parseJSXAttributeValue() { |
| return this.matchJSX("{") ? this.parseJSXExpressionAttribute() : this.matchJSX("<") ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute(); |
| } |
| parseJSXNameValueAttribute() { |
| const node = this.createJSXNode(); |
| const name = this.parseJSXAttributeName(); |
| let value = null; |
| if (this.matchJSX("=")) { |
| this.expectJSX("="); |
| value = this.parseJSXAttributeValue(); |
| } |
| return this.finalize(node, new JSXAttribute(name, value)); |
| } |
| parseJSXSpreadAttribute() { |
| const node = this.createJSXNode(); |
| this.expectJSX("{"); |
| this.expectJSX("..."); |
| this.finishJSX(); |
| const argument = this.parseAssignmentExpression(); |
| this.reenterJSX(); |
| return this.finalize(node, new JSXSpreadAttribute(argument)); |
| } |
| parseJSXAttributes() { |
| const attributes = []; |
| while (!this.matchJSX("/") && !this.matchJSX(">")) { |
| const attribute = this.matchJSX("{") ? this.parseJSXSpreadAttribute() : this.parseJSXNameValueAttribute(); |
| attributes.push(attribute); |
| } |
| return attributes; |
| } |
| parseJSXOpeningElement() { |
| const node = this.createJSXNode(); |
| this.expectJSX("<"); |
| if (this.matchJSX(">")) { |
| this.expectJSX(">"); |
| return this.finalize(node, new JSXOpeningFragment(false)); |
| } |
| const name = this.parseJSXElementName(); |
| const attributes = this.parseJSXAttributes(); |
| const selfClosing = this.matchJSX("/"); |
| if (selfClosing) { |
| this.expectJSX("/"); |
| } |
| this.expectJSX(">"); |
| return this.finalize(node, new JSXOpeningElement(name, selfClosing, attributes)); |
| } |
| parseJSXBoundaryElement() { |
| const node = this.createJSXNode(); |
| this.expectJSX("<"); |
| if (this.matchJSX("/")) { |
| this.expectJSX("/"); |
| if (this.matchJSX(">")) { |
| this.expectJSX(">"); |
| return this.finalize(node, new JSXClosingFragment()); |
| } |
| const elementName = this.parseJSXElementName(); |
| this.expectJSX(">"); |
| return this.finalize(node, new JSXClosingElement(elementName)); |
| } |
| const name = this.parseJSXElementName(); |
| const attributes = this.parseJSXAttributes(); |
| const selfClosing = this.matchJSX("/"); |
| if (selfClosing) { |
| this.expectJSX("/"); |
| } |
| this.expectJSX(">"); |
| return this.finalize(node, new JSXOpeningElement(name, selfClosing, attributes)); |
| } |
| parseJSXEmptyExpression() { |
| const node = this.createJSXChildNode(); |
| this.collectComments(); |
| this.lastMarker.index = this.scanner.index; |
| this.lastMarker.line = this.scanner.lineNumber; |
| this.lastMarker.column = this.scanner.index - this.scanner.lineStart; |
| return this.finalize(node, new JSXEmptyExpression()); |
| } |
| parseJSXExpressionContainer() { |
| const node = this.createJSXNode(); |
| this.expectJSX("{"); |
| let expression; |
| if (this.matchJSX("}")) { |
| expression = this.parseJSXEmptyExpression(); |
| this.expectJSX("}"); |
| } else { |
| this.finishJSX(); |
| expression = this.parseAssignmentExpression(); |
| this.reenterJSX(); |
| } |
| return this.finalize(node, new JSXExpressionContainer(expression)); |
| } |
| parseJSXChildren() { |
| const children = []; |
| while (!this.scanner.eof()) { |
| const node = this.createJSXChildNode(); |
| const token = this.nextJSXText(); |
| if (token.start < token.end) { |
| const raw = this.getTokenRaw(token); |
| const child = this.finalize(node, new JSXText(token.value, raw)); |
| children.push(child); |
| } |
| if (this.scanner.source[this.scanner.index] === "{") { |
| const container = this.parseJSXExpressionContainer(); |
| children.push(container); |
| } else { |
| break; |
| } |
| } |
| return children; |
| } |
| parseComplexJSXElement(el) { |
| const stack = []; |
| while (!this.scanner.eof()) { |
| el.children = el.children.concat(this.parseJSXChildren()); |
| const node = this.createJSXChildNode(); |
| const element = this.parseJSXBoundaryElement(); |
| if (element.type === "JSXOpeningElement" /* JSXOpeningElement */) { |
| const opening = element; |
| if (opening.selfClosing) { |
| const child = this.finalize(node, new JSXElement(opening, [], null)); |
| el.children.push(child); |
| } else { |
| stack.push(el); |
| el = { node, opening, closing: null, children: [] }; |
| } |
| } |
| if (element.type === "JSXClosingElement" /* JSXClosingElement */) { |
| el.closing = element; |
| const open = getQualifiedElementName(el.opening.name); |
| const close = getQualifiedElementName(el.closing.name); |
| if (open !== close) { |
| this.tolerateError("Expected corresponding JSX closing tag for %0", open); |
| } |
| if (stack.length > 0) { |
| const child = this.finalize(el.node, new JSXElement(el.opening, el.children, el.closing)); |
| el = stack[stack.length - 1]; |
| el.children.push(child); |
| stack.pop(); |
| } else { |
| break; |
| } |
| } |
| if (element.type === "JSXClosingFragment" /* JSXClosingFragment */) { |
| el.closing = element; |
| if (el.opening.type !== "JSXOpeningFragment" /* JSXOpeningFragment */) { |
| this.tolerateError("Expected corresponding JSX closing tag for jsx fragment"); |
| } else { |
| break; |
| } |
| } |
| } |
| return el; |
| } |
| parseJSXElement() { |
| const node = this.createJSXNode(); |
| const opening = this.parseJSXOpeningElement(); |
| let children = []; |
| let closing = null; |
| if (!opening.selfClosing) { |
| const el = this.parseComplexJSXElement({ node, opening, closing, children }); |
| children = el.children; |
| closing = el.closing; |
| } |
| return this.finalize(node, new JSXElement(opening, children, closing)); |
| } |
| parseJSXRoot() { |
| if (this.config.tokens) { |
| this.tokens.pop(); |
| } |
| this.startJSX(); |
| const element = this.parseJSXElement(); |
| this.finishJSX(); |
| return element; |
| } |
| isStartOfExpression() { |
| return super.isStartOfExpression() || this.match("<"); |
| } |
| }; |
| |
| // src/tokenizer.ts |
| var beforeFunctionExpressionTokens = [ |
| "(", |
| "{", |
| "[", |
| "in", |
| "typeof", |
| "instanceof", |
| "new", |
| "return", |
| "case", |
| "delete", |
| "throw", |
| "void", |
| // assignment operators |
| "=", |
| "+=", |
| "-=", |
| "*=", |
| "**=", |
| "/=", |
| "%=", |
| "<<=", |
| ">>=", |
| ">>>=", |
| "&=", |
| "|=", |
| "^=", |
| ",", |
| // binary/unary operators |
| "+", |
| "-", |
| "*", |
| "**", |
| "/", |
| "%", |
| "++", |
| "--", |
| "<<", |
| ">>", |
| ">>>", |
| "&", |
| "|", |
| "^", |
| "!", |
| "~", |
| "&&", |
| "||", |
| "??", |
| "?", |
| ":", |
| "===", |
| "==", |
| ">=", |
| "<=", |
| "<", |
| ">", |
| "!=", |
| "!==" |
| ]; |
| var Reader = class { |
| values; |
| curly; |
| paren; |
| constructor() { |
| this.values = []; |
| this.curly = this.paren = -1; |
| } |
| // A function following one of those tokens is an expression. |
| beforeFunctionExpression(t) { |
| return beforeFunctionExpressionTokens.includes(t); |
| } |
| // Determine if forward slash (/) is an operator or part of a regular expression |
| // https://github.com/mozilla/sweet.js/wiki/design |
| isRegexStart() { |
| const previous = this.values[this.values.length - 1]; |
| let regex = previous !== null; |
| switch (previous) { |
| case "this": |
| case "]": |
| regex = false; |
| break; |
| case ")": |
| const keyword = this.values[this.paren - 1]; |
| regex = keyword === "if" || keyword === "while" || keyword === "for" || keyword === "with"; |
| break; |
| case "}": |
| regex = true; |
| if (this.values[this.curly - 3] === "function") { |
| const check = this.values[this.curly - 4]; |
| regex = check ? !this.beforeFunctionExpression(check) : false; |
| } else if (this.values[this.curly - 4] === "function") { |
| const check = this.values[this.curly - 5]; |
| regex = check ? !this.beforeFunctionExpression(check) : true; |
| } |
| break; |
| default: |
| break; |
| } |
| return regex; |
| } |
| push(token) { |
| if (token.type === 7 /* Punctuator */ || token.type === 4 /* Keyword */) { |
| if (token.value === "{") { |
| this.curly = this.values.length; |
| } else if (token.value === "(") { |
| this.paren = this.values.length; |
| } |
| this.values.push(token.value); |
| } else { |
| this.values.push(null); |
| } |
| } |
| }; |
| var Tokenizer = class { |
| errorHandler; |
| scanner; |
| trackRange; |
| trackLoc; |
| buffer; |
| reader; |
| constructor(code, config) { |
| this.errorHandler = new ErrorHandler(); |
| this.errorHandler.tolerant = config ? typeof config.tolerant === "boolean" && config.tolerant : false; |
| this.scanner = new Scanner(code, this.errorHandler); |
| this.scanner.trackComment = config ? typeof config.comment === "boolean" && config.comment : false; |
| this.trackRange = config ? typeof config.range === "boolean" && config.range : false; |
| this.trackLoc = config ? typeof config.loc === "boolean" && config.loc : false; |
| this.buffer = []; |
| this.reader = new Reader(); |
| } |
| errors() { |
| return this.errorHandler.errors; |
| } |
| getNextToken() { |
| if (this.buffer.length === 0) { |
| const comments = this.scanner.scanComments(); |
| if (this.scanner.trackComment) { |
| for (let i = 0; i < comments.length; ++i) { |
| const e = comments[i]; |
| const value = this.scanner.source.slice(e.slice[0], e.slice[1]); |
| const comment = { |
| type: e.multiLine ? "BlockComment" : "LineComment", |
| value |
| }; |
| if (this.trackRange) { |
| comment.range = e.range; |
| } |
| if (this.trackLoc) { |
| comment.loc = e.loc; |
| } |
| this.buffer.push(comment); |
| } |
| } |
| if (!this.scanner.eof()) { |
| let loc; |
| if (this.trackLoc) { |
| loc = { |
| start: { |
| line: this.scanner.lineNumber, |
| column: this.scanner.index - this.scanner.lineStart |
| }, |
| end: {} |
| }; |
| } |
| const maybeRegex = this.scanner.source[this.scanner.index] === "/" && this.reader.isRegexStart(); |
| let token; |
| if (maybeRegex) { |
| const state = this.scanner.saveState(); |
| try { |
| token = this.scanner.scanRegExp(); |
| } catch (e) { |
| this.scanner.restoreState(state); |
| token = this.scanner.lex(); |
| } |
| } else { |
| token = this.scanner.lex(); |
| } |
| this.reader.push(token); |
| const entry = { |
| type: TokenName[token.type], |
| value: this.scanner.source.slice(token.start, token.end) |
| }; |
| if (this.trackRange) { |
| entry.range = [token.start, token.end]; |
| } |
| if (this.trackLoc) { |
| loc.end = { |
| line: this.scanner.lineNumber, |
| column: this.scanner.index - this.scanner.lineStart |
| }; |
| entry.loc = loc; |
| } |
| if (token.type === 9 /* RegularExpression */) { |
| const pattern = token.pattern; |
| const flags = token.flags; |
| entry.regex = { pattern, flags }; |
| } |
| this.buffer.push(entry); |
| } |
| } |
| return this.buffer.shift(); |
| } |
| }; |
| |
| // src/visitor.ts |
| var Visitor = class { |
| visit(node) { |
| if (node == null) |
| return node; |
| switch (node.type) { |
| case "AssignmentExpression" /* AssignmentExpression */: |
| return this.visitAssignmentExpression(node); |
| case "AssignmentPattern" /* AssignmentPattern */: |
| return this.visitAssignmentPattern(node); |
| case "ArrayExpression" /* ArrayExpression */: |
| return this.visitArrayExpression(node); |
| case "ArrayPattern" /* ArrayPattern */: |
| return this.visitArrayPattern(node); |
| case "ArrowFunctionExpression" /* ArrowFunctionExpression */: |
| return this.visitArrowFunctionExpression(node); |
| case "AwaitExpression" /* AwaitExpression */: |
| return this.visitAwaitExpression(node); |
| case "BlockStatement" /* BlockStatement */: |
| return this.visitBlockStatement(node); |
| case "BinaryExpression" /* BinaryExpression */: |
| return this.visitBinaryExpression(node); |
| case "BreakStatement" /* BreakStatement */: |
| return this.visitBreakStatement(node); |
| case "CallExpression" /* CallExpression */: |
| return this.visitCallExpression(node); |
| case "CatchClause" /* CatchClause */: |
| return this.visitCatchClause(node); |
| case "ChainExpression" /* ChainExpression */: |
| return this.visitChainExpression(node); |
| case "ClassBody" /* ClassBody */: |
| return this.visitClassBody(node); |
| case "ClassDeclaration" /* ClassDeclaration */: |
| return this.visitClassDeclaration(node); |
| case "ClassExpression" /* ClassExpression */: |
| return this.visitClassExpression(node); |
| case "ConditionalExpression" /* ConditionalExpression */: |
| return this.visitConditionalExpression(node); |
| case "ContinueStatement" /* ContinueStatement */: |
| return this.visitContinueStatement(node); |
| case "Decorator" /* Decorator */: |
| return this.visitDecorator(node); |
| case "DoWhileStatement" /* DoWhileStatement */: |
| return this.visitDoWhileStatement(node); |
| case "DebuggerStatement" /* DebuggerStatement */: |
| return this.visitDebuggerStatement(node); |
| case "EmptyStatement" /* EmptyStatement */: |
| return this.visitEmptyStatement(node); |
| case "ExportAllDeclaration" /* ExportAllDeclaration */: |
| return this.visitExportAllDeclaration(node); |
| case "ExportDefaultDeclaration" /* ExportDefaultDeclaration */: |
| return this.visitExportDefaultDeclaration(node); |
| case "ExportNamedDeclaration" /* ExportNamedDeclaration */: |
| return this.visitExportNamedDeclaration(node); |
| case "ExportSpecifier" /* ExportSpecifier */: |
| return this.visitExportSpecifier(node); |
| case "ExpressionStatement" /* ExpressionStatement */: |
| return this.visitExpressionStatement(node); |
| case "ForStatement" /* ForStatement */: |
| return this.visitForStatement(node); |
| case "ForOfStatement" /* ForOfStatement */: |
| return this.visitForOfStatement(node); |
| case "ForInStatement" /* ForInStatement */: |
| return this.visitForInStatement(node); |
| case "FunctionDeclaration" /* FunctionDeclaration */: |
| return this.visitFunctionDeclaration(node); |
| case "FunctionExpression" /* FunctionExpression */: |
| return this.visitFunctionExpression(node); |
| case "Identifier" /* Identifier */: |
| return this.visitIdentifier(node); |
| case "IfStatement" /* IfStatement */: |
| return this.visitIfStatement(node); |
| case "ImportAttribute" /* ImportAttribute */: |
| return this.visitImportAttribute(node); |
| case "ImportExpression" /* ImportExpression */: |
| return this.visitImportExpression(node); |
| case "ImportDeclaration" /* ImportDeclaration */: |
| return this.visitImportDeclaration(node); |
| case "ImportDefaultSpecifier" /* ImportDefaultSpecifier */: |
| return this.visitImportDefaultSpecifier(node); |
| case "ImportNamespaceSpecifier" /* ImportNamespaceSpecifier */: |
| return this.visitImportNamespaceSpecifier(node); |
| case "ImportSpecifier" /* ImportSpecifier */: |
| return this.visitImportSpecifier(node); |
| case "Literal" /* Literal */: |
| return this.visitLiteral(node); |
| case "LabeledStatement" /* LabeledStatement */: |
| return this.visitLabeledStatement(node); |
| case "LogicalExpression" /* LogicalExpression */: |
| return this.visitLogicalExpression(node); |
| case "MemberExpression" /* MemberExpression */: |
| return this.visitMemberExpression(node); |
| case "MetaProperty" /* MetaProperty */: |
| return this.visitMetaProperty(node); |
| case "MethodDefinition" /* MethodDefinition */: |
| return this.visitMethodDefinition(node); |
| case "NewExpression" /* NewExpression */: |
| return this.visitNewExpression(node); |
| case "ObjectExpression" /* ObjectExpression */: |
| return this.visitObjectExpression(node); |
| case "ObjectPattern" /* ObjectPattern */: |
| return this.visitObjectPattern(node); |
| case "Program" /* Program */: |
| return this.visitProgram(node); |
| case "Property" /* Property */: |
| return this.visitProperty(node); |
| case "PrivateIdentifier" /* PrivateIdentifier */: |
| return this.visitPrivateIdentifier(node); |
| case "RestElement" /* RestElement */: |
| return this.visitRestElement(node); |
| case "ReturnStatement" /* ReturnStatement */: |
| return this.visitReturnStatement(node); |
| case "SequenceExpression" /* SequenceExpression */: |
| return this.visitSequenceExpression(node); |
| case "SpreadElement" /* SpreadElement */: |
| return this.visitSpreadElement(node); |
| case "StaticBlock" /* StaticBlock */: |
| return this.visitStaticBlock(node); |
| case "Super" /* Super */: |
| return this.visitSuper(node); |
| case "SwitchCase" /* SwitchCase */: |
| return this.visitSwitchCase(node); |
| case "SwitchStatement" /* SwitchStatement */: |
| return this.visitSwitchStatement(node); |
| case "TaggedTemplateExpression" /* TaggedTemplateExpression */: |
| return this.visitTaggedTemplateExpression(node); |
| case "TemplateElement" /* TemplateElement */: |
| return this.visitTemplateElement(node); |
| case "TemplateLiteral" /* TemplateLiteral */: |
| return this.visitTemplateLiteral(node); |
| case "ThisExpression" /* ThisExpression */: |
| return this.visitThisExpression(node); |
| case "ThrowStatement" /* ThrowStatement */: |
| return this.visitThrowStatement(node); |
| case "TryStatement" /* TryStatement */: |
| return this.visitTryStatement(node); |
| case "UnaryExpression" /* UnaryExpression */: |
| return this.visitUnaryExpression(node); |
| case "UpdateExpression" /* UpdateExpression */: |
| return this.visitUpdateExpression(node); |
| case "VariableDeclaration" /* VariableDeclaration */: |
| return this.visitVariableDeclaration(node); |
| case "VariableDeclarator" /* VariableDeclarator */: |
| return this.visitVariableDeclarator(node); |
| case "WhileStatement" /* WhileStatement */: |
| return this.visitWhileStatement(node); |
| case "WithStatement" /* WithStatement */: |
| return this.visitWithStatement(node); |
| case "YieldExpression" /* YieldExpression */: |
| return this.visitYieldExpression(node); |
| } |
| } |
| visitNodeList(original) { |
| if (original == null) |
| return original; |
| let list = null; |
| for (let i = 0, n = original.length; i < n; i++) { |
| let p = this.visit(original[i]); |
| if (list != null) { |
| list.push(p); |
| } else if (p != original[i]) { |
| list = []; |
| for (let j = 0; j < i; j++) { |
| list.push(original[j]); |
| } |
| list.push(p); |
| } |
| } |
| if (list != null) |
| return list; |
| return original; |
| } |
| visitAssignmentExpression(node) { |
| const left = this.visit(node.left); |
| const right = this.visit(node.right); |
| if (left !== node.left || right !== node.right) |
| return new AssignmentExpression(node.operator, left, right); |
| return node; |
| } |
| visitAssignmentPattern(node) { |
| const left = this.visit(node.left); |
| const right = this.visit(node.right); |
| if (left !== node.left || right !== node.right) |
| return new AssignmentPattern(left, right); |
| return node; |
| } |
| visitArrayExpression(node) { |
| const elements = this.visitNodeList(node.elements); |
| if (elements !== node.elements) |
| return new ArrayExpression(elements); |
| return node; |
| } |
| visitArrayPattern(node) { |
| const elements = this.visitNodeList(node.elements); |
| if (elements !== node.elements) |
| return new ArrayPattern(elements); |
| return node; |
| } |
| visitArrowFunctionExpression(node) { |
| const id = this.visit(node.id); |
| const params = this.visitNodeList(node.params); |
| const body = this.visit(node.body); |
| if (id !== node.id || params !== node.params || body !== node.body) { |
| const ret = new ArrowFunctionExpression(params, body, node.expression, node.async); |
| ret.id = id; |
| return ret; |
| } |
| return node; |
| } |
| visitAwaitExpression(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new AwaitExpression(argument); |
| return node; |
| } |
| visitBlockStatement(node) { |
| const body = this.visitNodeList(node.body); |
| if (body !== node.body) |
| return new BlockStatement(body); |
| return node; |
| } |
| visitBinaryExpression(node) { |
| const left = this.visit(node.left); |
| const right = this.visit(node.right); |
| if (left !== node.left || right !== node.right) |
| return new BinaryExpression(node.operator, left, right); |
| return node; |
| } |
| visitBreakStatement(node) { |
| const label = this.visit(node.label); |
| if (label !== node.label) |
| return new BreakStatement(label); |
| return node; |
| } |
| visitCallExpression(node) { |
| const callee = this.visit(node.callee); |
| const args = this.visitNodeList(node.arguments); |
| if (callee !== node.callee || args !== node.arguments) |
| return new CallExpression(callee, args, node.optional); |
| return node; |
| } |
| visitCatchClause(node) { |
| const param = this.visit(node.param); |
| const body = this.visit(node.body); |
| if (param !== node.param || body !== node.body) |
| return new CatchClause(param, body); |
| return node; |
| } |
| visitChainExpression(node) { |
| const expression = this.visit(node.expression); |
| if (expression !== node.expression) |
| return new ChainExpression(expression); |
| return node; |
| } |
| visitClassBody(node) { |
| const body = this.visitNodeList(node.body); |
| if (body !== node.body) |
| return new ClassBody(body); |
| return node; |
| } |
| visitClassDeclaration(node) { |
| const id = this.visit(node.id); |
| const superClass = this.visit(node.superClass); |
| const body = this.visit(node.body); |
| const decorators = this.visitNodeList(node.decorators); |
| if (id !== node.id || superClass !== node.superClass || body !== node.body || decorators !== node.decorators) |
| return new ClassDeclaration(id, superClass, body, decorators); |
| return node; |
| } |
| visitClassExpression(node) { |
| const id = this.visit(node.id); |
| const superClass = this.visit(node.superClass); |
| const body = this.visit(node.body); |
| const decorators = this.visitNodeList(node.decorators); |
| if (id !== node.id || superClass !== node.superClass || body !== node.body || decorators !== node.decorators) |
| return new ClassExpression(id, superClass, body, decorators); |
| return node; |
| } |
| visitConditionalExpression(node) { |
| const test = this.visit(node.test); |
| const consequent = this.visit(node.consequent); |
| const alternate = this.visit(node.alternate); |
| if (test !== node.test || consequent !== node.consequent || alternate !== node.alternate) |
| return new ConditionalExpression(test, consequent, alternate); |
| return node; |
| } |
| visitContinueStatement(node) { |
| const label = this.visit(node.label); |
| if (label !== node.label) |
| return new ContinueStatement(label); |
| return node; |
| } |
| visitDecorator(node) { |
| const expression = this.visit(node.expression); |
| if (expression !== node.expression) |
| return new Decorator(expression); |
| return node; |
| } |
| visitDoWhileStatement(node) { |
| const body = this.visit(node.body); |
| const test = this.visit(node.test); |
| if (body !== node.body || test !== node.test) |
| return new DoWhileStatement(body, test); |
| return node; |
| } |
| visitDebuggerStatement(node) { |
| return node; |
| } |
| visitEmptyStatement(node) { |
| return node; |
| } |
| visitExportAllDeclaration(node) { |
| const source = this.visit(node.source); |
| const exported = this.visit(node.exported); |
| const assertions = this.visitNodeList(node.assertions); |
| if (source !== node.source || exported !== node.exported || assertions !== node.assertions) |
| return new ExportAllDeclaration(source, exported, assertions); |
| return node; |
| } |
| visitExportDefaultDeclaration(node) { |
| const declaration = this.visit(node.declaration); |
| if (declaration !== node.declaration) |
| return new ExportDefaultDeclaration(declaration); |
| return node; |
| } |
| visitExportNamedDeclaration(node) { |
| const declaration = this.visit(node.declaration); |
| const specifiers = this.visitNodeList(node.specifiers); |
| const source = this.visit(node.source); |
| const assertions = this.visitNodeList(node.assertions); |
| if (declaration !== node.declaration || specifiers !== node.specifiers || source !== node.source || assertions !== node.assertions) |
| return new ExportNamedDeclaration(declaration, specifiers, source, assertions); |
| return node; |
| } |
| visitExportSpecifier(node) { |
| const exported = this.visit(node.exported); |
| const local = this.visit(node.local); |
| if (exported !== node.exported || local !== node.local) |
| return new ExportSpecifier(exported, local); |
| return node; |
| } |
| visitExpressionStatement(node) { |
| const expression = this.visit(node.expression); |
| if (expression !== node.expression) |
| return new ExpressionStatement(expression); |
| return node; |
| } |
| visitForStatement(node) { |
| const init = this.visit(node.init); |
| const test = this.visit(node.test); |
| const update = this.visit(node.update); |
| const body = this.visit(node.body); |
| if (init !== node.init || test !== node.test || update !== node.update || body !== node.body) |
| return new ForStatement(init, test, update, body); |
| return node; |
| } |
| visitForOfStatement(node) { |
| const left = this.visit(node.left); |
| const right = this.visit(node.right); |
| const body = this.visit(node.body); |
| if (left !== node.left || right !== node.right || body !== node.body) |
| return new ForOfStatement(left, right, body, node.await); |
| return node; |
| } |
| visitForInStatement(node) { |
| const left = this.visit(node.left); |
| const right = this.visit(node.right); |
| const body = this.visit(node.body); |
| if (left !== node.left || right !== node.right || body !== node.body) |
| return new ForInStatement(left, right, body); |
| return node; |
| } |
| visitFunctionDeclaration(node) { |
| const id = this.visit(node.id); |
| const params = this.visitNodeList(node.params); |
| const body = this.visit(node.body); |
| if (id !== node.id || params !== node.params || body !== node.body) |
| return new FunctionDeclaration(id, params, body, node.generator); |
| return node; |
| } |
| visitFunctionExpression(node) { |
| const id = this.visit(node.id); |
| const params = this.visitNodeList(node.params); |
| const body = this.visit(node.body); |
| if (id !== node.id || params !== node.params || body !== node.body) |
| return new FunctionExpression(id, params, body, node.generator, node.async); |
| return node; |
| } |
| visitIdentifier(node) { |
| return node; |
| } |
| visitIfStatement(node) { |
| const test = this.visit(node.test); |
| const consequent = this.visit(node.consequent); |
| const alternate = this.visit(node.alternate); |
| if (test !== node.test || consequent !== node.consequent || alternate !== node.alternate) |
| return new IfStatement(test, consequent, alternate); |
| return node; |
| } |
| visitImportAttribute(node) { |
| const key = this.visit(node.key); |
| const value = this.visit(node.value); |
| if (key !== node.key || value !== node.value) |
| return new ImportAttribute(key, value); |
| return node; |
| } |
| visitImportExpression(node) { |
| const source = this.visit(node.source); |
| const attributes = this.visit(node.attributes); |
| if (source !== node.source || attributes !== node.attributes) |
| return new ImportExpression(source, attributes); |
| return node; |
| } |
| visitImportDeclaration(node) { |
| const specifiers = this.visitNodeList(node.specifiers); |
| const source = this.visit(node.source); |
| const assertions = this.visitNodeList(node.assertions); |
| if (specifiers !== node.specifiers || source !== node.source || assertions !== node.assertions) |
| return new ImportDeclaration(specifiers, source, assertions); |
| return node; |
| } |
| visitImportDefaultSpecifier(node) { |
| const local = this.visit(node.local); |
| if (local !== node.local) |
| return new ImportDefaultSpecifier(local); |
| return node; |
| } |
| visitImportNamespaceSpecifier(node) { |
| const local = this.visit(node.local); |
| if (local !== node.local) |
| return new ImportNamespaceSpecifier(local); |
| return node; |
| } |
| visitImportSpecifier(node) { |
| const local = this.visit(node.local); |
| const imported = this.visit(node.imported); |
| if (local !== node.local || imported !== node.imported) |
| return new ImportSpecifier(local, imported); |
| return node; |
| } |
| visitLiteral(node) { |
| return node; |
| } |
| visitLabeledStatement(node) { |
| const label = this.visit(node.label); |
| const body = this.visit(node.body); |
| if (label !== node.label || body !== node.body) |
| return new LabeledStatement(label, body); |
| return node; |
| } |
| visitLogicalExpression(node) { |
| const left = this.visit(node.left); |
| const right = this.visit(node.right); |
| if (left !== node.left || right !== node.right) |
| return new LogicalExpression(node.operator, left, right); |
| return node; |
| } |
| visitMemberExpression(node) { |
| const _object = this.visit(node.object); |
| const property = this.visit(node.property); |
| if (_object !== node.object || property !== node.property) |
| return new MemberExpression(node.computed, _object, property, node.optional); |
| return node; |
| } |
| visitMetaProperty(node) { |
| const meta = this.visit(node.meta); |
| const property = this.visit(node.property); |
| if (meta !== node.meta || property !== node.property) |
| return new MetaProperty(meta, property); |
| return node; |
| } |
| visitMethodDefinition(node) { |
| const key = this.visit(node.key); |
| const value = this.visit(node.value); |
| const decorators = this.visitNodeList(node.decorators); |
| if (key !== node.key || value !== node.value || decorators !== node.decorators) |
| return new MethodDefinition(key, node.computed, value, node.kind, node.static, decorators); |
| return node; |
| } |
| visitNewExpression(node) { |
| const callee = this.visit(node.callee); |
| const args = this.visitNodeList(node.arguments); |
| if (callee !== node.callee || args !== node.arguments) |
| return new NewExpression(callee, args); |
| return node; |
| } |
| visitObjectExpression(node) { |
| const properties = this.visitNodeList(node.properties); |
| if (properties !== node.properties) |
| return new ObjectExpression(properties); |
| return node; |
| } |
| visitObjectPattern(node) { |
| const properties = this.visitNodeList(node.properties); |
| if (properties !== node.properties) |
| return new ObjectPattern(properties); |
| return node; |
| } |
| visitProgram(node) { |
| const body = this.visitNodeList(node.body); |
| if (body !== node.body) |
| return new Program(node.sourceType, body); |
| return node; |
| } |
| visitProperty(node) { |
| const key = this.visit(node.key); |
| const value = this.visit(node.value); |
| const decorators = this.visitNodeList(node.decorators); |
| if (key !== node.key || value !== node.value || decorators !== decorators) { |
| if ("kind" in node) |
| return new Property(node.kind, key, node.computed, value, node.method, node.shorthand); |
| else |
| return new PropertyDefinition(key, node.computed, value, node.static, decorators); |
| } |
| return node; |
| } |
| visitPrivateIdentifier(node) { |
| return node; |
| } |
| visitRestElement(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new RestElement(argument); |
| return node; |
| } |
| visitReturnStatement(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new ReturnStatement(argument); |
| return node; |
| } |
| visitSequenceExpression(node) { |
| const expressions = this.visitNodeList(node.expressions); |
| if (expressions !== node.expressions) |
| return new SequenceExpression(expressions); |
| return node; |
| } |
| visitSpreadElement(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new SpreadElement(argument); |
| return node; |
| } |
| visitStaticBlock(node) { |
| const body = this.visitNodeList(node.body); |
| if (body !== node.body) |
| return new StaticBlock(body); |
| return node; |
| } |
| visitSuper(node) { |
| return node; |
| } |
| visitSwitchCase(node) { |
| const test = this.visit(node.test); |
| const consequent = this.visitNodeList(node.consequent); |
| if (test !== node.test || consequent !== node.consequent) |
| return new SwitchCase(test, consequent); |
| return node; |
| } |
| visitSwitchStatement(node) { |
| const discriminant = this.visit(node.discriminant); |
| const cases = this.visitNodeList(node.cases); |
| if (discriminant !== node.discriminant || cases !== node.cases) |
| return new SwitchStatement(discriminant, cases); |
| return node; |
| } |
| visitTaggedTemplateExpression(node) { |
| const tag = this.visit(node.tag); |
| const quasi = this.visit(node.quasi); |
| if (tag !== node.tag || quasi !== node.quasi) |
| return new TaggedTemplateExpression(tag, quasi); |
| return node; |
| } |
| visitTemplateElement(node) { |
| return node; |
| } |
| visitTemplateLiteral(node) { |
| const quasis = this.visitNodeList(node.quasis); |
| const expressions = this.visitNodeList(node.expressions); |
| if (quasis !== node.quasis || expressions !== node.expressions) |
| return new TemplateLiteral(quasis, expressions); |
| return node; |
| } |
| visitThisExpression(node) { |
| return node; |
| } |
| visitThrowStatement(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new ThrowStatement(argument); |
| return node; |
| } |
| visitTryStatement(node) { |
| const block = this.visit(node.block); |
| const handler = this.visit(node.handler); |
| const finalizer = this.visit(node.finalizer); |
| if (block !== node.block || handler !== node.handler || finalizer !== node.finalizer) |
| return new TryStatement(block, handler, finalizer); |
| return node; |
| } |
| visitUnaryExpression(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new UnaryExpression(node.operator, argument); |
| return node; |
| } |
| visitUpdateExpression(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new UpdateExpression(node.operator, argument, node.prefix); |
| return node; |
| } |
| visitVariableDeclaration(node) { |
| const declarations = this.visitNodeList(node.declarations); |
| if (declarations !== node.declarations) |
| return new VariableDeclaration(declarations, node.kind); |
| return node; |
| } |
| visitVariableDeclarator(node) { |
| const id = this.visit(node.id); |
| const init = this.visit(node.init); |
| if (id !== node.id || init !== node.init) |
| return new VariableDeclarator(id, init); |
| return node; |
| } |
| visitWhileStatement(node) { |
| const test = this.visit(node.test); |
| const body = this.visit(node.body); |
| if (test !== node.test || body !== node.body) |
| return new WhileStatement(test, body); |
| return node; |
| } |
| visitWithStatement(node) { |
| const _object = this.visit(node.object); |
| const body = this.visit(node.body); |
| if (_object !== node.object || body !== node.body) |
| return new WithStatement(_object, body); |
| return node; |
| } |
| visitYieldExpression(node) { |
| const argument = this.visit(node.argument); |
| if (argument !== node.argument) |
| return new YieldExpression(argument, node.delegate); |
| return node; |
| } |
| }; |
| |
| // src/esprima.ts |
| function parse(code, options, delegate) { |
| let commentHandler = null; |
| const proxyDelegate = (node, metadata) => { |
| if (delegate) { |
| delegate(node, metadata); |
| } |
| if (commentHandler) { |
| commentHandler.visit(node, metadata); |
| } |
| }; |
| let parserDelegate = typeof delegate === "function" ? proxyDelegate : null; |
| let collectComment = false; |
| if (options) { |
| collectComment = typeof options.comment === "boolean" && options.comment; |
| const attachComment = typeof options.attachComment === "boolean" && options.attachComment; |
| if (collectComment || attachComment) { |
| commentHandler = new CommentHandler(); |
| commentHandler.attach = attachComment; |
| options.comment = true; |
| parserDelegate = proxyDelegate; |
| } |
| } |
| let isModule = false; |
| if (options && typeof options.sourceType === "string") { |
| isModule = options.sourceType === "module"; |
| } |
| let parser; |
| if (options && typeof options.jsx === "boolean" && options.jsx) { |
| parser = new JSXParser(code, options, parserDelegate); |
| } else { |
| parser = new Parser(code, options, parserDelegate); |
| } |
| const program = isModule ? parser.parseModule() : parser.parseScript(); |
| const ast = program; |
| if (collectComment && commentHandler) { |
| ast.comments = commentHandler.comments; |
| } |
| if (parser.config.tokens) { |
| ast.tokens = parser.tokens; |
| } |
| if (parser.config.tolerant) { |
| ast.errors = parser.errorHandler.errors; |
| } |
| return ast; |
| } |
| function parseModule(code, options, delegate) { |
| const parsingOptions = options || {}; |
| parsingOptions.sourceType = "module"; |
| return parse(code, parsingOptions, delegate); |
| } |
| function parseScript(code, options, delegate) { |
| const parsingOptions = options || {}; |
| parsingOptions.sourceType = "script"; |
| return parse(code, parsingOptions, delegate); |
| } |
| function tokenize(code, options, delegate) { |
| const tokenizer = new Tokenizer(code, options); |
| const tokens = []; |
| try { |
| while (true) { |
| let token = tokenizer.getNextToken(); |
| if (!token) { |
| break; |
| } |
| if (delegate) { |
| token = delegate(token); |
| } |
| tokens.push(token); |
| } |
| } catch (e) { |
| tokenizer.errorHandler.tolerate(e); |
| } |
| if (tokenizer.errorHandler.tolerant) { |
| tokens.errors = tokenizer.errors(); |
| } |
| return tokens; |
| } |
| var version = "6.0.3"; |
| var esprima_default = { |
| parse, |
| parseModule, |
| parseScript, |
| tokenize, |
| Syntax, |
| version |
| }; |
| |
| |
| |
| /***/ }) |
| |
| /******/ }); |
| /************************************************************************/ |
| /******/ // The module cache |
| /******/ var __webpack_module_cache__ = {}; |
| /******/ |
| /******/ // The require function |
| /******/ function __webpack_require__(moduleId) { |
| /******/ // Check if module is in cache |
| /******/ var cachedModule = __webpack_module_cache__[moduleId]; |
| /******/ if (cachedModule !== undefined) { |
| /******/ return cachedModule.exports; |
| /******/ } |
| /******/ // Create a new module (and put it into the cache) |
| /******/ var module = __webpack_module_cache__[moduleId] = { |
| /******/ // no module.id needed |
| /******/ // no module.loaded needed |
| /******/ exports: {} |
| /******/ }; |
| /******/ |
| /******/ // Execute the module function |
| /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); |
| /******/ |
| /******/ // Return the exports of the module |
| /******/ return module.exports; |
| /******/ } |
| /******/ |
| /************************************************************************/ |
| /******/ /* webpack/runtime/define property getters */ |
| /******/ (() => { |
| /******/ // define getter functions for harmony exports |
| /******/ __webpack_require__.d = (exports, definition) => { |
| /******/ for(var key in definition) { |
| /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { |
| /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); |
| /******/ } |
| /******/ } |
| /******/ }; |
| /******/ })(); |
| /******/ |
| /******/ /* webpack/runtime/hasOwnProperty shorthand */ |
| /******/ (() => { |
| /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) |
| /******/ })(); |
| /******/ |
| /******/ /* webpack/runtime/make namespace object */ |
| /******/ (() => { |
| /******/ // define __esModule on exports |
| /******/ __webpack_require__.r = (exports) => { |
| /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { |
| /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); |
| /******/ } |
| /******/ Object.defineProperty(exports, '__esModule', { value: true }); |
| /******/ }; |
| /******/ })(); |
| /******/ |
| /************************************************************************/ |
| var __webpack_exports__ = {}; |
| // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. |
| (() => { |
| /*!******************************!*\ |
| !*** ./src/esprima-next.mjs ***! |
| \******************************/ |
| __webpack_require__.r(__webpack_exports__); |
| /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| /* harmony export */ runTest: () => (/* binding */ runTest) |
| /* harmony export */ }); |
| /* harmony import */ var esprima_next__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! esprima-next */ "./node_modules/esprima-next/dist/esprima.js"); |
| // Copyright 2017 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| |
| |
| const payloads = [ |
| "backbone-1.6.1.js", |
| "jquery-3.7.1.js", |
| "mootools-core-1.6.0.js", |
| "underscore-1.13.7.js", |
| ]; |
| |
| function runTest(fileData) { |
| const testData = payloads.map((name) => fileData[name]); |
| |
| return testData.map((payload) => { |
| let count = 0; |
| count += esprima_next__WEBPACK_IMPORTED_MODULE_0__.tokenize(payload, { loc: true, range: true }).length; |
| count += esprima_next__WEBPACK_IMPORTED_MODULE_0__.parse(payload, { loc: true, range: true }).body.length; |
| return count; |
| }); |
| } |
| |
| })(); |
| |
| self.WTBenchmark = __webpack_exports__; |
| /******/ })() |
| ; |