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.
295 lines
7.7 KiB
295 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
|
|
|