first commit
This commit is contained in:
925
app_vue/node_modules/es-module-lexer/lexer.js
generated
vendored
Normal file
925
app_vue/node_modules/es-module-lexer/lexer.js
generated
vendored
Normal file
@ -0,0 +1,925 @@
|
||||
let source, pos, end,
|
||||
openTokenDepth,
|
||||
lastTokenPos,
|
||||
openTokenPosStack,
|
||||
openClassPosStack,
|
||||
curDynamicImport,
|
||||
templateStackDepth,
|
||||
facade,
|
||||
lastSlashWasDivision,
|
||||
nextBraceIsClass,
|
||||
templateDepth,
|
||||
templateStack,
|
||||
imports,
|
||||
exports,
|
||||
name;
|
||||
|
||||
function addImport (ss, s, e, d) {
|
||||
const impt = { ss, se: d === -2 ? e : d === -1 ? e + 1 : 0, s, e, d, a: -1, n: undefined };
|
||||
imports.push(impt);
|
||||
return impt;
|
||||
}
|
||||
|
||||
function addExport (s, e, ls, le) {
|
||||
exports.push({
|
||||
s,
|
||||
e,
|
||||
ls,
|
||||
le,
|
||||
n: s[0] === '"' ? readString(s, '"') : s[0] === "'" ? readString(s, "'") : source.slice(s, e),
|
||||
ln: ls[0] === '"' ? readString(ls, '"') : ls[0] === "'" ? readString(ls, "'") : source.slice(ls, le)
|
||||
});
|
||||
}
|
||||
|
||||
function readName (impt) {
|
||||
let { d, s } = impt;
|
||||
if (d !== -1)
|
||||
s++;
|
||||
impt.n = readString(s, source.charCodeAt(s - 1));
|
||||
}
|
||||
|
||||
// Note: parsing is based on the _assumption_ that the source is already valid
|
||||
export function parse (_source, _name) {
|
||||
openTokenDepth = 0;
|
||||
curDynamicImport = null;
|
||||
templateDepth = -1;
|
||||
lastTokenPos = -1;
|
||||
lastSlashWasDivision = false;
|
||||
templateStack = Array(1024);
|
||||
templateStackDepth = 0;
|
||||
openTokenPosStack = Array(1024);
|
||||
openClassPosStack = Array(1024);
|
||||
nextBraceIsClass = false;
|
||||
facade = true;
|
||||
name = _name || '@';
|
||||
|
||||
imports = [];
|
||||
exports = [];
|
||||
|
||||
source = _source;
|
||||
pos = -1;
|
||||
end = source.length - 1;
|
||||
let ch = 0;
|
||||
|
||||
// start with a pure "module-only" parser
|
||||
m: while (pos++ < end) {
|
||||
ch = source.charCodeAt(pos);
|
||||
|
||||
if (ch === 32 || ch < 14 && ch > 8)
|
||||
continue;
|
||||
|
||||
switch (ch) {
|
||||
case 101/*e*/:
|
||||
if (openTokenDepth === 0 && keywordStart(pos) && source.startsWith('xport', pos + 1)) {
|
||||
tryParseExportStatement();
|
||||
// export might have been a non-pure declaration
|
||||
if (!facade) {
|
||||
lastTokenPos = pos;
|
||||
break m;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 105/*i*/:
|
||||
if (keywordStart(pos) && source.startsWith('mport', pos + 1))
|
||||
tryParseImportStatement();
|
||||
break;
|
||||
case 59/*;*/:
|
||||
break;
|
||||
case 47/*/*/: {
|
||||
const next_ch = source.charCodeAt(pos + 1);
|
||||
if (next_ch === 47/*/*/) {
|
||||
lineComment();
|
||||
// dont update lastToken
|
||||
continue;
|
||||
}
|
||||
else if (next_ch === 42/***/) {
|
||||
blockComment(true);
|
||||
// dont update lastToken
|
||||
continue;
|
||||
}
|
||||
// fallthrough
|
||||
}
|
||||
default:
|
||||
// as soon as we hit a non-module token, we go to main parser
|
||||
facade = false;
|
||||
pos--;
|
||||
break m;
|
||||
}
|
||||
lastTokenPos = pos;
|
||||
}
|
||||
|
||||
while (pos++ < end) {
|
||||
ch = source.charCodeAt(pos);
|
||||
|
||||
if (ch === 32 || ch < 14 && ch > 8)
|
||||
continue;
|
||||
|
||||
switch (ch) {
|
||||
case 101/*e*/:
|
||||
if (openTokenDepth === 0 && keywordStart(pos) && source.startsWith('xport', pos + 1))
|
||||
tryParseExportStatement();
|
||||
break;
|
||||
case 105/*i*/:
|
||||
if (keywordStart(pos) && source.startsWith('mport', pos + 1))
|
||||
tryParseImportStatement();
|
||||
break;
|
||||
case 99/*c*/:
|
||||
if (keywordStart(pos) && source.startsWith('lass', pos + 1) && isBrOrWs(source.charCodeAt(pos + 5)))
|
||||
nextBraceIsClass = true;
|
||||
break;
|
||||
case 40/*(*/:
|
||||
openTokenPosStack[openTokenDepth++] = lastTokenPos;
|
||||
break;
|
||||
case 41/*)*/:
|
||||
if (openTokenDepth === 0)
|
||||
syntaxError();
|
||||
openTokenDepth--;
|
||||
if (curDynamicImport && curDynamicImport.d === openTokenPosStack[openTokenDepth]) {
|
||||
if (curDynamicImport.e === 0)
|
||||
curDynamicImport.e = pos;
|
||||
curDynamicImport.se = pos;
|
||||
curDynamicImport = null;
|
||||
}
|
||||
break;
|
||||
case 123/*{*/:
|
||||
// dynamic import followed by { is not a dynamic import (so remove)
|
||||
// this is a sneaky way to get around { import () {} } v { import () }
|
||||
// block / object ambiguity without a parser (assuming source is valid)
|
||||
if (source.charCodeAt(lastTokenPos) === 41/*)*/ && imports.length && imports[imports.length - 1].e === lastTokenPos) {
|
||||
imports.pop();
|
||||
}
|
||||
openClassPosStack[openTokenDepth] = nextBraceIsClass;
|
||||
nextBraceIsClass = false;
|
||||
openTokenPosStack[openTokenDepth++] = lastTokenPos;
|
||||
break;
|
||||
case 125/*}*/:
|
||||
if (openTokenDepth === 0)
|
||||
syntaxError();
|
||||
if (openTokenDepth-- === templateDepth) {
|
||||
templateDepth = templateStack[--templateStackDepth];
|
||||
templateString();
|
||||
}
|
||||
else {
|
||||
if (templateDepth !== -1 && openTokenDepth < templateDepth)
|
||||
syntaxError();
|
||||
}
|
||||
break;
|
||||
case 39/*'*/:
|
||||
case 34/*"*/:
|
||||
stringLiteral(ch);
|
||||
break;
|
||||
case 47/*/*/: {
|
||||
const next_ch = source.charCodeAt(pos + 1);
|
||||
if (next_ch === 47/*/*/) {
|
||||
lineComment();
|
||||
// dont update lastToken
|
||||
continue;
|
||||
}
|
||||
else if (next_ch === 42/***/) {
|
||||
blockComment(true);
|
||||
// dont update lastToken
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// Division / regex ambiguity handling based on checking backtrack analysis of:
|
||||
// - what token came previously (lastToken)
|
||||
// - if a closing brace or paren, what token came before the corresponding
|
||||
// opening brace or paren (lastOpenTokenIndex)
|
||||
const lastToken = source.charCodeAt(lastTokenPos);
|
||||
const lastExport = exports[exports.length - 1];
|
||||
if (isExpressionPunctuator(lastToken) &&
|
||||
!(lastToken === 46/*.*/ && (source.charCodeAt(lastTokenPos - 1) >= 48/*0*/ && source.charCodeAt(lastTokenPos - 1) <= 57/*9*/)) &&
|
||||
!(lastToken === 43/*+*/ && source.charCodeAt(lastTokenPos - 1) === 43/*+*/) && !(lastToken === 45/*-*/ && source.charCodeAt(lastTokenPos - 1) === 45/*-*/) ||
|
||||
lastToken === 41/*)*/ && isParenKeyword(openTokenPosStack[openTokenDepth]) ||
|
||||
lastToken === 125/*}*/ && (isExpressionTerminator(openTokenPosStack[openTokenDepth]) || openClassPosStack[openTokenDepth]) ||
|
||||
lastToken === 47/*/*/ && lastSlashWasDivision ||
|
||||
isExpressionKeyword(lastTokenPos) ||
|
||||
!lastToken) {
|
||||
regularExpression();
|
||||
lastSlashWasDivision = false;
|
||||
}
|
||||
else if (lastExport && lastTokenPos >= lastExport.s && lastTokenPos <= lastExport.e) {
|
||||
// export default /some-regexp/
|
||||
regularExpression();
|
||||
lastSlashWasDivision = false;
|
||||
}
|
||||
else {
|
||||
lastSlashWasDivision = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 96/*`*/:
|
||||
templateString();
|
||||
break;
|
||||
}
|
||||
lastTokenPos = pos;
|
||||
}
|
||||
|
||||
if (templateDepth !== -1 || openTokenDepth)
|
||||
syntaxError();
|
||||
|
||||
return [imports, exports, facade];
|
||||
}
|
||||
|
||||
function tryParseImportStatement () {
|
||||
const startPos = pos;
|
||||
|
||||
pos += 6;
|
||||
|
||||
let ch = commentWhitespace(true);
|
||||
|
||||
switch (ch) {
|
||||
// dynamic import
|
||||
case 40/*(*/:
|
||||
openTokenPosStack[openTokenDepth++] = startPos;
|
||||
if (source.charCodeAt(lastTokenPos) === 46/*.*/)
|
||||
return;
|
||||
// dynamic import indicated by positive d
|
||||
const impt = addImport(startPos, pos + 1, 0, startPos);
|
||||
curDynamicImport = impt;
|
||||
// try parse a string, to record a safe dynamic import string
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 39/*'*/ || ch === 34/*"*/) {
|
||||
stringLiteral(ch);
|
||||
}
|
||||
else {
|
||||
pos--;
|
||||
return;
|
||||
}
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 44/*,*/) {
|
||||
impt.e = pos;
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
impt.a = pos;
|
||||
readName(impt);
|
||||
pos--;
|
||||
}
|
||||
else if (ch === 41/*)*/) {
|
||||
openTokenDepth--;
|
||||
impt.e = pos;
|
||||
impt.se = pos;
|
||||
readName(impt);
|
||||
}
|
||||
else {
|
||||
pos--;
|
||||
}
|
||||
return;
|
||||
// import.meta
|
||||
case 46/*.*/:
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
// import.meta indicated by d === -2
|
||||
if (ch === 109/*m*/ && source.startsWith('eta', pos + 1) && source.charCodeAt(lastTokenPos) !== 46/*.*/)
|
||||
addImport(startPos, startPos, pos + 4, -2);
|
||||
return;
|
||||
|
||||
default:
|
||||
// no space after "import" -> not an import keyword
|
||||
if (pos === startPos + 6)
|
||||
break;
|
||||
case 34/*"*/:
|
||||
case 39/*'*/:
|
||||
case 123/*{*/:
|
||||
case 42/***/:
|
||||
// import statement only permitted at base-level
|
||||
if (openTokenDepth !== 0) {
|
||||
pos--;
|
||||
return;
|
||||
}
|
||||
while (pos < end) {
|
||||
ch = source.charCodeAt(pos);
|
||||
if (ch === 39/*'*/ || ch === 34/*"*/) {
|
||||
readImportString(startPos, ch);
|
||||
return;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
syntaxError();
|
||||
}
|
||||
}
|
||||
|
||||
function tryParseExportStatement () {
|
||||
const sStartPos = pos;
|
||||
const prevExport = exports.length;
|
||||
|
||||
pos += 6;
|
||||
|
||||
const curPos = pos;
|
||||
|
||||
let ch = commentWhitespace(true);
|
||||
|
||||
if (pos === curPos && !isPunctuator(ch))
|
||||
return;
|
||||
|
||||
switch (ch) {
|
||||
// export default ...
|
||||
case 100/*d*/:
|
||||
addExport(pos, pos + 7, -1, -1);
|
||||
return;
|
||||
|
||||
// export async? function*? name () {
|
||||
case 97/*a*/:
|
||||
pos += 5;
|
||||
commentWhitespace(true);
|
||||
// fallthrough
|
||||
case 102/*f*/:
|
||||
pos += 8;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 42/***/) {
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
}
|
||||
const startPos = pos;
|
||||
ch = readToWsOrPunctuator(ch);
|
||||
addExport(startPos, pos, startPos, pos);
|
||||
pos--;
|
||||
return;
|
||||
|
||||
// export class name ...
|
||||
case 99/*c*/:
|
||||
if (source.startsWith('lass', pos + 1) && isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos + 5))) {
|
||||
pos += 5;
|
||||
ch = commentWhitespace(true);
|
||||
const startPos = pos;
|
||||
ch = readToWsOrPunctuator(ch);
|
||||
addExport(startPos, pos, startPos, pos);
|
||||
pos--;
|
||||
return;
|
||||
}
|
||||
pos += 2;
|
||||
// fallthrough
|
||||
|
||||
// export var/let/const name = ...(, name = ...)+
|
||||
case 118/*v*/:
|
||||
case 109/*l*/:
|
||||
// destructured initializations not currently supported (skipped for { or [)
|
||||
// also, lexing names after variable equals is skipped (export var p = function () { ... }, q = 5 skips "q")
|
||||
pos += 2;
|
||||
facade = false;
|
||||
do {
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
const startPos = pos;
|
||||
ch = readToWsOrPunctuator(ch);
|
||||
// dont yet handle [ { destructurings
|
||||
if (ch === 123/*{*/ || ch === 91/*[*/) {
|
||||
pos--;
|
||||
return;
|
||||
}
|
||||
if (pos === startPos)
|
||||
return;
|
||||
addExport(startPos, pos, startPos, pos);
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 61/*=*/) {
|
||||
pos--;
|
||||
return;
|
||||
}
|
||||
} while (ch === 44/*,*/);
|
||||
pos--;
|
||||
return;
|
||||
|
||||
|
||||
// export {...}
|
||||
case 123/*{*/:
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
while (true) {
|
||||
const startPos = pos;
|
||||
readToWsOrPunctuator(ch);
|
||||
const endPos = pos;
|
||||
commentWhitespace(true);
|
||||
ch = readExportAs(startPos, endPos);
|
||||
// ,
|
||||
if (ch === 44/*,*/) {
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
}
|
||||
if (ch === 125/*}*/)
|
||||
break;
|
||||
if (pos === startPos)
|
||||
return syntaxError();
|
||||
if (pos > end)
|
||||
return syntaxError();
|
||||
}
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
break;
|
||||
|
||||
// export *
|
||||
// export * as X
|
||||
case 42/***/:
|
||||
pos++;
|
||||
commentWhitespace(true);
|
||||
ch = readExportAs(pos, pos);
|
||||
ch = commentWhitespace(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// from ...
|
||||
if (ch === 102/*f*/ && source.startsWith('rom', pos + 1)) {
|
||||
pos += 4;
|
||||
readImportString(sStartPos, commentWhitespace(true));
|
||||
|
||||
// There were no local names.
|
||||
for (let i = prevExport; i < exports.length; ++i) {
|
||||
exports[i].ls = exports[i].le = -1;
|
||||
exports[i].ln = undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ported from Acorn
|
||||
*
|
||||
* MIT License
|
||||
|
||||
* Copyright (C) 2012-2020 by various contributors (see AUTHORS)
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
let acornPos;
|
||||
function readString (start, quote) {
|
||||
acornPos = start;
|
||||
let out = '', chunkStart = acornPos;
|
||||
for (;;) {
|
||||
if (acornPos >= source.length) syntaxError();
|
||||
const ch = source.charCodeAt(acornPos);
|
||||
if (ch === quote) break;
|
||||
if (ch === 92) { // '\'
|
||||
out += source.slice(chunkStart, acornPos);
|
||||
out += readEscapedChar();
|
||||
chunkStart = acornPos;
|
||||
}
|
||||
else if (ch === 0x2028 || ch === 0x2029) {
|
||||
++acornPos;
|
||||
}
|
||||
else {
|
||||
if (isBr(ch)) syntaxError();
|
||||
++acornPos;
|
||||
}
|
||||
}
|
||||
out += source.slice(chunkStart, acornPos++);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Used to read escaped characters
|
||||
|
||||
function readEscapedChar () {
|
||||
let ch = source.charCodeAt(++acornPos);
|
||||
++acornPos;
|
||||
switch (ch) {
|
||||
case 110: return '\n'; // 'n' -> '\n'
|
||||
case 114: return '\r'; // 'r' -> '\r'
|
||||
case 120: return String.fromCharCode(readHexChar(2)); // 'x'
|
||||
case 117: return readCodePointToString(); // 'u'
|
||||
case 116: return '\t'; // 't' -> '\t'
|
||||
case 98: return '\b'; // 'b' -> '\b'
|
||||
case 118: return '\u000b'; // 'v' -> '\u000b'
|
||||
case 102: return '\f'; // 'f' -> '\f'
|
||||
case 13: if (source.charCodeAt(acornPos) === 10) ++acornPos; // '\r\n'
|
||||
case 10: // ' \n'
|
||||
return '';
|
||||
case 56:
|
||||
case 57:
|
||||
syntaxError();
|
||||
default:
|
||||
if (ch >= 48 && ch <= 55) {
|
||||
let octalStr = source.substr(acornPos - 1, 3).match(/^[0-7]+/)[0];
|
||||
let octal = parseInt(octalStr, 8);
|
||||
if (octal > 255) {
|
||||
octalStr = octalStr.slice(0, -1);
|
||||
octal = parseInt(octalStr, 8);
|
||||
}
|
||||
acornPos += octalStr.length - 1;
|
||||
ch = source.charCodeAt(acornPos);
|
||||
if (octalStr !== '0' || ch === 56 || ch === 57)
|
||||
syntaxError();
|
||||
return String.fromCharCode(octal);
|
||||
}
|
||||
if (isBr(ch)) {
|
||||
// Unicode new line characters after \ get removed from output in both
|
||||
// template literals and strings
|
||||
return '';
|
||||
}
|
||||
return String.fromCharCode(ch);
|
||||
}
|
||||
}
|
||||
|
||||
// Used to read character escape sequences ('\x', '\u', '\U').
|
||||
|
||||
function readHexChar (len) {
|
||||
const start = acornPos;
|
||||
let total = 0, lastCode = 0;
|
||||
for (let i = 0; i < len; ++i, ++acornPos) {
|
||||
let code = source.charCodeAt(acornPos), val;
|
||||
|
||||
if (code === 95) {
|
||||
if (lastCode === 95 || i === 0) syntaxError();
|
||||
lastCode = code;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code >= 97) val = code - 97 + 10; // a
|
||||
else if (code >= 65) val = code - 65 + 10; // A
|
||||
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
|
||||
else break;
|
||||
if (val >= 16) break;
|
||||
lastCode = code;
|
||||
total = total * 16 + val;
|
||||
}
|
||||
|
||||
if (lastCode === 95 || acornPos - start !== len) syntaxError();
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
// Read a string value, interpreting backslash-escapes.
|
||||
|
||||
function readCodePointToString () {
|
||||
const ch = source.charCodeAt(acornPos);
|
||||
let code;
|
||||
if (ch === 123) { // '{'
|
||||
++acornPos;
|
||||
code = readHexChar(source.indexOf('}', acornPos) - acornPos);
|
||||
++acornPos;
|
||||
if (code > 0x10FFFF) syntaxError();
|
||||
} else {
|
||||
code = readHexChar(4);
|
||||
}
|
||||
// UTF-16 Decoding
|
||||
if (code <= 0xFFFF) return String.fromCharCode(code);
|
||||
code -= 0x10000;
|
||||
return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00);
|
||||
}
|
||||
|
||||
/*
|
||||
* </ Acorn Port>
|
||||
*/
|
||||
|
||||
function readExportAs (startPos, endPos) {
|
||||
let ch = source.charCodeAt(pos);
|
||||
let ls = startPos, le = endPos;
|
||||
if (ch === 97 /*a*/) {
|
||||
pos += 2;
|
||||
ch = commentWhitespace(true);
|
||||
startPos = pos;
|
||||
readToWsOrPunctuator(ch);
|
||||
endPos = pos;
|
||||
ch = commentWhitespace(true);
|
||||
}
|
||||
if (pos !== startPos)
|
||||
addExport(startPos, endPos, ls, le);
|
||||
return ch;
|
||||
}
|
||||
|
||||
function readImportString (ss, ch) {
|
||||
const startPos = pos + 1;
|
||||
if (ch === 39/*'*/ || ch === 34/*"*/) {
|
||||
stringLiteral(ch);
|
||||
}
|
||||
else {
|
||||
syntaxError();
|
||||
return;
|
||||
}
|
||||
const impt = addImport(ss, startPos, pos, -1);
|
||||
readName(impt);
|
||||
pos++;
|
||||
ch = commentWhitespace(false);
|
||||
if (ch !== 97/*a*/ || !source.startsWith('ssert', pos + 1)) {
|
||||
pos--;
|
||||
return;
|
||||
}
|
||||
const assertIndex = pos;
|
||||
|
||||
pos += 6;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch !== 123/*{*/) {
|
||||
pos = assertIndex;
|
||||
return;
|
||||
}
|
||||
const assertStart = pos;
|
||||
do {
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 39/*'*/ || ch === 34/*"*/) {
|
||||
stringLiteral(ch);
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
}
|
||||
else {
|
||||
ch = readToWsOrPunctuator(ch);
|
||||
}
|
||||
if (ch !== 58/*:*/) {
|
||||
pos = assertIndex;
|
||||
return;
|
||||
}
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 39/*'*/ || ch === 34/*"*/) {
|
||||
stringLiteral(ch);
|
||||
}
|
||||
else {
|
||||
pos = assertIndex;
|
||||
return;
|
||||
}
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 44/*,*/) {
|
||||
pos++;
|
||||
ch = commentWhitespace(true);
|
||||
if (ch === 125/*}*/)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (ch === 125/*}*/)
|
||||
break;
|
||||
pos = assertIndex;
|
||||
return;
|
||||
} while (true);
|
||||
impt.a = assertStart;
|
||||
impt.se = pos + 1;
|
||||
}
|
||||
|
||||
function commentWhitespace (br) {
|
||||
let ch;
|
||||
do {
|
||||
ch = source.charCodeAt(pos);
|
||||
if (ch === 47/*/*/) {
|
||||
const next_ch = source.charCodeAt(pos + 1);
|
||||
if (next_ch === 47/*/*/)
|
||||
lineComment();
|
||||
else if (next_ch === 42/***/)
|
||||
blockComment(br);
|
||||
else
|
||||
return ch;
|
||||
}
|
||||
else if (br ? !isBrOrWs(ch): !isWsNotBr(ch)) {
|
||||
return ch;
|
||||
}
|
||||
} while (pos++ < end);
|
||||
return ch;
|
||||
}
|
||||
|
||||
function templateString () {
|
||||
while (pos++ < end) {
|
||||
const ch = source.charCodeAt(pos);
|
||||
if (ch === 36/*$*/ && source.charCodeAt(pos + 1) === 123/*{*/) {
|
||||
pos++;
|
||||
templateStack[templateStackDepth++] = templateDepth;
|
||||
templateDepth = ++openTokenDepth;
|
||||
return;
|
||||
}
|
||||
if (ch === 96/*`*/)
|
||||
return;
|
||||
if (ch === 92/*\*/)
|
||||
pos++;
|
||||
}
|
||||
syntaxError();
|
||||
}
|
||||
|
||||
function blockComment (br) {
|
||||
pos++;
|
||||
while (pos++ < end) {
|
||||
const ch = source.charCodeAt(pos);
|
||||
if (!br && isBr(ch))
|
||||
return;
|
||||
if (ch === 42/***/ && source.charCodeAt(pos + 1) === 47/*/*/) {
|
||||
pos++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function lineComment () {
|
||||
while (pos++ < end) {
|
||||
const ch = source.charCodeAt(pos);
|
||||
if (ch === 10/*\n*/ || ch === 13/*\r*/)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function stringLiteral (quote) {
|
||||
while (pos++ < end) {
|
||||
let ch = source.charCodeAt(pos);
|
||||
if (ch === quote)
|
||||
return;
|
||||
if (ch === 92/*\*/) {
|
||||
ch = source.charCodeAt(++pos);
|
||||
if (ch === 13/*\r*/ && source.charCodeAt(pos + 1) === 10/*\n*/)
|
||||
pos++;
|
||||
}
|
||||
else if (isBr(ch))
|
||||
break;
|
||||
}
|
||||
syntaxError();
|
||||
}
|
||||
|
||||
function regexCharacterClass () {
|
||||
while (pos++ < end) {
|
||||
let ch = source.charCodeAt(pos);
|
||||
if (ch === 93/*]*/)
|
||||
return ch;
|
||||
if (ch === 92/*\*/)
|
||||
pos++;
|
||||
else if (ch === 10/*\n*/ || ch === 13/*\r*/)
|
||||
break;
|
||||
}
|
||||
syntaxError();
|
||||
}
|
||||
|
||||
function regularExpression () {
|
||||
while (pos++ < end) {
|
||||
let ch = source.charCodeAt(pos);
|
||||
if (ch === 47/*/*/)
|
||||
return;
|
||||
if (ch === 91/*[*/)
|
||||
ch = regexCharacterClass();
|
||||
else if (ch === 92/*\*/)
|
||||
pos++;
|
||||
else if (ch === 10/*\n*/ || ch === 13/*\r*/)
|
||||
break;
|
||||
}
|
||||
syntaxError();
|
||||
}
|
||||
|
||||
function readToWsOrPunctuator (ch) {
|
||||
do {
|
||||
if (isBrOrWs(ch) || isPunctuator(ch))
|
||||
return ch;
|
||||
} while (ch = source.charCodeAt(++pos));
|
||||
return ch;
|
||||
}
|
||||
|
||||
// Note: non-asii BR and whitespace checks omitted for perf / footprint
|
||||
// if there is a significant user need this can be reconsidered
|
||||
function isBr (c) {
|
||||
return c === 13/*\r*/ || c === 10/*\n*/;
|
||||
}
|
||||
|
||||
function isWsNotBr (c) {
|
||||
return c === 9 || c === 11 || c === 12 || c === 32 || c === 160;
|
||||
}
|
||||
|
||||
function isBrOrWs (c) {
|
||||
return c > 8 && c < 14 || c === 32 || c === 160;
|
||||
}
|
||||
|
||||
function isBrOrWsOrPunctuatorNotDot (c) {
|
||||
return c > 8 && c < 14 || c === 32 || c === 160 || isPunctuator(c) && c !== 46/*.*/;
|
||||
}
|
||||
|
||||
function keywordStart (pos) {
|
||||
return pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - 1));
|
||||
}
|
||||
|
||||
function readPrecedingKeyword (pos, match) {
|
||||
if (pos < match.length - 1)
|
||||
return false;
|
||||
return source.startsWith(match, pos - match.length + 1) && (pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - match.length)));
|
||||
}
|
||||
|
||||
function readPrecedingKeyword1 (pos, ch) {
|
||||
return source.charCodeAt(pos) === ch && (pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - 1)));
|
||||
}
|
||||
|
||||
// Detects one of case, debugger, delete, do, else, in, instanceof, new,
|
||||
// return, throw, typeof, void, yield, await
|
||||
function isExpressionKeyword (pos) {
|
||||
switch (source.charCodeAt(pos)) {
|
||||
case 100/*d*/:
|
||||
switch (source.charCodeAt(pos - 1)) {
|
||||
case 105/*i*/:
|
||||
// void
|
||||
return readPrecedingKeyword(pos - 2, 'vo');
|
||||
case 108/*l*/:
|
||||
// yield
|
||||
return readPrecedingKeyword(pos - 2, 'yie');
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case 101/*e*/:
|
||||
switch (source.charCodeAt(pos - 1)) {
|
||||
case 115/*s*/:
|
||||
switch (source.charCodeAt(pos - 2)) {
|
||||
case 108/*l*/:
|
||||
// else
|
||||
return readPrecedingKeyword1(pos - 3, 101/*e*/);
|
||||
case 97/*a*/:
|
||||
// case
|
||||
return readPrecedingKeyword1(pos - 3, 99/*c*/);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case 116/*t*/:
|
||||
// delete
|
||||
return readPrecedingKeyword(pos - 2, 'dele');
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case 102/*f*/:
|
||||
if (source.charCodeAt(pos - 1) !== 111/*o*/ || source.charCodeAt(pos - 2) !== 101/*e*/)
|
||||
return false;
|
||||
switch (source.charCodeAt(pos - 3)) {
|
||||
case 99/*c*/:
|
||||
// instanceof
|
||||
return readPrecedingKeyword(pos - 4, 'instan');
|
||||
case 112/*p*/:
|
||||
// typeof
|
||||
return readPrecedingKeyword(pos - 4, 'ty');
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case 110/*n*/:
|
||||
// in, return
|
||||
return readPrecedingKeyword1(pos - 1, 105/*i*/) || readPrecedingKeyword(pos - 1, 'retur');
|
||||
case 111/*o*/:
|
||||
// do
|
||||
return readPrecedingKeyword1(pos - 1, 100/*d*/);
|
||||
case 114/*r*/:
|
||||
// debugger
|
||||
return readPrecedingKeyword(pos - 1, 'debugge');
|
||||
case 116/*t*/:
|
||||
// await
|
||||
return readPrecedingKeyword(pos - 1, 'awai');
|
||||
case 119/*w*/:
|
||||
switch (source.charCodeAt(pos - 1)) {
|
||||
case 101/*e*/:
|
||||
// new
|
||||
return readPrecedingKeyword1(pos - 2, 110/*n*/);
|
||||
case 111/*o*/:
|
||||
// throw
|
||||
return readPrecedingKeyword(pos - 2, 'thr');
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isParenKeyword (curPos) {
|
||||
return source.charCodeAt(curPos) === 101/*e*/ && source.startsWith('whil', curPos - 4) ||
|
||||
source.charCodeAt(curPos) === 114/*r*/ && source.startsWith('fo', curPos - 2) ||
|
||||
source.charCodeAt(curPos - 1) === 105/*i*/ && source.charCodeAt(curPos) === 102/*f*/;
|
||||
}
|
||||
|
||||
function isPunctuator (ch) {
|
||||
// 23 possible punctuator endings: !%&()*+,-./:;<=>?[]^{}|~
|
||||
return ch === 33/*!*/ || ch === 37/*%*/ || ch === 38/*&*/ ||
|
||||
ch > 39 && ch < 48 || ch > 57 && ch < 64 ||
|
||||
ch === 91/*[*/ || ch === 93/*]*/ || ch === 94/*^*/ ||
|
||||
ch > 122 && ch < 127;
|
||||
}
|
||||
|
||||
function isExpressionPunctuator (ch) {
|
||||
// 20 possible expression endings: !%&(*+,-.:;<=>?[^{|~
|
||||
return ch === 33/*!*/ || ch === 37/*%*/ || ch === 38/*&*/ ||
|
||||
ch > 39 && ch < 47 && ch !== 41 || ch > 57 && ch < 64 ||
|
||||
ch === 91/*[*/ || ch === 94/*^*/ || ch > 122 && ch < 127 && ch !== 125/*}*/;
|
||||
}
|
||||
|
||||
function isExpressionTerminator (curPos) {
|
||||
// detects:
|
||||
// => ; ) finally catch else
|
||||
// as all of these followed by a { will indicate a statement brace
|
||||
switch (source.charCodeAt(curPos)) {
|
||||
case 62/*>*/:
|
||||
return source.charCodeAt(curPos - 1) === 61/*=*/;
|
||||
case 59/*;*/:
|
||||
case 41/*)*/:
|
||||
return true;
|
||||
case 104/*h*/:
|
||||
return source.startsWith('catc', curPos - 4);
|
||||
case 121/*y*/:
|
||||
return source.startsWith('finall', curPos - 6);
|
||||
case 101/*e*/:
|
||||
return source.startsWith('els', curPos - 3);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function syntaxError () {
|
||||
throw Object.assign(new Error(`Parse error ${name}:${source.slice(0, pos).split('\n').length}:${pos - source.lastIndexOf('\n', pos - 1)}`), { idx: pos });
|
||||
}
|
Reference in New Issue
Block a user