diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
| commit | efbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch) | |
| tree | 2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/acorn-import-attributes | |
| parent | 43acceb75957c880a5ba5a31aae221394a36d5f6 (diff) | |
node fixes, updates
Diffstat (limited to 'node_modules/acorn-import-attributes')
| -rw-r--r-- | node_modules/acorn-import-attributes/LICENSE | 21 | ||||
| -rw-r--r-- | node_modules/acorn-import-attributes/README.md | 21 | ||||
| -rw-r--r-- | node_modules/acorn-import-attributes/lib/index.js | 286 | ||||
| -rw-r--r-- | node_modules/acorn-import-attributes/lib/index.mjs | 291 | ||||
| -rw-r--r-- | node_modules/acorn-import-attributes/package.json | 49 | ||||
| -rw-r--r-- | node_modules/acorn-import-attributes/src/index.js | 291 |
6 files changed, 959 insertions, 0 deletions
diff --git a/node_modules/acorn-import-attributes/LICENSE b/node_modules/acorn-import-attributes/LICENSE new file mode 100644 index 00000000..ed4a7f19 --- /dev/null +++ b/node_modules/acorn-import-attributes/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Sven Sauleau + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/acorn-import-attributes/README.md b/node_modules/acorn-import-attributes/README.md new file mode 100644 index 00000000..2ad8e725 --- /dev/null +++ b/node_modules/acorn-import-attributes/README.md @@ -0,0 +1,21 @@ +# Support for import attributes in acorn + +## Install + +``` +yarn add acorn-import-attributes +``` + +## Usage + +This module provides a plugin that can be used to extend the Acorn Parser class: + +```js +const {Parser} = require('acorn'); +const {importAttributes} = require('acorn-import-attributes'); +Parser.extend(importAttributes).parse('...'); +``` + +## License + +This plugin is released under an MIT License. diff --git a/node_modules/acorn-import-attributes/lib/index.js b/node_modules/acorn-import-attributes/lib/index.js new file mode 100644 index 00000000..4331dcff --- /dev/null +++ b/node_modules/acorn-import-attributes/lib/index.js @@ -0,0 +1,286 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.importAttributesOrAssertions = exports.importAttributes = exports.importAssertions = void 0; +var _acorn = _interopRequireWildcard(require("acorn")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } +const leftCurlyBrace = "{".charCodeAt(0); +const space = " ".charCodeAt(0); +const withKeyword = "with"; +const assertKeyword = "assert"; +const FUNC_STATEMENT = 1, + FUNC_HANGING_STATEMENT = 2, + FUNC_NULLABLE_ID = 4; +const importAttributes = exports.importAttributes = plugin({ + keyword: "with" +}); +const importAssertions = exports.importAssertions = plugin({ + keyword: "assert" +}); +const importAttributesOrAssertions = exports.importAttributesOrAssertions = plugin({ + keyword: "with-assert" +}); +function plugin(options) { + return function (Parser) { + return pluginImpl(options, Parser); + }; +} +function pluginImpl(options, Parser) { + // Use supplied version acorn version if present, to avoid + // reference mismatches due to different acorn versions. This + // allows this plugin to be used with Rollup which supplies + // its own internal version of acorn and thereby sidesteps + // the package manager. + const acorn = Parser.acorn || _acorn; + const { + tokTypes: tt, + TokenType + } = acorn; + const { + keyword + } = options; + const isWithKeyword = keyword.includes(withKeyword); + const isAssertKeyword = keyword.includes(assertKeyword); + const isWithOrAssertKeyword = isWithKeyword && isAssertKeyword; + return class extends Parser { + constructor(...args) { + super(...args); + this.withToken = isWithKeyword && new TokenType(withKeyword); + this.assertToken = isAssertKeyword && new TokenType(assertKeyword); + } + _codeAt(i) { + return this.input.charCodeAt(i); + } + _eat(t) { + if (this.type !== t) { + this.unexpected(); + } + this.next(); + } + _matchKeywordToken() { + return isWithOrAssertKeyword && (this.type === this.withToken || this.type === this.assertToken) || isWithKeyword && this.type === this.withToken || isAssertKeyword && this.type === this.assertToken; + } + _getProperty() { + if (isWithOrAssertKeyword) { + return this.type === this.withToken ? "attributes" : "assertions"; + } + return isWithKeyword ? "attributes" : "assertions"; + } + readToken(code) { + let i = 0; + let keyword; + let token; + if (isWithOrAssertKeyword) { + if (this.input.slice(this.pos, this.pos + withKeyword.length) === withKeyword) { + keyword = withKeyword; + token = this.withToken; + } else if (this.input.slice(this.pos, this.pos + assertKeyword.length) === assertKeyword) { + keyword = assertKeyword; + token = this.assertToken; + } else { + return super.readToken(code); + } + i += keyword.length; + } else { + keyword = isWithKeyword ? withKeyword : assertKeyword; + token = isWithKeyword ? this.withToken : this.assertToken; + for (; i < keyword.length; i++) { + if (this._codeAt(this.pos + i) !== keyword.charCodeAt(i)) { + return super.readToken(code); + } + } + } + + // ensure that the keyword is at the correct location + // ie `with{...` or `with {...` + for (;; i++) { + if (this._codeAt(this.pos + i) === leftCurlyBrace) { + // Found '{' + break; + } else if (this._codeAt(this.pos + i) === space) { + // white space is allowed between `with` and `{`, so continue. + continue; + } else { + return super.readToken(code); + } + } + + // If we're inside a dynamic import expression we'll parse + // the `with` keyword as a standard object property name + // ie `import(""./foo.json", { with: { type: "json" } })` + if (this.type.label === "{") { + return super.readToken(code); + } + this.pos += keyword.length; + return this.finishToken(token); + } + parseDynamicImport(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + if (this.eat(tt.comma)) { + const expr = this.parseExpression(); + node.arguments = [expr]; + } + this._eat(tt.parenR); + return this.finishNode(node, "ImportExpression"); + } + + // ported from acorn/src/statement.js pp.parseExport + parseExport(node, exports) { + this.next(); + // export * from '...' + if (this.eat(tt.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== tt.string) { + this.unexpected(); + } + node.source = this.parseExprAtom(); + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration"); + } + if (this.eat(tt._default)) { + // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === tt._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { + this.next(); + } + node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); + } else if (this.type === tt._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration"); + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + if (node.declaration.type === "VariableDeclaration") { + this.checkVariableExport(exports, node.declaration.declarations); + } else { + this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); + } + node.specifiers = []; + node.source = null; + } else { + // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== tt.string) { + this.unexpected(); + } + node.source = this.parseExprAtom(); + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + } + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration"); + } + parseImport(node) { + this.next(); + // import '...' + if (this.type === tt.string) { + node.specifiers = []; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected(); + } + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + parseImportAttributes() { + this._eat(tt.braceL); + const attrs = this.parsewithEntries(); + this._eat(tt.braceR); + return attrs; + } + parsewithEntries() { + const attrs = []; + const attrNames = new Set(); + do { + if (this.type === tt.braceR) { + break; + } + const node = this.startNode(); + + // parse withionKey : IdentifierName, StringLiteral + let withionKeyNode; + if (this.type === tt.string) { + withionKeyNode = this.parseLiteral(this.value); + } else { + withionKeyNode = this.parseIdent(true); + } + this.next(); + node.key = withionKeyNode; + + // check if we already have an entry for an attribute + // if a duplicate entry is found, throw an error + // for now this logic will come into play only when someone declares `type` twice + if (attrNames.has(node.key.name)) { + this.raise(this.pos, "Duplicated key in attributes"); + } + attrNames.add(node.key.name); + if (this.type !== tt.string) { + this.raise(this.pos, "Only string is supported as an attribute value"); + } + node.value = this.parseLiteral(this.value); + attrs.push(this.finishNode(node, "ImportAttribute")); + } while (this.eat(tt.comma)); + return attrs; + } + }; +}
\ No newline at end of file diff --git a/node_modules/acorn-import-attributes/lib/index.mjs b/node_modules/acorn-import-attributes/lib/index.mjs new file mode 100644 index 00000000..b39dfd0c --- /dev/null +++ b/node_modules/acorn-import-attributes/lib/index.mjs @@ -0,0 +1,291 @@ +import * as _acorn from "acorn"; + +const leftCurlyBrace = "{".charCodeAt(0); +const space = " ".charCodeAt(0); + +const withKeyword = "with"; +const assertKeyword = "assert"; +const FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4 + +export const importAttributes = plugin({ keyword: "with" }); +export const importAssertions = plugin({ keyword: "assert" }); +export const importAttributesOrAssertions = plugin({ keyword: "with-assert" }) + +function plugin(options) { + return function(Parser) { + return pluginImpl(options, Parser); + }; +} + +function pluginImpl(options, Parser) { + // Use supplied version acorn version if present, to avoid + // reference mismatches due to different acorn versions. This + // allows this plugin to be used with Rollup which supplies + // its own internal version of acorn and thereby sidesteps + // the package manager. + const acorn = Parser.acorn || _acorn; + const { tokTypes: tt, TokenType } = acorn; + const { keyword } = options; + const isWithKeyword = keyword.includes(withKeyword); + const isAssertKeyword = keyword.includes(assertKeyword); + const isWithOrAssertKeyword = isWithKeyword && isAssertKeyword; + + return class extends Parser { + constructor(...args) { + super(...args); + this.withToken = isWithKeyword && new TokenType(withKeyword); + this.assertToken = isAssertKeyword && new TokenType(assertKeyword); + } + + _codeAt(i) { + return this.input.charCodeAt(i); + } + + _eat(t) { + if (this.type !== t) { + this.unexpected(); + } + this.next(); + } + + _matchKeywordToken() { + return (isWithOrAssertKeyword && (this.type === this.withToken || this.type === this.assertToken)) + || (isWithKeyword && this.type === this.withToken) + || (isAssertKeyword && this.type === this.assertToken) + } + + _getProperty() { + if (isWithOrAssertKeyword) { + return this.type === this.withToken ? "attributes" : "assertions"; + } + return isWithKeyword ? "attributes" : "assertions"; + } + + readToken(code) { + let i = 0; + let keyword; + let token; + if (isWithOrAssertKeyword) { + if (this.input.slice(this.pos, this.pos + withKeyword.length) === withKeyword) { + keyword = withKeyword; + token = this.withToken; + } else if (this.input.slice(this.pos, this.pos + assertKeyword.length) === assertKeyword) { + keyword = assertKeyword; + token = this.assertToken; + } else { + return super.readToken(code); + } + i += keyword.length; + } else { + keyword = isWithKeyword ? withKeyword : assertKeyword; + token = isWithKeyword ? this.withToken : this.assertToken; + for (; i < keyword.length; i++) { + if (this._codeAt(this.pos + i) !== keyword.charCodeAt(i)) { + return super.readToken(code); + } + } + } + + // ensure that the keyword is at the correct location + // ie `with{...` or `with {...` + for (;; i++) { + if (this._codeAt(this.pos + i) === leftCurlyBrace) { + // Found '{' + break; + } else if (this._codeAt(this.pos + i) === space) { + // white space is allowed between `with` and `{`, so continue. + continue; + } else { + return super.readToken(code); + } + } + + // If we're inside a dynamic import expression we'll parse + // the `with` keyword as a standard object property name + // ie `import(""./foo.json", { with: { type: "json" } })` + if (this.type.label === "{") { + return super.readToken(code); + } + + this.pos += keyword.length; + return this.finishToken(token); + } + + parseDynamicImport(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + if (this.eat(tt.comma)) { + const expr = this.parseExpression(); + node.arguments = [expr]; + } + this._eat(tt.parenR); + return this.finishNode(node, "ImportExpression"); + } + + // ported from acorn/src/statement.js pp.parseExport + parseExport(node, exports) { + this.next(); + // export * from '...' + if (this.eat(tt.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== tt.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === tt._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); + } else if (this.type === tt._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== tt.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + } + + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + } + + parseImport(node) { + this.next(); + // import '...' + if (this.type === tt.string) { + node.specifiers = []; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = + this.type === tt.string ? this.parseExprAtom() : this.unexpected(); + } + + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + parseImportAttributes() { + this._eat(tt.braceL); + const attrs = this.parsewithEntries(); + this._eat(tt.braceR); + return attrs; + } + + parsewithEntries() { + const attrs = []; + const attrNames = new Set(); + + do { + if (this.type === tt.braceR) { + break; + } + + const node = this.startNode(); + + // parse withionKey : IdentifierName, StringLiteral + let withionKeyNode; + if (this.type === tt.string) { + withionKeyNode = this.parseLiteral(this.value); + } else { + withionKeyNode = this.parseIdent(true); + } + this.next(); + node.key = withionKeyNode; + + // check if we already have an entry for an attribute + // if a duplicate entry is found, throw an error + // for now this logic will come into play only when someone declares `type` twice + if (attrNames.has(node.key.name)) { + this.raise(this.pos, "Duplicated key in attributes"); + } + attrNames.add(node.key.name); + + if (this.type !== tt.string) { + this.raise( + this.pos, + "Only string is supported as an attribute value" + ); + } + + node.value = this.parseLiteral(this.value); + + attrs.push(this.finishNode(node, "ImportAttribute")); + } while (this.eat(tt.comma)); + + return attrs; + } + }; +} diff --git a/node_modules/acorn-import-attributes/package.json b/node_modules/acorn-import-attributes/package.json new file mode 100644 index 00000000..4fdf3f14 --- /dev/null +++ b/node_modules/acorn-import-attributes/package.json @@ -0,0 +1,49 @@ +{ + "name": "acorn-import-attributes", + "version": "1.9.5", + "description": "Support for import attributes in acorn", + "main": "lib/index.js", + "module": "src/index.js", + "exports": { + ".": { + "import": "./lib/index.mjs", + "require": "./lib/index.js" + }, + "./package.json": "./package.json", + "./": "./" + }, + "scripts": { + "build": "babel ./src --out-dir ./lib && node post-build.js", + "prepublishOnly": "npm run build", + "test": "mocha ./test/index.js", + "test:test262": "node run_test262.js", + "watch": "babel ./src --out-dir ./lib --watch" + }, + "author": "Sven Sauleau <sven@sauleau.com>", + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.14.8", + "@babel/core": "^7.15.0", + "@babel/preset-env": "^7.15.0", + "@babel/register": "^7.15.3", + "acorn": "^8.4.1", + "chai": "^4.3.4", + "mocha": "^9.1.0", + "test262": "https://github.com/tc39/test262#47ab262658cd97ae35c9a537808cac18fa4ab567", + "test262-parser-runner": "^0.5.0" + }, + "peerDependencies": { + "acorn": "^8" + }, + "repository": { + "type": "git", + "url": "https://github.com/xtuc/acorn-import-attributes" + }, + "browserslist": [ + "maintained node versions" + ], + "files": [ + "lib", + "src" + ] +} diff --git a/node_modules/acorn-import-attributes/src/index.js b/node_modules/acorn-import-attributes/src/index.js new file mode 100644 index 00000000..b39dfd0c --- /dev/null +++ b/node_modules/acorn-import-attributes/src/index.js @@ -0,0 +1,291 @@ +import * as _acorn from "acorn"; + +const leftCurlyBrace = "{".charCodeAt(0); +const space = " ".charCodeAt(0); + +const withKeyword = "with"; +const assertKeyword = "assert"; +const FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4 + +export const importAttributes = plugin({ keyword: "with" }); +export const importAssertions = plugin({ keyword: "assert" }); +export const importAttributesOrAssertions = plugin({ keyword: "with-assert" }) + +function plugin(options) { + return function(Parser) { + return pluginImpl(options, Parser); + }; +} + +function pluginImpl(options, Parser) { + // Use supplied version acorn version if present, to avoid + // reference mismatches due to different acorn versions. This + // allows this plugin to be used with Rollup which supplies + // its own internal version of acorn and thereby sidesteps + // the package manager. + const acorn = Parser.acorn || _acorn; + const { tokTypes: tt, TokenType } = acorn; + const { keyword } = options; + const isWithKeyword = keyword.includes(withKeyword); + const isAssertKeyword = keyword.includes(assertKeyword); + const isWithOrAssertKeyword = isWithKeyword && isAssertKeyword; + + return class extends Parser { + constructor(...args) { + super(...args); + this.withToken = isWithKeyword && new TokenType(withKeyword); + this.assertToken = isAssertKeyword && new TokenType(assertKeyword); + } + + _codeAt(i) { + return this.input.charCodeAt(i); + } + + _eat(t) { + if (this.type !== t) { + this.unexpected(); + } + this.next(); + } + + _matchKeywordToken() { + return (isWithOrAssertKeyword && (this.type === this.withToken || this.type === this.assertToken)) + || (isWithKeyword && this.type === this.withToken) + || (isAssertKeyword && this.type === this.assertToken) + } + + _getProperty() { + if (isWithOrAssertKeyword) { + return this.type === this.withToken ? "attributes" : "assertions"; + } + return isWithKeyword ? "attributes" : "assertions"; + } + + readToken(code) { + let i = 0; + let keyword; + let token; + if (isWithOrAssertKeyword) { + if (this.input.slice(this.pos, this.pos + withKeyword.length) === withKeyword) { + keyword = withKeyword; + token = this.withToken; + } else if (this.input.slice(this.pos, this.pos + assertKeyword.length) === assertKeyword) { + keyword = assertKeyword; + token = this.assertToken; + } else { + return super.readToken(code); + } + i += keyword.length; + } else { + keyword = isWithKeyword ? withKeyword : assertKeyword; + token = isWithKeyword ? this.withToken : this.assertToken; + for (; i < keyword.length; i++) { + if (this._codeAt(this.pos + i) !== keyword.charCodeAt(i)) { + return super.readToken(code); + } + } + } + + // ensure that the keyword is at the correct location + // ie `with{...` or `with {...` + for (;; i++) { + if (this._codeAt(this.pos + i) === leftCurlyBrace) { + // Found '{' + break; + } else if (this._codeAt(this.pos + i) === space) { + // white space is allowed between `with` and `{`, so continue. + continue; + } else { + return super.readToken(code); + } + } + + // If we're inside a dynamic import expression we'll parse + // the `with` keyword as a standard object property name + // ie `import(""./foo.json", { with: { type: "json" } })` + if (this.type.label === "{") { + return super.readToken(code); + } + + this.pos += keyword.length; + return this.finishToken(token); + } + + parseDynamicImport(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + if (this.eat(tt.comma)) { + const expr = this.parseExpression(); + node.arguments = [expr]; + } + this._eat(tt.parenR); + return this.finishNode(node, "ImportExpression"); + } + + // ported from acorn/src/statement.js pp.parseExport + parseExport(node, exports) { + this.next(); + // export * from '...' + if (this.eat(tt.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== tt.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === tt._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); + } else if (this.type === tt._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== tt.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + } + + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + } + + parseImport(node) { + this.next(); + // import '...' + if (this.type === tt.string) { + node.specifiers = []; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = + this.type === tt.string ? this.parseExprAtom() : this.unexpected(); + } + + if (this._matchKeywordToken()) { + const property = this._getProperty(); + this.next(); + const attributes = this.parseImportAttributes(); + if (attributes) { + node[property] = attributes; + } + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + parseImportAttributes() { + this._eat(tt.braceL); + const attrs = this.parsewithEntries(); + this._eat(tt.braceR); + return attrs; + } + + parsewithEntries() { + const attrs = []; + const attrNames = new Set(); + + do { + if (this.type === tt.braceR) { + break; + } + + const node = this.startNode(); + + // parse withionKey : IdentifierName, StringLiteral + let withionKeyNode; + if (this.type === tt.string) { + withionKeyNode = this.parseLiteral(this.value); + } else { + withionKeyNode = this.parseIdent(true); + } + this.next(); + node.key = withionKeyNode; + + // check if we already have an entry for an attribute + // if a duplicate entry is found, throw an error + // for now this logic will come into play only when someone declares `type` twice + if (attrNames.has(node.key.name)) { + this.raise(this.pos, "Duplicated key in attributes"); + } + attrNames.add(node.key.name); + + if (this.type !== tt.string) { + this.raise( + this.pos, + "Only string is supported as an attribute value" + ); + } + + node.value = this.parseLiteral(this.value); + + attrs.push(this.finishNode(node, "ImportAttribute")); + } while (this.eat(tt.comma)); + + return attrs; + } + }; +} |
