You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							348 lines
						
					
					
						
							7.7 KiB
						
					
					
				
			
		
		
	
	
							348 lines
						
					
					
						
							7.7 KiB
						
					
					
				| "use strict";
 | |
| 
 | |
| Object.defineProperty(exports, "__esModule", {
 | |
|   value: true
 | |
| });
 | |
| exports.readCodePoint = readCodePoint;
 | |
| exports.readInt = readInt;
 | |
| exports.readStringContents = readStringContents;
 | |
| 
 | |
| var _isDigit = function isDigit(code) {
 | |
|   return code >= 48 && code <= 57;
 | |
| };
 | |
| 
 | |
| const forbiddenNumericSeparatorSiblings = {
 | |
|   decBinOct: new Set([46, 66, 69, 79, 95, 98, 101, 111]),
 | |
|   hex: new Set([46, 88, 95, 120])
 | |
| };
 | |
| const isAllowedNumericSeparatorSibling = {
 | |
|   bin: ch => ch === 48 || ch === 49,
 | |
|   oct: ch => ch >= 48 && ch <= 55,
 | |
|   dec: ch => ch >= 48 && ch <= 57,
 | |
|   hex: ch => ch >= 48 && ch <= 57 || ch >= 65 && ch <= 70 || ch >= 97 && ch <= 102
 | |
| };
 | |
| 
 | |
