index.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.readCodePoint = readCodePoint;
  6. exports.readInt = readInt;
  7. exports.readStringContents = readStringContents;
  8. var _isDigit = function isDigit(code) {
  9. return code >= 48 && code <= 57;
  10. };
  11. const forbiddenNumericSeparatorSiblings = {
  12. decBinOct: new Set([46, 66, 69, 79, 95, 98, 101, 111]),
  13. hex: new Set([46, 88, 95, 120])
  14. };
  15. const isAllowedNumericSeparatorSibling = {
  16. bin: ch => ch === 48 || ch === 49,
  17. oct: ch => ch >= 48 && ch <= 55,
  18. dec: ch => ch >= 48 && ch <= 57,
  19. hex: ch => ch >= 48 && ch <= 57 || ch >= 65 && ch <= 70 || ch >= 97 && ch <= 102
  20. };
  21. function readStringContents(type, input, pos, lineStart, curLine, errors) {
  22. const initialPos = pos;
  23. const initialLineStart = lineStart;
  24. const initialCurLine = curLine;
  25. let out = "";
  26. let firstInvalidLoc = null;
  27. let chunkStart = pos;
  28. const {
  29. length
  30. } = input;
  31. for (;;) {
  32. if (pos >= length) {
  33. errors.unterminated(initialPos, initialLineStart, initialCurLine);
  34. out += input.slice(chunkStart, pos);
  35. break;
  36. }
  37. const ch = input.charCodeAt(pos);
  38. if (isStringEnd(type, ch, input, pos)) {
  39. out += input.slice(chunkStart, pos);
  40. break;
  41. }
  42. if (ch === 92) {
  43. out += input.slice(chunkStart, pos);
  44. const res = readEscapedChar(input, pos, lineStart, curLine, type === "template", errors);
  45. if (res.ch === null && !firstInvalidLoc) {
  46. firstInvalidLoc = {
  47. pos,
  48. lineStart,
  49. curLine
  50. };
  51. } else {
  52. out += res.ch;
  53. }
  54. ({
  55. pos,
  56. lineStart,
  57. curLine
  58. } = res);
  59. chunkStart = pos;
  60. } else if (ch === 8232 || ch === 8233) {
  61. ++pos;
  62. ++curLine;
  63. lineStart = pos;
  64. } else if (ch === 10 || ch === 13) {
  65. if (type === "template") {
  66. out += input.slice(chunkStart, pos) + "\n";
  67. ++pos;
  68. if (ch === 13 && input.charCodeAt(pos) === 10) {
  69. ++pos;
  70. }
  71. ++curLine;
  72. chunkStart = lineStart = pos;
  73. } else {
  74. errors.unterminated(initialPos, initialLineStart, initialCurLine);
  75. }
  76. } else {
  77. ++pos;
  78. }
  79. }
  80. return {
  81. pos,
  82. str: out,
  83. firstInvalidLoc,
  84. lineStart,
  85. curLine,
  86. containsInvalid: !!firstInvalidLoc
  87. };
  88. }
  89. function isStringEnd(type, ch, input, pos) {
  90. if (type === "template") {
  91. return ch === 96 || ch === 36 && input.charCodeAt(pos + 1) === 123;
  92. }
  93. return ch === (type === "double" ? 34 : 39);
  94. }
  95. function readEscapedChar(input, pos, lineStart, curLine, inTemplate, errors) {
  96. const throwOnInvalid = !inTemplate;
  97. pos++;
  98. const res = ch => ({
  99. pos,
  100. ch,
  101. lineStart,
  102. curLine
  103. });
  104. const ch = input.charCodeAt(pos++);
  105. switch (ch) {
  106. case 110:
  107. return res("\n");
  108. case 114:
  109. return res("\r");
  110. case 120:
  111. {
  112. let code;
  113. ({
  114. code,
  115. pos
  116. } = readHexChar(input, pos, lineStart, curLine, 2, false, throwOnInvalid, errors));
  117. return res(code === null ? null : String.fromCharCode(code));
  118. }
  119. case 117:
  120. {
  121. let code;
  122. ({
  123. code,
  124. pos
  125. } = readCodePoint(input, pos, lineStart, curLine, throwOnInvalid, errors));
  126. return res(code === null ? null : String.fromCodePoint(code));
  127. }
  128. case 116:
  129. return res("\t");
  130. case 98:
  131. return res("\b");
  132. case 118:
  133. return res("\u000b");
  134. case 102:
  135. return res("\f");
  136. case 13:
  137. if (input.charCodeAt(pos) === 10) {
  138. ++pos;
  139. }
  140. case 10:
  141. lineStart = pos;
  142. ++curLine;
  143. case 8232:
  144. case 8233:
  145. return res("");
  146. case 56:
  147. case 57:
  148. if (inTemplate) {
  149. return res(null);
  150. } else {
  151. errors.strictNumericEscape(pos - 1, lineStart, curLine);
  152. }
  153. default:
  154. if (ch >= 48 && ch <= 55) {
  155. const startPos = pos - 1;
  156. const match = /^[0-7]+/.exec(input.slice(startPos, pos + 2));
  157. let octalStr = match[0];
  158. let octal = parseInt(octalStr, 8);
  159. if (octal > 255) {
  160. octalStr = octalStr.slice(0, -1);
  161. octal = parseInt(octalStr, 8);
  162. }
  163. pos += octalStr.length - 1;
  164. const next = input.charCodeAt(pos);
  165. if (octalStr !== "0" || next === 56 || next === 57) {
  166. if (inTemplate) {
  167. return res(null);
  168. } else {
  169. errors.strictNumericEscape(startPos, lineStart, curLine);
  170. }
  171. }
  172. return res(String.fromCharCode(octal));
  173. }
  174. return res(String.fromCharCode(ch));
  175. }
  176. }
  177. function readHexChar(input, pos, lineStart, curLine, len, forceLen, throwOnInvalid, errors) {
  178. const initialPos = pos;
  179. let n;
  180. ({
  181. n,
  182. pos
  183. } = readInt(input, pos, lineStart, curLine, 16, len, forceLen, false, errors, !throwOnInvalid));
  184. if (n === null) {
  185. if (throwOnInvalid) {
  186. errors.invalidEscapeSequence(initialPos, lineStart, curLine);
  187. } else {
  188. pos = initialPos - 1;
  189. }
  190. }
  191. return {
  192. code: n,
  193. pos
  194. };
  195. }
  196. function readInt(input, pos, lineStart, curLine, radix, len, forceLen, allowNumSeparator, errors, bailOnError) {
  197. const start = pos;
  198. const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct;
  199. const isAllowedSibling = radix === 16 ? isAllowedNumericSeparatorSibling.hex : radix === 10 ? isAllowedNumericSeparatorSibling.dec : radix === 8 ? isAllowedNumericSeparatorSibling.oct : isAllowedNumericSeparatorSibling.bin;
  200. let invalid = false;
  201. let total = 0;
  202. for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) {
  203. const code = input.charCodeAt(pos);
  204. let val;
  205. if (code === 95 && allowNumSeparator !== "bail") {
  206. const prev = input.charCodeAt(pos - 1);
  207. const next = input.charCodeAt(pos + 1);
  208. if (!allowNumSeparator) {
  209. if (bailOnError) return {
  210. n: null,
  211. pos
  212. };
  213. errors.numericSeparatorInEscapeSequence(pos, lineStart, curLine);
  214. } else if (Number.isNaN(next) || !isAllowedSibling(next) || forbiddenSiblings.has(prev) || forbiddenSiblings.has(next)) {
  215. if (bailOnError) return {
  216. n: null,
  217. pos
  218. };
  219. errors.unexpectedNumericSeparator(pos, lineStart, curLine);
  220. }
  221. ++pos;
  222. continue;
  223. }
  224. if (code >= 97) {
  225. val = code - 97 + 10;
  226. } else if (code >= 65) {
  227. val = code - 65 + 10;
  228. } else if (_isDigit(code)) {
  229. val = code - 48;
  230. } else {
  231. val = Infinity;
  232. }
  233. if (val >= radix) {
  234. if (val <= 9 && bailOnError) {
  235. return {
  236. n: null,
  237. pos
  238. };
  239. } else if (val <= 9 && errors.invalidDigit(pos, lineStart, curLine, radix)) {
  240. val = 0;
  241. } else if (forceLen) {
  242. val = 0;
  243. invalid = true;
  244. } else {
  245. break;
  246. }
  247. }
  248. ++pos;
  249. total = total * radix + val;
  250. }
  251. if (pos === start || len != null && pos - start !== len || invalid) {
  252. return {
  253. n: null,
  254. pos
  255. };
  256. }
  257. return {
  258. n: total,
  259. pos
  260. };
  261. }
  262. function readCodePoint(input, pos, lineStart, curLine, throwOnInvalid, errors) {
  263. const ch = input.charCodeAt(pos);
  264. let code;
  265. if (ch === 123) {
  266. ++pos;
  267. ({
  268. code,
  269. pos
  270. } = readHexChar(input, pos, lineStart, curLine, input.indexOf("}", pos) - pos, true, throwOnInvalid, errors));
  271. ++pos;
  272. if (code !== null && code > 0x10ffff) {
  273. if (throwOnInvalid) {
  274. errors.invalidCodePoint(pos, lineStart, curLine);
  275. } else {
  276. return {
  277. code: null,
  278. pos
  279. };
  280. }
  281. }
  282. } else {
  283. ({
  284. code,
  285. pos
  286. } = readHexChar(input, pos, lineStart, curLine, 4, false, throwOnInvalid, errors));
  287. }
  288. return {
  289. code,
  290. pos
  291. };
  292. }
  293. //# sourceMappingURL=index.js.map