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
			| 
											3 years ago
										 | "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
 |