index.js 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = exports.Token = void 0;
  6. var N = _interopRequireWildcard(require("../types"));
  7. var _identifier = require("../util/identifier");
  8. var _types2 = require("./types");
  9. var _context = require("./context");
  10. var _location = _interopRequireDefault(require("../parser/location"));
  11. var _location2 = require("../util/location");
  12. var _whitespace = require("../util/whitespace");
  13. var _state = _interopRequireDefault(require("./state"));
  14. var _isDigit = function isDigit(code) {
  15. return code >= 48 && code <= 57;
  16. };
  17. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  18. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
  19. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  20. const VALID_REGEX_FLAGS = new Set(["g", "m", "s", "i", "y", "u"]);
  21. const forbiddenNumericSeparatorSiblings = {
  22. decBinOct: [46, 66, 69, 79, 95, 98, 101, 111],
  23. hex: [46, 88, 95, 120]
  24. };
  25. const allowedNumericSeparatorSiblings = {};
  26. allowedNumericSeparatorSiblings.bin = [48, 49];
  27. allowedNumericSeparatorSiblings.oct = [...allowedNumericSeparatorSiblings.bin, 50, 51, 52, 53, 54, 55];
  28. allowedNumericSeparatorSiblings.dec = [...allowedNumericSeparatorSiblings.oct, 56, 57];
  29. allowedNumericSeparatorSiblings.hex = [...allowedNumericSeparatorSiblings.dec, 65, 66, 67, 68, 69, 70, 97, 98, 99, 100, 101, 102];
  30. class Token {
  31. constructor(state) {
  32. this.type = state.type;
  33. this.value = state.value;
  34. this.start = state.start;
  35. this.end = state.end;
  36. this.loc = new _location2.SourceLocation(state.startLoc, state.endLoc);
  37. }
  38. }
  39. exports.Token = Token;
  40. class Tokenizer extends _location.default {
  41. constructor(options, input) {
  42. super();
  43. this.tokens = [];
  44. this.state = new _state.default();
  45. this.state.init(options);
  46. this.input = input;
  47. this.length = input.length;
  48. this.isLookahead = false;
  49. }
  50. pushToken(token) {
  51. this.tokens.length = this.state.tokensLength;
  52. this.tokens.push(token);
  53. ++this.state.tokensLength;
  54. }
  55. next() {
  56. if (!this.isLookahead) {
  57. this.checkKeywordEscapes();
  58. if (this.options.tokens) {
  59. this.pushToken(new Token(this.state));
  60. }
  61. }
  62. this.state.lastTokEnd = this.state.end;
  63. this.state.lastTokStart = this.state.start;
  64. this.state.lastTokEndLoc = this.state.endLoc;
  65. this.state.lastTokStartLoc = this.state.startLoc;
  66. this.nextToken();
  67. }
  68. eat(type) {
  69. if (this.match(type)) {
  70. this.next();
  71. return true;
  72. } else {
  73. return false;
  74. }
  75. }
  76. match(type) {
  77. return this.state.type === type;
  78. }
  79. lookahead() {
  80. const old = this.state;
  81. this.state = old.clone(true);
  82. this.isLookahead = true;
  83. this.next();
  84. this.isLookahead = false;
  85. const curr = this.state;
  86. this.state = old;
  87. return curr;
  88. }
  89. nextTokenStart() {
  90. const thisTokEnd = this.state.pos;
  91. _whitespace.skipWhiteSpace.lastIndex = thisTokEnd;
  92. const skip = _whitespace.skipWhiteSpace.exec(this.input);
  93. return thisTokEnd + skip[0].length;
  94. }
  95. lookaheadCharCode() {
  96. return this.input.charCodeAt(this.nextTokenStart());
  97. }
  98. setStrict(strict) {
  99. this.state.strict = strict;
  100. if (!this.match(_types2.types.num) && !this.match(_types2.types.string)) return;
  101. this.state.pos = this.state.start;
  102. while (this.state.pos < this.state.lineStart) {
  103. this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1;
  104. --this.state.curLine;
  105. }
  106. this.nextToken();
  107. }
  108. curContext() {
  109. return this.state.context[this.state.context.length - 1];
  110. }
  111. nextToken() {
  112. const curContext = this.curContext();
  113. if (!curContext || !curContext.preserveSpace) this.skipSpace();
  114. this.state.containsOctal = false;
  115. this.state.octalPosition = null;
  116. this.state.start = this.state.pos;
  117. this.state.startLoc = this.state.curPosition();
  118. if (this.state.pos >= this.length) {
  119. this.finishToken(_types2.types.eof);
  120. return;
  121. }
  122. if (curContext.override) {
  123. curContext.override(this);
  124. } else {
  125. this.getTokenFromCode(this.input.codePointAt(this.state.pos));
  126. }
  127. }
  128. pushComment(block, text, start, end, startLoc, endLoc) {
  129. const comment = {
  130. type: block ? "CommentBlock" : "CommentLine",
  131. value: text,
  132. start: start,
  133. end: end,
  134. loc: new _location2.SourceLocation(startLoc, endLoc)
  135. };
  136. if (this.options.tokens) this.pushToken(comment);
  137. this.state.comments.push(comment);
  138. this.addComment(comment);
  139. }
  140. skipBlockComment() {
  141. const startLoc = this.state.curPosition();
  142. const start = this.state.pos;
  143. const end = this.input.indexOf("*/", this.state.pos + 2);
  144. if (end === -1) throw this.raise(start, "Unterminated comment");
  145. this.state.pos = end + 2;
  146. _whitespace.lineBreakG.lastIndex = start;
  147. let match;
  148. while ((match = _whitespace.lineBreakG.exec(this.input)) && match.index < this.state.pos) {
  149. ++this.state.curLine;
  150. this.state.lineStart = match.index + match[0].length;
  151. }
  152. if (this.isLookahead) return;
  153. this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition());
  154. }
  155. skipLineComment(startSkip) {
  156. const start = this.state.pos;
  157. const startLoc = this.state.curPosition();
  158. let ch = this.input.charCodeAt(this.state.pos += startSkip);
  159. if (this.state.pos < this.length) {
  160. while (!(0, _whitespace.isNewLine)(ch) && ++this.state.pos < this.length) {
  161. ch = this.input.charCodeAt(this.state.pos);
  162. }
  163. }
  164. if (this.isLookahead) return;
  165. this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition());
  166. }
  167. skipSpace() {
  168. loop: while (this.state.pos < this.length) {
  169. const ch = this.input.charCodeAt(this.state.pos);
  170. switch (ch) {
  171. case 32:
  172. case 160:
  173. case 9:
  174. ++this.state.pos;
  175. break;
  176. case 13:
  177. if (this.input.charCodeAt(this.state.pos + 1) === 10) {
  178. ++this.state.pos;
  179. }
  180. case 10:
  181. case 8232:
  182. case 8233:
  183. ++this.state.pos;
  184. ++this.state.curLine;
  185. this.state.lineStart = this.state.pos;
  186. break;
  187. case 47:
  188. switch (this.input.charCodeAt(this.state.pos + 1)) {
  189. case 42:
  190. this.skipBlockComment();
  191. break;
  192. case 47:
  193. this.skipLineComment(2);
  194. break;
  195. default:
  196. break loop;
  197. }
  198. break;
  199. default:
  200. if ((0, _whitespace.isWhitespace)(ch)) {
  201. ++this.state.pos;
  202. } else {
  203. break loop;
  204. }
  205. }
  206. }
  207. }
  208. finishToken(type, val) {
  209. this.state.end = this.state.pos;
  210. this.state.endLoc = this.state.curPosition();
  211. const prevType = this.state.type;
  212. this.state.type = type;
  213. this.state.value = val;
  214. if (!this.isLookahead) this.updateContext(prevType);
  215. }
  216. readToken_numberSign() {
  217. if (this.state.pos === 0 && this.readToken_interpreter()) {
  218. return;
  219. }
  220. const nextPos = this.state.pos + 1;
  221. const next = this.input.charCodeAt(nextPos);
  222. if (next >= 48 && next <= 57) {
  223. throw this.raise(this.state.pos, "Unexpected digit after hash token");
  224. }
  225. if (this.hasPlugin("classPrivateProperties") || this.hasPlugin("classPrivateMethods") || this.getPluginOption("pipelineOperator", "proposal") === "smart") {
  226. this.finishOp(_types2.types.hash, 1);
  227. } else {
  228. throw this.raise(this.state.pos, "Unexpected character '#'");
  229. }
  230. }
  231. readToken_dot() {
  232. const next = this.input.charCodeAt(this.state.pos + 1);
  233. if (next >= 48 && next <= 57) {
  234. this.readNumber(true);
  235. return;
  236. }
  237. if (next === 46 && this.input.charCodeAt(this.state.pos + 2) === 46) {
  238. this.state.pos += 3;
  239. this.finishToken(_types2.types.ellipsis);
  240. } else {
  241. ++this.state.pos;
  242. this.finishToken(_types2.types.dot);
  243. }
  244. }
  245. readToken_slash() {
  246. if (this.state.exprAllowed && !this.state.inType) {
  247. ++this.state.pos;
  248. this.readRegexp();
  249. return;
  250. }
  251. const next = this.input.charCodeAt(this.state.pos + 1);
  252. if (next === 61) {
  253. this.finishOp(_types2.types.assign, 2);
  254. } else {
  255. this.finishOp(_types2.types.slash, 1);
  256. }
  257. }
  258. readToken_interpreter() {
  259. if (this.state.pos !== 0 || this.length < 2) return false;
  260. const start = this.state.pos;
  261. this.state.pos += 1;
  262. let ch = this.input.charCodeAt(this.state.pos);
  263. if (ch !== 33) return false;
  264. while (!(0, _whitespace.isNewLine)(ch) && ++this.state.pos < this.length) {
  265. ch = this.input.charCodeAt(this.state.pos);
  266. }
  267. const value = this.input.slice(start + 2, this.state.pos);
  268. this.finishToken(_types2.types.interpreterDirective, value);
  269. return true;
  270. }
  271. readToken_mult_modulo(code) {
  272. let type = code === 42 ? _types2.types.star : _types2.types.modulo;
  273. let width = 1;
  274. let next = this.input.charCodeAt(this.state.pos + 1);
  275. const exprAllowed = this.state.exprAllowed;
  276. if (code === 42 && next === 42) {
  277. width++;
  278. next = this.input.charCodeAt(this.state.pos + 2);
  279. type = _types2.types.exponent;
  280. }
  281. if (next === 61 && !exprAllowed) {
  282. width++;
  283. type = _types2.types.assign;
  284. }
  285. this.finishOp(type, width);
  286. }
  287. readToken_pipe_amp(code) {
  288. const next = this.input.charCodeAt(this.state.pos + 1);
  289. if (next === code) {
  290. if (this.input.charCodeAt(this.state.pos + 2) === 61) {
  291. this.finishOp(_types2.types.assign, 3);
  292. } else {
  293. this.finishOp(code === 124 ? _types2.types.logicalOR : _types2.types.logicalAND, 2);
  294. }
  295. return;
  296. }
  297. if (code === 124) {
  298. if (next === 62) {
  299. this.finishOp(_types2.types.pipeline, 2);
  300. return;
  301. }
  302. }
  303. if (next === 61) {
  304. this.finishOp(_types2.types.assign, 2);
  305. return;
  306. }
  307. this.finishOp(code === 124 ? _types2.types.bitwiseOR : _types2.types.bitwiseAND, 1);
  308. }
  309. readToken_caret() {
  310. const next = this.input.charCodeAt(this.state.pos + 1);
  311. if (next === 61) {
  312. this.finishOp(_types2.types.assign, 2);
  313. } else {
  314. this.finishOp(_types2.types.bitwiseXOR, 1);
  315. }
  316. }
  317. readToken_plus_min(code) {
  318. const next = this.input.charCodeAt(this.state.pos + 1);
  319. if (next === code) {
  320. if (next === 45 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 62 && (this.state.lastTokEnd === 0 || _whitespace.lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.pos)))) {
  321. this.skipLineComment(3);
  322. this.skipSpace();
  323. this.nextToken();
  324. return;
  325. }
  326. this.finishOp(_types2.types.incDec, 2);
  327. return;
  328. }
  329. if (next === 61) {
  330. this.finishOp(_types2.types.assign, 2);
  331. } else {
  332. this.finishOp(_types2.types.plusMin, 1);
  333. }
  334. }
  335. readToken_lt_gt(code) {
  336. const next = this.input.charCodeAt(this.state.pos + 1);
  337. let size = 1;
  338. if (next === code) {
  339. size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2;
  340. if (this.input.charCodeAt(this.state.pos + size) === 61) {
  341. this.finishOp(_types2.types.assign, size + 1);
  342. return;
  343. }
  344. this.finishOp(_types2.types.bitShift, size);
  345. return;
  346. }
  347. if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) {
  348. this.skipLineComment(4);
  349. this.skipSpace();
  350. this.nextToken();
  351. return;
  352. }
  353. if (next === 61) {
  354. size = 2;
  355. }
  356. this.finishOp(_types2.types.relational, size);
  357. }
  358. readToken_eq_excl(code) {
  359. const next = this.input.charCodeAt(this.state.pos + 1);
  360. if (next === 61) {
  361. this.finishOp(_types2.types.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2);
  362. return;
  363. }
  364. if (code === 61 && next === 62) {
  365. this.state.pos += 2;
  366. this.finishToken(_types2.types.arrow);
  367. return;
  368. }
  369. this.finishOp(code === 61 ? _types2.types.eq : _types2.types.bang, 1);
  370. }
  371. readToken_question() {
  372. const next = this.input.charCodeAt(this.state.pos + 1);
  373. const next2 = this.input.charCodeAt(this.state.pos + 2);
  374. if (next === 63 && !this.state.inType) {
  375. if (next2 === 61) {
  376. this.finishOp(_types2.types.assign, 3);
  377. } else {
  378. this.finishOp(_types2.types.nullishCoalescing, 2);
  379. }
  380. } else if (next === 46 && !(next2 >= 48 && next2 <= 57)) {
  381. this.state.pos += 2;
  382. this.finishToken(_types2.types.questionDot);
  383. } else {
  384. ++this.state.pos;
  385. this.finishToken(_types2.types.question);
  386. }
  387. }
  388. getTokenFromCode(code) {
  389. switch (code) {
  390. case 46:
  391. this.readToken_dot();
  392. return;
  393. case 40:
  394. ++this.state.pos;
  395. this.finishToken(_types2.types.parenL);
  396. return;
  397. case 41:
  398. ++this.state.pos;
  399. this.finishToken(_types2.types.parenR);
  400. return;
  401. case 59:
  402. ++this.state.pos;
  403. this.finishToken(_types2.types.semi);
  404. return;
  405. case 44:
  406. ++this.state.pos;
  407. this.finishToken(_types2.types.comma);
  408. return;
  409. case 91:
  410. ++this.state.pos;
  411. this.finishToken(_types2.types.bracketL);
  412. return;
  413. case 93:
  414. ++this.state.pos;
  415. this.finishToken(_types2.types.bracketR);
  416. return;
  417. case 123:
  418. ++this.state.pos;
  419. this.finishToken(_types2.types.braceL);
  420. return;
  421. case 125:
  422. ++this.state.pos;
  423. this.finishToken(_types2.types.braceR);
  424. return;
  425. case 58:
  426. if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) {
  427. this.finishOp(_types2.types.doubleColon, 2);
  428. } else {
  429. ++this.state.pos;
  430. this.finishToken(_types2.types.colon);
  431. }
  432. return;
  433. case 63:
  434. this.readToken_question();
  435. return;
  436. case 96:
  437. ++this.state.pos;
  438. this.finishToken(_types2.types.backQuote);
  439. return;
  440. case 48:
  441. {
  442. const next = this.input.charCodeAt(this.state.pos + 1);
  443. if (next === 120 || next === 88) {
  444. this.readRadixNumber(16);
  445. return;
  446. }
  447. if (next === 111 || next === 79) {
  448. this.readRadixNumber(8);
  449. return;
  450. }
  451. if (next === 98 || next === 66) {
  452. this.readRadixNumber(2);
  453. return;
  454. }
  455. }
  456. case 49:
  457. case 50:
  458. case 51:
  459. case 52:
  460. case 53:
  461. case 54:
  462. case 55:
  463. case 56:
  464. case 57:
  465. this.readNumber(false);
  466. return;
  467. case 34:
  468. case 39:
  469. this.readString(code);
  470. return;
  471. case 47:
  472. this.readToken_slash();
  473. return;
  474. case 37:
  475. case 42:
  476. this.readToken_mult_modulo(code);
  477. return;
  478. case 124:
  479. case 38:
  480. this.readToken_pipe_amp(code);
  481. return;
  482. case 94:
  483. this.readToken_caret();
  484. return;
  485. case 43:
  486. case 45:
  487. this.readToken_plus_min(code);
  488. return;
  489. case 60:
  490. case 62:
  491. this.readToken_lt_gt(code);
  492. return;
  493. case 61:
  494. case 33:
  495. this.readToken_eq_excl(code);
  496. return;
  497. case 126:
  498. this.finishOp(_types2.types.tilde, 1);
  499. return;
  500. case 64:
  501. ++this.state.pos;
  502. this.finishToken(_types2.types.at);
  503. return;
  504. case 35:
  505. this.readToken_numberSign();
  506. return;
  507. case 92:
  508. this.readWord();
  509. return;
  510. default:
  511. if ((0, _identifier.isIdentifierStart)(code)) {
  512. this.readWord();
  513. return;
  514. }
  515. }
  516. throw this.raise(this.state.pos, `Unexpected character '${String.fromCodePoint(code)}'`);
  517. }
  518. finishOp(type, size) {
  519. const str = this.input.slice(this.state.pos, this.state.pos + size);
  520. this.state.pos += size;
  521. this.finishToken(type, str);
  522. }
  523. readRegexp() {
  524. const start = this.state.pos;
  525. let escaped, inClass;
  526. for (;;) {
  527. if (this.state.pos >= this.length) {
  528. throw this.raise(start, "Unterminated regular expression");
  529. }
  530. const ch = this.input.charAt(this.state.pos);
  531. if (_whitespace.lineBreak.test(ch)) {
  532. throw this.raise(start, "Unterminated regular expression");
  533. }
  534. if (escaped) {
  535. escaped = false;
  536. } else {
  537. if (ch === "[") {
  538. inClass = true;
  539. } else if (ch === "]" && inClass) {
  540. inClass = false;
  541. } else if (ch === "/" && !inClass) {
  542. break;
  543. }
  544. escaped = ch === "\\";
  545. }
  546. ++this.state.pos;
  547. }
  548. const content = this.input.slice(start, this.state.pos);
  549. ++this.state.pos;
  550. let mods = "";
  551. while (this.state.pos < this.length) {
  552. const char = this.input[this.state.pos];
  553. const charCode = this.input.codePointAt(this.state.pos);
  554. if (VALID_REGEX_FLAGS.has(char)) {
  555. if (mods.indexOf(char) > -1) {
  556. this.raise(this.state.pos + 1, "Duplicate regular expression flag");
  557. }
  558. } else if ((0, _identifier.isIdentifierChar)(charCode) || charCode === 92) {
  559. this.raise(this.state.pos + 1, "Invalid regular expression flag");
  560. } else {
  561. break;
  562. }
  563. ++this.state.pos;
  564. mods += char;
  565. }
  566. this.finishToken(_types2.types.regexp, {
  567. pattern: content,
  568. flags: mods
  569. });
  570. }
  571. readInt(radix, len, forceLen, allowNumSeparator = true) {
  572. const start = this.state.pos;
  573. const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct;
  574. const allowedSiblings = radix === 16 ? allowedNumericSeparatorSiblings.hex : radix === 10 ? allowedNumericSeparatorSiblings.dec : radix === 8 ? allowedNumericSeparatorSiblings.oct : allowedNumericSeparatorSiblings.bin;
  575. let invalid = false;
  576. let total = 0;
  577. for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) {
  578. const code = this.input.charCodeAt(this.state.pos);
  579. let val;
  580. if (this.hasPlugin("numericSeparator")) {
  581. if (code === 95) {
  582. const prev = this.input.charCodeAt(this.state.pos - 1);
  583. const next = this.input.charCodeAt(this.state.pos + 1);
  584. if (allowedSiblings.indexOf(next) === -1) {
  585. this.raise(this.state.pos, "A numeric separator is only allowed between two digits");
  586. } else if (forbiddenSiblings.indexOf(prev) > -1 || forbiddenSiblings.indexOf(next) > -1 || Number.isNaN(next)) {
  587. this.raise(this.state.pos, "A numeric separator is only allowed between two digits");
  588. }
  589. if (!allowNumSeparator) {
  590. this.raise(this.state.pos, "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences");
  591. }
  592. ++this.state.pos;
  593. continue;
  594. }
  595. }
  596. if (code >= 97) {
  597. val = code - 97 + 10;
  598. } else if (code >= 65) {
  599. val = code - 65 + 10;
  600. } else if (_isDigit(code)) {
  601. val = code - 48;
  602. } else {
  603. val = Infinity;
  604. }
  605. if (val >= radix) {
  606. if (this.options.errorRecovery && val <= 9) {
  607. val = 0;
  608. this.raise(this.state.start + i + 2, "Expected number in radix " + radix);
  609. } else if (forceLen) {
  610. val = 0;
  611. invalid = true;
  612. } else {
  613. break;
  614. }
  615. }
  616. ++this.state.pos;
  617. total = total * radix + val;
  618. }
  619. if (this.state.pos === start || len != null && this.state.pos - start !== len || invalid) {
  620. return null;
  621. }
  622. return total;
  623. }
  624. readRadixNumber(radix) {
  625. const start = this.state.pos;
  626. let isBigInt = false;
  627. this.state.pos += 2;
  628. const val = this.readInt(radix);
  629. if (val == null) {
  630. this.raise(this.state.start + 2, "Expected number in radix " + radix);
  631. }
  632. if (this.hasPlugin("bigInt")) {
  633. if (this.input.charCodeAt(this.state.pos) === 110) {
  634. ++this.state.pos;
  635. isBigInt = true;
  636. }
  637. }
  638. if ((0, _identifier.isIdentifierStart)(this.input.codePointAt(this.state.pos))) {
  639. throw this.raise(this.state.pos, "Identifier directly after number");
  640. }
  641. if (isBigInt) {
  642. const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, "");
  643. this.finishToken(_types2.types.bigint, str);
  644. return;
  645. }
  646. this.finishToken(_types2.types.num, val);
  647. }
  648. readNumber(startsWithDot) {
  649. const start = this.state.pos;
  650. let isFloat = false;
  651. let isBigInt = false;
  652. let isNonOctalDecimalInt = false;
  653. if (!startsWithDot && this.readInt(10) === null) {
  654. this.raise(start, "Invalid number");
  655. }
  656. let octal = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48;
  657. if (octal) {
  658. if (this.state.strict) {
  659. this.raise(start, "Legacy octal literals are not allowed in strict mode");
  660. }
  661. if (/[89]/.test(this.input.slice(start, this.state.pos))) {
  662. octal = false;
  663. isNonOctalDecimalInt = true;
  664. }
  665. }
  666. let next = this.input.charCodeAt(this.state.pos);
  667. if (next === 46 && !octal) {
  668. ++this.state.pos;
  669. this.readInt(10);
  670. isFloat = true;
  671. next = this.input.charCodeAt(this.state.pos);
  672. }
  673. if ((next === 69 || next === 101) && !octal) {
  674. next = this.input.charCodeAt(++this.state.pos);
  675. if (next === 43 || next === 45) {
  676. ++this.state.pos;
  677. }
  678. if (this.readInt(10) === null) this.raise(start, "Invalid number");
  679. isFloat = true;
  680. next = this.input.charCodeAt(this.state.pos);
  681. }
  682. if (this.hasPlugin("numericSeparator") && (octal || isNonOctalDecimalInt)) {
  683. const underscorePos = this.input.slice(start, this.state.pos).indexOf("_");
  684. if (underscorePos > 0) {
  685. this.raise(underscorePos + start, "Numeric separator can not be used after leading 0");
  686. }
  687. }
  688. if (this.hasPlugin("bigInt")) {
  689. if (next === 110) {
  690. if (isFloat || octal || isNonOctalDecimalInt) {
  691. this.raise(start, "Invalid BigIntLiteral");
  692. }
  693. ++this.state.pos;
  694. isBigInt = true;
  695. }
  696. }
  697. if ((0, _identifier.isIdentifierStart)(this.input.codePointAt(this.state.pos))) {
  698. throw this.raise(this.state.pos, "Identifier directly after number");
  699. }
  700. const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, "");
  701. if (isBigInt) {
  702. this.finishToken(_types2.types.bigint, str);
  703. return;
  704. }
  705. const val = octal ? parseInt(str, 8) : parseFloat(str);
  706. this.finishToken(_types2.types.num, val);
  707. }
  708. readCodePoint(throwOnInvalid) {
  709. const ch = this.input.charCodeAt(this.state.pos);
  710. let code;
  711. if (ch === 123) {
  712. const codePos = ++this.state.pos;
  713. code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, true, throwOnInvalid);
  714. ++this.state.pos;
  715. if (code !== null && code > 0x10ffff) {
  716. if (throwOnInvalid) {
  717. this.raise(codePos, "Code point out of bounds");
  718. } else {
  719. return null;
  720. }
  721. }
  722. } else {
  723. code = this.readHexChar(4, false, throwOnInvalid);
  724. }
  725. return code;
  726. }
  727. readString(quote) {
  728. let out = "",
  729. chunkStart = ++this.state.pos;
  730. for (;;) {
  731. if (this.state.pos >= this.length) {
  732. throw this.raise(this.state.start, "Unterminated string constant");
  733. }
  734. const ch = this.input.charCodeAt(this.state.pos);
  735. if (ch === quote) break;
  736. if (ch === 92) {
  737. out += this.input.slice(chunkStart, this.state.pos);
  738. out += this.readEscapedChar(false);
  739. chunkStart = this.state.pos;
  740. } else if (ch === 8232 || ch === 8233) {
  741. ++this.state.pos;
  742. ++this.state.curLine;
  743. this.state.lineStart = this.state.pos;
  744. } else if ((0, _whitespace.isNewLine)(ch)) {
  745. throw this.raise(this.state.start, "Unterminated string constant");
  746. } else {
  747. ++this.state.pos;
  748. }
  749. }
  750. out += this.input.slice(chunkStart, this.state.pos++);
  751. this.finishToken(_types2.types.string, out);
  752. }
  753. readTmplToken() {
  754. let out = "",
  755. chunkStart = this.state.pos,
  756. containsInvalid = false;
  757. for (;;) {
  758. if (this.state.pos >= this.length) {
  759. throw this.raise(this.state.start, "Unterminated template");
  760. }
  761. const ch = this.input.charCodeAt(this.state.pos);
  762. if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) {
  763. if (this.state.pos === this.state.start && this.match(_types2.types.template)) {
  764. if (ch === 36) {
  765. this.state.pos += 2;
  766. this.finishToken(_types2.types.dollarBraceL);
  767. return;
  768. } else {
  769. ++this.state.pos;
  770. this.finishToken(_types2.types.backQuote);
  771. return;
  772. }
  773. }
  774. out += this.input.slice(chunkStart, this.state.pos);
  775. this.finishToken(_types2.types.template, containsInvalid ? null : out);
  776. return;
  777. }
  778. if (ch === 92) {
  779. out += this.input.slice(chunkStart, this.state.pos);
  780. const escaped = this.readEscapedChar(true);
  781. if (escaped === null) {
  782. containsInvalid = true;
  783. } else {
  784. out += escaped;
  785. }
  786. chunkStart = this.state.pos;
  787. } else if ((0, _whitespace.isNewLine)(ch)) {
  788. out += this.input.slice(chunkStart, this.state.pos);
  789. ++this.state.pos;
  790. switch (ch) {
  791. case 13:
  792. if (this.input.charCodeAt(this.state.pos) === 10) {
  793. ++this.state.pos;
  794. }
  795. case 10:
  796. out += "\n";
  797. break;
  798. default:
  799. out += String.fromCharCode(ch);
  800. break;
  801. }
  802. ++this.state.curLine;
  803. this.state.lineStart = this.state.pos;
  804. chunkStart = this.state.pos;
  805. } else {
  806. ++this.state.pos;
  807. }
  808. }
  809. }
  810. readEscapedChar(inTemplate) {
  811. const throwOnInvalid = !inTemplate;
  812. const ch = this.input.charCodeAt(++this.state.pos);
  813. ++this.state.pos;
  814. switch (ch) {
  815. case 110:
  816. return "\n";
  817. case 114:
  818. return "\r";
  819. case 120:
  820. {
  821. const code = this.readHexChar(2, false, throwOnInvalid);
  822. return code === null ? null : String.fromCharCode(code);
  823. }
  824. case 117:
  825. {
  826. const code = this.readCodePoint(throwOnInvalid);
  827. return code === null ? null : String.fromCodePoint(code);
  828. }
  829. case 116:
  830. return "\t";
  831. case 98:
  832. return "\b";
  833. case 118:
  834. return "\u000b";
  835. case 102:
  836. return "\f";
  837. case 13:
  838. if (this.input.charCodeAt(this.state.pos) === 10) {
  839. ++this.state.pos;
  840. }
  841. case 10:
  842. this.state.lineStart = this.state.pos;
  843. ++this.state.curLine;
  844. case 8232:
  845. case 8233:
  846. return "";
  847. case 56:
  848. case 57:
  849. if (inTemplate) {
  850. return null;
  851. }
  852. default:
  853. if (ch >= 48 && ch <= 55) {
  854. const codePos = this.state.pos - 1;
  855. let octalStr = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/)[0];
  856. let octal = parseInt(octalStr, 8);
  857. if (octal > 255) {
  858. octalStr = octalStr.slice(0, -1);
  859. octal = parseInt(octalStr, 8);
  860. }
  861. this.state.pos += octalStr.length - 1;
  862. const next = this.input.charCodeAt(this.state.pos);
  863. if (octalStr !== "0" || next === 56 || next === 57) {
  864. if (inTemplate) {
  865. return null;
  866. } else if (this.state.strict) {
  867. this.raise(codePos, "Octal literal in strict mode");
  868. } else if (!this.state.containsOctal) {
  869. this.state.containsOctal = true;
  870. this.state.octalPosition = codePos;
  871. }
  872. }
  873. return String.fromCharCode(octal);
  874. }
  875. return String.fromCharCode(ch);
  876. }
  877. }
  878. readHexChar(len, forceLen, throwOnInvalid) {
  879. const codePos = this.state.pos;
  880. const n = this.readInt(16, len, forceLen, false);
  881. if (n === null) {
  882. if (throwOnInvalid) {
  883. this.raise(codePos, "Bad character escape sequence");
  884. } else {
  885. this.state.pos = codePos - 1;
  886. }
  887. }
  888. return n;
  889. }
  890. readWord1() {
  891. let word = "";
  892. this.state.containsEsc = false;
  893. const start = this.state.pos;
  894. let chunkStart = this.state.pos;
  895. while (this.state.pos < this.length) {
  896. const ch = this.input.codePointAt(this.state.pos);
  897. if ((0, _identifier.isIdentifierChar)(ch)) {
  898. this.state.pos += ch <= 0xffff ? 1 : 2;
  899. } else if (this.state.isIterator && ch === 64) {
  900. ++this.state.pos;
  901. } else if (ch === 92) {
  902. this.state.containsEsc = true;
  903. word += this.input.slice(chunkStart, this.state.pos);
  904. const escStart = this.state.pos;
  905. const identifierCheck = this.state.pos === start ? _identifier.isIdentifierStart : _identifier.isIdentifierChar;
  906. if (this.input.charCodeAt(++this.state.pos) !== 117) {
  907. this.raise(this.state.pos, "Expecting Unicode escape sequence \\uXXXX");
  908. continue;
  909. }
  910. ++this.state.pos;
  911. const esc = this.readCodePoint(true);
  912. if (esc !== null) {
  913. if (!identifierCheck(esc)) {
  914. this.raise(escStart, "Invalid Unicode escape");
  915. }
  916. word += String.fromCodePoint(esc);
  917. }
  918. chunkStart = this.state.pos;
  919. } else {
  920. break;
  921. }
  922. }
  923. return word + this.input.slice(chunkStart, this.state.pos);
  924. }
  925. isIterator(word) {
  926. return word === "@@iterator" || word === "@@asyncIterator";
  927. }
  928. readWord() {
  929. const word = this.readWord1();
  930. const type = _types2.keywords.get(word) || _types2.types.name;
  931. if (this.state.isIterator && (!this.isIterator(word) || !this.state.inType)) {
  932. this.raise(this.state.pos, `Invalid identifier ${word}`);
  933. }
  934. this.finishToken(type, word);
  935. }
  936. checkKeywordEscapes() {
  937. const kw = this.state.type.keyword;
  938. if (kw && this.state.containsEsc) {
  939. this.raise(this.state.start, `Escape sequence in keyword ${kw}`);
  940. }
  941. }
  942. braceIsBlock(prevType) {
  943. const parent = this.curContext();
  944. if (parent === _context.types.functionExpression || parent === _context.types.functionStatement) {
  945. return true;
  946. }
  947. if (prevType === _types2.types.colon && (parent === _context.types.braceStatement || parent === _context.types.braceExpression)) {
  948. return !parent.isExpr;
  949. }
  950. if (prevType === _types2.types._return || prevType === _types2.types.name && this.state.exprAllowed) {
  951. return _whitespace.lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start));
  952. }
  953. if (prevType === _types2.types._else || prevType === _types2.types.semi || prevType === _types2.types.eof || prevType === _types2.types.parenR || prevType === _types2.types.arrow) {
  954. return true;
  955. }
  956. if (prevType === _types2.types.braceL) {
  957. return parent === _context.types.braceStatement;
  958. }
  959. if (prevType === _types2.types._var || prevType === _types2.types._const || prevType === _types2.types.name) {
  960. return false;
  961. }
  962. if (prevType === _types2.types.relational) {
  963. return true;
  964. }
  965. return !this.state.exprAllowed;
  966. }
  967. updateContext(prevType) {
  968. const type = this.state.type;
  969. let update;
  970. if (type.keyword && (prevType === _types2.types.dot || prevType === _types2.types.questionDot)) {
  971. this.state.exprAllowed = false;
  972. } else if (update = type.updateContext) {
  973. update.call(this, prevType);
  974. } else {
  975. this.state.exprAllowed = type.beforeExpr;
  976. }
  977. }
  978. }
  979. exports.default = Tokenizer;