| function readStringContents(type, input, pos, lineStart, curLine, errors) {
 | |
|   const initialPos = pos;
 | |
|   const initialLineStart = lineStart;
 | |
|   const initialCurLine = curLine;
 | |
|   let out = "";
 | |
|   let firstInvalidLoc = null;
 | |
|   let chunkStart = pos;
 | |
|   const {
 | |
|     length
 | |
|   } = input;
 | |
| 
 | |
|   for (;;) {
 | |
|     if (pos >= length) {
 | |
|       errors.unterminated(initialPos, initialLineStart, initialCurLine);
 | |
|       out += input.slice(chunkStart, pos);
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     const ch = input.charCodeAt(pos);
 | |
| 
 | |
|     if (isStringEnd(type, ch, input, pos)) {
 | |
|       out += input.slice(chunkStart, pos);
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     if (ch === 92) {
 | |
|       out += input.slice(chunkStart, pos);
 | |
|       const res = readEscapedChar(input, pos, lineStart, curLine, type === "template", errors);
 | |
| 
 | |
|       if (res.ch === null && !firstInvalidLoc) {
 | |
|         firstInvalidLoc = {
 | |
|           pos,
 | |
|           lineStart,
 | |
|           curLine
 | |
|         };
 | |
|       } else {
 | |
|         out += res.ch;
 | |
|       }
 | |
| 
 | |
|       ({
 | |
|         pos,
 | |
|         lineStart,
 | |
|         curLine
 | |
|       } = res);
 | |
|       chunkStart = pos;
 | |
|     } else if (ch === 8232 || ch === 8233) {
 | |
|       ++pos;
 | |
|       ++curLine;
 | |
|       lineStart = pos;
 | |
|     } else if (ch === 10 || ch === 13) {
 | |
|       if (type === "template") {
 | |
|         out += input.slice(chunkStart, pos) + "\n";
 | |
|         ++pos;
 | |
| 
 | |
|         if (ch === 13 && input.charCodeAt(pos) === 10) {
 | |
|           ++pos;
 | |
|         }
 | |
| 
 | |
|         ++curLine;
 | |
|         chunkStart = lineStart = pos;
 | |
|       } else {
 | |
|         errors.unterminated(initialPos, initialLineStart, initialCurLine);
 | |
|       }
 | |
|     } else {
 | |
|       ++pos;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     pos,
 | |
|     str: out,
 | |
|     firstInvalidLoc,
 | |
|     lineStart,
 | |
|     curLine,
 | |
|     containsInvalid: !!firstInvalidLoc
 | |
|   };
 | |
| }
 | |
| 
 | |
| function isStringEnd(type, ch, input, pos) {
 | |
|   if (type === "template") {
 | |
|     return ch === 96 || ch === 36 && input.charCodeAt(pos + 1) === 123;
 | |
|   }
 | |
| 
 | |
|   return ch === (type === "double" ? 34 : 39);
 | |
| }
 | |
| 
 | |
| function readEscapedChar(input, pos, lineStart, curLine, inTemplate, errors) {
 | |
|   const throwOnInvalid = !inTemplate;
 | |
|   pos++;
 | |
| 
 | |
|   const res = ch => ({
 | |
|     pos,
 | |
|     ch,
 | |
|     lineStart,
 | |
|     curLine
 | |
|   });
 | |
| 
 | |
|   const ch = input.charCodeAt(pos++);
 | |
| 
 | |
|   switch (ch) {
 | |
|     case 110:
 | |
|       return res("\n");
 | |
| 
 | |
|     case 114:
 | |
|       return res("\r");
 | |
| 
 | |
|     case 120:
 | |
|       {
 | |
|         let code;
 | |
|         ({
 | |
|           code,
 | |
|           pos
 | |
|         } = readHexChar(input, pos, lineStart, curLine, 2, false, throwOnInvalid, errors));
 | |
|         return res(code === null ? null : String.fromCharCode(code));
 | |
|       }
 | |
| 
 | |
|     case 117:
 | |
|       {
 | |
|         let code;
 | |
|         ({
 | |
|           code,
 | |
|           pos
 | |
|         } = readCodePoint(input, pos, lineStart, curLine, throwOnInvalid, errors));
 | |
|         return res(code === null ? null : String.fromCodePoint(code));
 | |
|       }
 | |
| 
 | |
|     case 116:
 | |
|       return res("\t");
 | |
| 
 | |
|     case 98:
 | |
|       return res("\b");
 | |
| 
 | |
|     case 118:
 | |
|       return res("\u000b");
 | |
| 
 | |
|     case 102:
 | |
|       return res("\f");
 | |
| 
 | |
|     case 13:
 | |
|       if (input.charCodeAt(pos) === 10) {
 | |
|         ++pos;
 | |
|       }
 | |
| 
 | |
|     case 10:
 | |
|       lineStart = pos;
 | |
|       ++curLine;
 | |
| 
 | |
|     case 8232:
 | |
|     case 8233:
 | |
|       return res("");
 | |
| 
 | |
|     case 56:
 | |
|     case 57:
 | |
|       if (inTemplate) {
 | |
|         return res(null);
 | |
|       } else {
 | |
|         errors.strictNumericEscape(pos - 1, lineStart, curLine);
 | |
|       }
 | |
| 
 | |
|     default:
 | |
|       if (ch >= 48 && ch <= 55) {
 | |
|         const startPos = pos - 1;
 | |
|         const match = input.slice(startPos, pos + 2).match(/^[0-7]+/);
 | |
|         let octalStr = match[0];
 | |
|         let octal = parseInt(octalStr, 8);
 | |
| 
 | |
|         if (octal > 255) {
 | |
|           octalStr = octalStr.slice(0, -1);
 | |
|           octal = parseInt(octalStr, 8);
 | |
|         }
 | |
| 
 | |
|         pos += octalStr.length - 1;
 | |
|         const next = input.charCodeAt(pos);
 | |
| 
 | |
|         if (octalStr !== "0" || next === 56 || next === 57) {
 | |
|           if (inTemplate) {
 | |
|             return res(null);
 | |
|           } else {
 | |
|             errors.strictNumericEscape(startPos, lineStart, curLine);
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         return res(String.fromCharCode(octal));
 | |
|       }
 | |
| 
 | |
|       return res(String.fromCharCode(ch));
 | |
|   }
 | |
| }
 | |
| 
 | |
| function readHexChar(input, pos, lineStart, curLine, len, forceLen, throwOnInvalid, errors) {
 | |
|   const initialPos = pos;
 | |
|   let n;
 | |
|   ({
 | |
|     n,
 | |
|     pos
 | |
|   } = readInt(input, pos, lineStart, curLine, 16, len, forceLen, false, errors, !throwOnInvalid));
 | |
| 
 | |
|   if (n === null) {
 | |
|     if (throwOnInvalid) {
 | |
|       errors.invalidEscapeSequence(initialPos, lineStart, curLine);
 | |
|     } else {
 | |
|       pos = initialPos - 1;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     code: n,
 | |
|     pos
 | |
|   };
 | |
| }
 | |
| 
 | |
| function readInt(input, pos, lineStart, curLine, radix, len, forceLen, allowNumSeparator, errors, bailOnError) {
 | |
|   const start = pos;
 | |
|   const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct;
 | |
|   const isAllowedSibling = radix === 16 ? isAllowedNumericSeparatorSibling.hex : radix === 10 ? isAllowedNumericSeparatorSibling.dec : radix === 8 ? isAllowedNumericSeparatorSibling.oct : isAllowedNumericSeparatorSibling.bin;
 | |
|   let invalid = false;
 | |
|   let total = 0;
 | |
| 
 | |
|   for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) {
 | |
|     const code = input.charCodeAt(pos);
 | |
|     let val;
 | |
| 
 | |
|     if (code === 95 && allowNumSeparator !== "bail") {
 | |
|       const prev = input.charCodeAt(pos - 1);
 | |
|       const next = input.charCodeAt(pos + 1);
 | |
| 
 | |
|       if (!allowNumSeparator) {
 | |
|         if (bailOnError) return {
 | |
|           n: null,
 | |
|           pos
 | |
|         };
 | |
|         errors.numericSeparatorInEscapeSequence(pos, lineStart, curLine);
 | |
|       } else if (Number.isNaN(next) || !isAllowedSibling(next) || forbiddenSiblings.has(prev) || forbiddenSiblings.has(next)) {
 | |
|         if (bailOnError) return {
 | |
|           n: null,
 | |
|           pos
 | |
|         };
 | |
|         errors.unexpectedNumericSeparator(pos, lineStart, curLine);
 | |
|       }
 | |
| 
 | |
|       ++pos;
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     if (code >= 97) {
 | |
|       val = code - 97 + 10;
 | |
|     } else if (code >= 65) {
 | |
|       val = code - 65 + 10;
 | |
|     } else if (_isDigit(code)) {
 | |
|       val = code - 48;
 | |
|     } else {
 | |
|       val = Infinity;
 | |
|     }
 | |
| 
 | |
|     if (val >= radix) {
 | |
|       if (val <= 9 && bailOnError) {
 | |
|         return {
 | |
|           n: null,
 | |
|           pos
 | |
|         };
 | |
|       } else if (val <= 9 && errors.invalidDigit(pos, lineStart, curLine, radix)) {
 | |
|         val = 0;
 | |
|       } else if (forceLen) {
 | |
|         val = 0;
 | |
|         invalid = true;
 | |
|       } else {
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     ++pos;
 | |
|     total = total * radix + val;
 | |
|   }
 | |
| 
 | |
|   if (pos === start || len != null && pos - start !== len || invalid) {
 | |
|     return {
 | |
|       n: null,
 | |
|       pos
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     n: total,
 | |
|     pos
 | |
|   };
 | |
| }
 | |
| 
 | |
| function readCodePoint(input, pos, lineStart, curLine, throwOnInvalid, errors) {
 | |
|   const ch = input.charCodeAt(pos);
 | |
|   let code;
 | |
| 
 | |
|   if (ch === 123) {
 | |
|     ++pos;
 | |
|     ({
 | |
|       code,
 | |
|       pos
 | |
|     } = readHexChar(input, pos, lineStart, curLine, input.indexOf("}", pos) - pos, true, throwOnInvalid, errors));
 | |
|     ++pos;
 | |
| 
 | |
|     if (code !== null && code > 0x10ffff) {
 | |
|       if (throwOnInvalid) {
 | |
|         errors.invalidCodePoint(pos, lineStart, curLine);
 | |
|       } else {
 | |
|         return {
 | |
|           code: null,
 | |
|           pos
 | |
|         };
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     ({
 | |
|       code,
 | |
|       pos
 | |
|     } = readHexChar(input, pos, lineStart, curLine, 4, false, throwOnInvalid, errors));
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     code,
 | |
|     pos
 | |
|   };
 | |
| }
 | |
| 
 | |
| //# sourceMappingURL=index.js.map
 |