index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.importAttributesOrAssertions = exports.importAttributes = exports.importAssertions = void 0;
  6. var _acorn = _interopRequireWildcard(require("acorn"));
  7. 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); }
  8. 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; }
  9. const leftCurlyBrace = "{".charCodeAt(0);
  10. const space = " ".charCodeAt(0);
  11. const withKeyword = "with";
  12. const assertKeyword = "assert";
  13. const FUNC_STATEMENT = 1,
  14. FUNC_HANGING_STATEMENT = 2,
  15. FUNC_NULLABLE_ID = 4;
  16. const importAttributes = exports.importAttributes = plugin({
  17. keyword: "with"
  18. });
  19. const importAssertions = exports.importAssertions = plugin({
  20. keyword: "assert"
  21. });
  22. const importAttributesOrAssertions = exports.importAttributesOrAssertions = plugin({
  23. keyword: "with-assert"
  24. });
  25. function plugin(options) {
  26. return function (Parser) {
  27. return pluginImpl(options, Parser);
  28. };
  29. }
  30. function pluginImpl(options, Parser) {
  31. // Use supplied version acorn version if present, to avoid
  32. // reference mismatches due to different acorn versions. This
  33. // allows this plugin to be used with Rollup which supplies
  34. // its own internal version of acorn and thereby sidesteps
  35. // the package manager.
  36. const acorn = Parser.acorn || _acorn;
  37. const {
  38. tokTypes: tt,
  39. TokenType
  40. } = acorn;
  41. const {
  42. keyword
  43. } = options;
  44. const isWithKeyword = keyword.includes(withKeyword);
  45. const isAssertKeyword = keyword.includes(assertKeyword);
  46. const isWithOrAssertKeyword = isWithKeyword && isAssertKeyword;
  47. return class extends Parser {
  48. constructor(...args) {
  49. super(...args);
  50. this.withToken = isWithKeyword && new TokenType(withKeyword);
  51. this.assertToken = isAssertKeyword && new TokenType(assertKeyword);
  52. }
  53. _codeAt(i) {
  54. return this.input.charCodeAt(i);
  55. }
  56. _eat(t) {
  57. if (this.type !== t) {
  58. this.unexpected();
  59. }
  60. this.next();
  61. }
  62. _matchKeywordToken() {
  63. return isWithOrAssertKeyword && (this.type === this.withToken || this.type === this.assertToken) || isWithKeyword && this.type === this.withToken || isAssertKeyword && this.type === this.assertToken;
  64. }
  65. _getProperty() {
  66. if (isWithOrAssertKeyword) {
  67. return this.type === this.withToken ? "attributes" : "assertions";
  68. }
  69. return isWithKeyword ? "attributes" : "assertions";
  70. }
  71. readToken(code) {
  72. let i = 0;
  73. let keyword;
  74. let token;
  75. if (isWithOrAssertKeyword) {
  76. if (this.input.slice(this.pos, this.pos + withKeyword.length) === withKeyword) {
  77. keyword = withKeyword;
  78. token = this.withToken;
  79. } else if (this.input.slice(this.pos, this.pos + assertKeyword.length) === assertKeyword) {
  80. keyword = assertKeyword;
  81. token = this.assertToken;
  82. } else {
  83. return super.readToken(code);
  84. }
  85. i += keyword.length;
  86. } else {
  87. keyword = isWithKeyword ? withKeyword : assertKeyword;
  88. token = isWithKeyword ? this.withToken : this.assertToken;
  89. for (; i < keyword.length; i++) {
  90. if (this._codeAt(this.pos + i) !== keyword.charCodeAt(i)) {
  91. return super.readToken(code);
  92. }
  93. }
  94. }
  95. // ensure that the keyword is at the correct location
  96. // ie `with{...` or `with {...`
  97. for (;; i++) {
  98. if (this._codeAt(this.pos + i) === leftCurlyBrace) {
  99. // Found '{'
  100. break;
  101. } else if (this._codeAt(this.pos + i) === space) {
  102. // white space is allowed between `with` and `{`, so continue.
  103. continue;
  104. } else {
  105. return super.readToken(code);
  106. }
  107. }
  108. // If we're inside a dynamic import expression we'll parse
  109. // the `with` keyword as a standard object property name
  110. // ie `import(""./foo.json", { with: { type: "json" } })`
  111. if (this.type.label === "{") {
  112. return super.readToken(code);
  113. }
  114. this.pos += keyword.length;
  115. return this.finishToken(token);
  116. }
  117. parseDynamicImport(node) {
  118. this.next(); // skip `(`
  119. // Parse node.source.
  120. node.source = this.parseMaybeAssign();
  121. if (this.eat(tt.comma)) {
  122. const expr = this.parseExpression();
  123. node.arguments = [expr];
  124. }
  125. this._eat(tt.parenR);
  126. return this.finishNode(node, "ImportExpression");
  127. }
  128. // ported from acorn/src/statement.js pp.parseExport
  129. parseExport(node, exports) {
  130. this.next();
  131. // export * from '...'
  132. if (this.eat(tt.star)) {
  133. if (this.options.ecmaVersion >= 11) {
  134. if (this.eatContextual("as")) {
  135. node.exported = this.parseIdent(true);
  136. this.checkExport(exports, node.exported.name, this.lastTokStart);
  137. } else {
  138. node.exported = null;
  139. }
  140. }
  141. this.expectContextual("from");
  142. if (this.type !== tt.string) {
  143. this.unexpected();
  144. }
  145. node.source = this.parseExprAtom();
  146. if (this._matchKeywordToken()) {
  147. const property = this._getProperty();
  148. this.next();
  149. const attributes = this.parseImportAttributes();
  150. if (attributes) {
  151. node[property] = attributes;
  152. }
  153. }
  154. this.semicolon();
  155. return this.finishNode(node, "ExportAllDeclaration");
  156. }
  157. if (this.eat(tt._default)) {
  158. // export default ...
  159. this.checkExport(exports, "default", this.lastTokStart);
  160. var isAsync;
  161. if (this.type === tt._function || (isAsync = this.isAsyncFunction())) {
  162. var fNode = this.startNode();
  163. this.next();
  164. if (isAsync) {
  165. this.next();
  166. }
  167. node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
  168. } else if (this.type === tt._class) {
  169. var cNode = this.startNode();
  170. node.declaration = this.parseClass(cNode, "nullableID");
  171. } else {
  172. node.declaration = this.parseMaybeAssign();
  173. this.semicolon();
  174. }
  175. return this.finishNode(node, "ExportDefaultDeclaration");
  176. }
  177. // export var|const|let|function|class ...
  178. if (this.shouldParseExportStatement()) {
  179. node.declaration = this.parseStatement(null);
  180. if (node.declaration.type === "VariableDeclaration") {
  181. this.checkVariableExport(exports, node.declaration.declarations);
  182. } else {
  183. this.checkExport(exports, node.declaration.id.name, node.declaration.id.start);
  184. }
  185. node.specifiers = [];
  186. node.source = null;
  187. } else {
  188. // export { x, y as z } [from '...']
  189. node.declaration = null;
  190. node.specifiers = this.parseExportSpecifiers(exports);
  191. if (this.eatContextual("from")) {
  192. if (this.type !== tt.string) {
  193. this.unexpected();
  194. }
  195. node.source = this.parseExprAtom();
  196. if (this._matchKeywordToken()) {
  197. const property = this._getProperty();
  198. this.next();
  199. const attributes = this.parseImportAttributes();
  200. if (attributes) {
  201. node[property] = attributes;
  202. }
  203. }
  204. } else {
  205. for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
  206. // check for keywords used as local names
  207. var spec = list[i];
  208. this.checkUnreserved(spec.local);
  209. // check if export is defined
  210. this.checkLocalExport(spec.local);
  211. }
  212. node.source = null;
  213. }
  214. this.semicolon();
  215. }
  216. return this.finishNode(node, "ExportNamedDeclaration");
  217. }
  218. parseImport(node) {
  219. this.next();
  220. // import '...'
  221. if (this.type === tt.string) {
  222. node.specifiers = [];
  223. node.source = this.parseExprAtom();
  224. } else {
  225. node.specifiers = this.parseImportSpecifiers();
  226. this.expectContextual("from");
  227. node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
  228. }
  229. if (this._matchKeywordToken()) {
  230. const property = this._getProperty();
  231. this.next();
  232. const attributes = this.parseImportAttributes();
  233. if (attributes) {
  234. node[property] = attributes;
  235. }
  236. }
  237. this.semicolon();
  238. return this.finishNode(node, "ImportDeclaration");
  239. }
  240. parseImportAttributes() {
  241. this._eat(tt.braceL);
  242. const attrs = this.parsewithEntries();
  243. this._eat(tt.braceR);
  244. return attrs;
  245. }
  246. parsewithEntries() {
  247. const attrs = [];
  248. const attrNames = new Set();
  249. do {
  250. if (this.type === tt.braceR) {
  251. break;
  252. }
  253. const node = this.startNode();
  254. // parse withionKey : IdentifierName, StringLiteral
  255. let withionKeyNode;
  256. if (this.type === tt.string) {
  257. withionKeyNode = this.parseLiteral(this.value);
  258. } else {
  259. withionKeyNode = this.parseIdent(true);
  260. }
  261. this.next();
  262. node.key = withionKeyNode;
  263. // check if we already have an entry for an attribute
  264. // if a duplicate entry is found, throw an error
  265. // for now this logic will come into play only when someone declares `type` twice
  266. if (attrNames.has(node.key.name)) {
  267. this.raise(this.pos, "Duplicated key in attributes");
  268. }
  269. attrNames.add(node.key.name);
  270. if (this.type !== tt.string) {
  271. this.raise(this.pos, "Only string is supported as an attribute value");
  272. }
  273. node.value = this.parseLiteral(this.value);
  274. attrs.push(this.finishNode(node, "ImportAttribute"));
  275. } while (this.eat(tt.comma));
  276. return attrs;
  277. }
  278. };
  279. }