placeholders.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _types = require("../tokenizer/types");
  7. var _parseError = require("../parse-error");
  8. const PlaceholderErrors = (0, _parseError.ParseErrorEnum)`placeholders`({
  9. ClassNameIsRequired: "A class name is required.",
  10. UnexpectedSpace: "Unexpected space in placeholder."
  11. });
  12. var _default = superClass => class PlaceholdersParserMixin extends superClass {
  13. parsePlaceholder(expectedNode) {
  14. if (this.match(142)) {
  15. const node = this.startNode();
  16. this.next();
  17. this.assertNoSpace();
  18. node.name = super.parseIdentifier(true);
  19. this.assertNoSpace();
  20. this.expect(142);
  21. return this.finishPlaceholder(node, expectedNode);
  22. }
  23. }
  24. finishPlaceholder(node, expectedNode) {
  25. const isFinished = !!(node.expectedNode && node.type === "Placeholder");
  26. node.expectedNode = expectedNode;
  27. return isFinished ? node : this.finishNode(node, "Placeholder");
  28. }
  29. getTokenFromCode(code) {
  30. if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) {
  31. this.finishOp(142, 2);
  32. } else {
  33. super.getTokenFromCode(code);
  34. }
  35. }
  36. parseExprAtom(refExpressionErrors) {
  37. return this.parsePlaceholder("Expression") || super.parseExprAtom(refExpressionErrors);
  38. }
  39. parseIdentifier(liberal) {
  40. return this.parsePlaceholder("Identifier") || super.parseIdentifier(liberal);
  41. }
  42. checkReservedWord(word, startLoc, checkKeywords, isBinding) {
  43. if (word !== undefined) {
  44. super.checkReservedWord(word, startLoc, checkKeywords, isBinding);
  45. }
  46. }
  47. parseBindingAtom() {
  48. return this.parsePlaceholder("Pattern") || super.parseBindingAtom();
  49. }
  50. isValidLVal(type, isParenthesized, binding) {
  51. return type === "Placeholder" || super.isValidLVal(type, isParenthesized, binding);
  52. }
  53. toAssignable(node, isLHS) {
  54. if (node && node.type === "Placeholder" && node.expectedNode === "Expression") {
  55. node.expectedNode = "Pattern";
  56. } else {
  57. super.toAssignable(node, isLHS);
  58. }
  59. }
  60. chStartsBindingIdentifier(ch, pos) {
  61. if (super.chStartsBindingIdentifier(ch, pos)) {
  62. return true;
  63. }
  64. const nextToken = this.lookahead();
  65. if (nextToken.type === 142) {
  66. return true;
  67. }
  68. return false;
  69. }
  70. verifyBreakContinue(node, isBreak) {
  71. if (node.label && node.label.type === "Placeholder") return;
  72. super.verifyBreakContinue(node, isBreak);
  73. }
  74. parseExpressionStatement(node, expr) {
  75. if (expr.type !== "Placeholder" || expr.extra && expr.extra.parenthesized) {
  76. return super.parseExpressionStatement(node, expr);
  77. }
  78. if (this.match(14)) {
  79. const stmt = node;
  80. stmt.label = this.finishPlaceholder(expr, "Identifier");
  81. this.next();
  82. stmt.body = super.parseStatementOrSloppyAnnexBFunctionDeclaration();
  83. return this.finishNode(stmt, "LabeledStatement");
  84. }
  85. this.semicolon();
  86. node.name = expr.name;
  87. return this.finishPlaceholder(node, "Statement");
  88. }
  89. parseBlock(allowDirectives, createNewLexicalScope, afterBlockParse) {
  90. return this.parsePlaceholder("BlockStatement") || super.parseBlock(allowDirectives, createNewLexicalScope, afterBlockParse);
  91. }
  92. parseFunctionId(requireId) {
  93. return this.parsePlaceholder("Identifier") || super.parseFunctionId(requireId);
  94. }
  95. parseClass(node, isStatement, optionalId) {
  96. const type = isStatement ? "ClassDeclaration" : "ClassExpression";
  97. this.next();
  98. const oldStrict = this.state.strict;
  99. const placeholder = this.parsePlaceholder("Identifier");
  100. if (placeholder) {
  101. if (this.match(81) || this.match(142) || this.match(5)) {
  102. node.id = placeholder;
  103. } else if (optionalId || !isStatement) {
  104. node.id = null;
  105. node.body = this.finishPlaceholder(placeholder, "ClassBody");
  106. return this.finishNode(node, type);
  107. } else {
  108. throw this.raise(PlaceholderErrors.ClassNameIsRequired, {
  109. at: this.state.startLoc
  110. });
  111. }
  112. } else {
  113. this.parseClassId(node, isStatement, optionalId);
  114. }
  115. super.parseClassSuper(node);
  116. node.body = this.parsePlaceholder("ClassBody") || super.parseClassBody(!!node.superClass, oldStrict);
  117. return this.finishNode(node, type);
  118. }
  119. parseExport(node, decorators) {
  120. const placeholder = this.parsePlaceholder("Identifier");
  121. if (!placeholder) return super.parseExport(node, decorators);
  122. if (!this.isContextual(97) && !this.match(12)) {
  123. node.specifiers = [];
  124. node.source = null;
  125. node.declaration = this.finishPlaceholder(placeholder, "Declaration");
  126. return this.finishNode(node, "ExportNamedDeclaration");
  127. }
  128. this.expectPlugin("exportDefaultFrom");
  129. const specifier = this.startNode();
  130. specifier.exported = placeholder;
  131. node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
  132. return super.parseExport(node, decorators);
  133. }
  134. isExportDefaultSpecifier() {
  135. if (this.match(65)) {
  136. const next = this.nextTokenStart();
  137. if (this.isUnparsedContextual(next, "from")) {
  138. if (this.input.startsWith((0, _types.tokenLabelName)(142), this.nextTokenStartSince(next + 4))) {
  139. return true;
  140. }
  141. }
  142. }
  143. return super.isExportDefaultSpecifier();
  144. }
  145. maybeParseExportDefaultSpecifier(node, maybeDefaultIdentifier) {
  146. var _specifiers;
  147. if ((_specifiers = node.specifiers) != null && _specifiers.length) {
  148. return true;
  149. }
  150. return super.maybeParseExportDefaultSpecifier(node, maybeDefaultIdentifier);
  151. }
  152. checkExport(node) {
  153. const {
  154. specifiers
  155. } = node;
  156. if (specifiers != null && specifiers.length) {
  157. node.specifiers = specifiers.filter(node => node.exported.type === "Placeholder");
  158. }
  159. super.checkExport(node);
  160. node.specifiers = specifiers;
  161. }
  162. parseImport(node) {
  163. const placeholder = this.parsePlaceholder("Identifier");
  164. if (!placeholder) return super.parseImport(node);
  165. node.specifiers = [];
  166. if (!this.isContextual(97) && !this.match(12)) {
  167. node.source = this.finishPlaceholder(placeholder, "StringLiteral");
  168. this.semicolon();
  169. return this.finishNode(node, "ImportDeclaration");
  170. }
  171. const specifier = this.startNodeAtNode(placeholder);
  172. specifier.local = placeholder;
  173. node.specifiers.push(this.finishNode(specifier, "ImportDefaultSpecifier"));
  174. if (this.eat(12)) {
  175. const hasStarImport = this.maybeParseStarImportSpecifier(node);
  176. if (!hasStarImport) this.parseNamedImportSpecifiers(node);
  177. }
  178. this.expectContextual(97);
  179. node.source = this.parseImportSource();
  180. this.semicolon();
  181. return this.finishNode(node, "ImportDeclaration");
  182. }
  183. parseImportSource() {
  184. return this.parsePlaceholder("StringLiteral") || super.parseImportSource();
  185. }
  186. assertNoSpace() {
  187. if (this.state.start > this.state.lastTokEndLoc.index) {
  188. this.raise(PlaceholderErrors.UnexpectedSpace, {
  189. at: this.state.lastTokEndLoc
  190. });
  191. }
  192. }
  193. };
  194. exports.default = _default;
  195. //# sourceMappingURL=placeholders.js.map