This commit is contained in:
363
node_modules/jsonc-parser/lib/esm/impl/scanner.js
generated
vendored
Normal file
363
node_modules/jsonc-parser/lib/esm/impl/scanner.js
generated
vendored
Normal file
@@ -0,0 +1,363 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export function createScanner(text, ignoreTrivia) {
|
||||
if (ignoreTrivia === void 0) { ignoreTrivia = false; }
|
||||
var len = text.length;
|
||||
var pos = 0, value = '', tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */;
|
||||
function scanHexDigits(count, exact) {
|
||||
var digits = 0;
|
||||
var value = 0;
|
||||
while (digits < count || !exact) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
|
||||
value = value * 16 + ch - 48 /* _0 */;
|
||||
}
|
||||
else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
|
||||
value = value * 16 + ch - 65 /* A */ + 10;
|
||||
}
|
||||
else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
|
||||
value = value * 16 + ch - 97 /* a */ + 10;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
digits++;
|
||||
}
|
||||
if (digits < count) {
|
||||
value = -1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function setPosition(newPosition) {
|
||||
pos = newPosition;
|
||||
value = '';
|
||||
tokenOffset = 0;
|
||||
token = 16 /* Unknown */;
|
||||
scanError = 0 /* None */;
|
||||
}
|
||||
function scanNumber() {
|
||||
var start = pos;
|
||||
if (text.charCodeAt(pos) === 48 /* _0 */) {
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) {
|
||||
pos++;
|
||||
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scanError = 3 /* UnexpectedEndOfNumber */;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
}
|
||||
var end = pos;
|
||||
if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) {
|
||||
pos++;
|
||||
if (pos < text.length && text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) {
|
||||
pos++;
|
||||
}
|
||||
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
end = pos;
|
||||
}
|
||||
else {
|
||||
scanError = 3 /* UnexpectedEndOfNumber */;
|
||||
}
|
||||
}
|
||||
return text.substring(start, end);
|
||||
}
|
||||
function scanString() {
|
||||
var result = '', start = pos;
|
||||
while (true) {
|
||||
if (pos >= len) {
|
||||
result += text.substring(start, pos);
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch === 34 /* doubleQuote */) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
if (ch === 92 /* backslash */) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
if (pos >= len) {
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
var ch2 = text.charCodeAt(pos++);
|
||||
switch (ch2) {
|
||||
case 34 /* doubleQuote */:
|
||||
result += '\"';
|
||||
break;
|
||||
case 92 /* backslash */:
|
||||
result += '\\';
|
||||
break;
|
||||
case 47 /* slash */:
|
||||
result += '/';
|
||||
break;
|
||||
case 98 /* b */:
|
||||
result += '\b';
|
||||
break;
|
||||
case 102 /* f */:
|
||||
result += '\f';
|
||||
break;
|
||||
case 110 /* n */:
|
||||
result += '\n';
|
||||
break;
|
||||
case 114 /* r */:
|
||||
result += '\r';
|
||||
break;
|
||||
case 116 /* t */:
|
||||
result += '\t';
|
||||
break;
|
||||
case 117 /* u */:
|
||||
var ch3 = scanHexDigits(4, true);
|
||||
if (ch3 >= 0) {
|
||||
result += String.fromCharCode(ch3);
|
||||
}
|
||||
else {
|
||||
scanError = 4 /* InvalidUnicode */;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
scanError = 5 /* InvalidEscapeCharacter */;
|
||||
}
|
||||
start = pos;
|
||||
continue;
|
||||
}
|
||||
if (ch >= 0 && ch <= 0x1f) {
|
||||
if (isLineBreak(ch)) {
|
||||
result += text.substring(start, pos);
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
scanError = 6 /* InvalidCharacter */;
|
||||
// mark as error but continue with string
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function scanNext() {
|
||||
value = '';
|
||||
scanError = 0 /* None */;
|
||||
tokenOffset = pos;
|
||||
lineStartOffset = lineNumber;
|
||||
prevTokenLineStartOffset = tokenLineStartOffset;
|
||||
if (pos >= len) {
|
||||
// at the end
|
||||
tokenOffset = len;
|
||||
return token = 17 /* EOF */;
|
||||
}
|
||||
var code = text.charCodeAt(pos);
|
||||
// trivia: whitespace
|
||||
if (isWhiteSpace(code)) {
|
||||
do {
|
||||
pos++;
|
||||
value += String.fromCharCode(code);
|
||||
code = text.charCodeAt(pos);
|
||||
} while (isWhiteSpace(code));
|
||||
return token = 15 /* Trivia */;
|
||||
}
|
||||
// trivia: newlines
|
||||
if (isLineBreak(code)) {
|
||||
pos++;
|
||||
value += String.fromCharCode(code);
|
||||
if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
||||
pos++;
|
||||
value += '\n';
|
||||
}
|
||||
lineNumber++;
|
||||
tokenLineStartOffset = pos;
|
||||
return token = 14 /* LineBreakTrivia */;
|
||||
}
|
||||
switch (code) {
|
||||
// tokens: []{}:,
|
||||
case 123 /* openBrace */:
|
||||
pos++;
|
||||
return token = 1 /* OpenBraceToken */;
|
||||
case 125 /* closeBrace */:
|
||||
pos++;
|
||||
return token = 2 /* CloseBraceToken */;
|
||||
case 91 /* openBracket */:
|
||||
pos++;
|
||||
return token = 3 /* OpenBracketToken */;
|
||||
case 93 /* closeBracket */:
|
||||
pos++;
|
||||
return token = 4 /* CloseBracketToken */;
|
||||
case 58 /* colon */:
|
||||
pos++;
|
||||
return token = 6 /* ColonToken */;
|
||||
case 44 /* comma */:
|
||||
pos++;
|
||||
return token = 5 /* CommaToken */;
|
||||
// strings
|
||||
case 34 /* doubleQuote */:
|
||||
pos++;
|
||||
value = scanString();
|
||||
return token = 10 /* StringLiteral */;
|
||||
// comments
|
||||
case 47 /* slash */:
|
||||
var start = pos - 1;
|
||||
// Single-line comment
|
||||
if (text.charCodeAt(pos + 1) === 47 /* slash */) {
|
||||
pos += 2;
|
||||
while (pos < len) {
|
||||
if (isLineBreak(text.charCodeAt(pos))) {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
value = text.substring(start, pos);
|
||||
return token = 12 /* LineCommentTrivia */;
|
||||
}
|
||||
// Multi-line comment
|
||||
if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
|
||||
pos += 2;
|
||||
var safeLength = len - 1; // For lookahead.
|
||||
var commentClosed = false;
|
||||
while (pos < safeLength) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
|
||||
pos += 2;
|
||||
commentClosed = true;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
if (isLineBreak(ch)) {
|
||||
if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
||||
pos++;
|
||||
}
|
||||
lineNumber++;
|
||||
tokenLineStartOffset = pos;
|
||||
}
|
||||
}
|
||||
if (!commentClosed) {
|
||||
pos++;
|
||||
scanError = 1 /* UnexpectedEndOfComment */;
|
||||
}
|
||||
value = text.substring(start, pos);
|
||||
return token = 13 /* BlockCommentTrivia */;
|
||||
}
|
||||
// just a single slash
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
return token = 16 /* Unknown */;
|
||||
// numbers
|
||||
case 45 /* minus */:
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
// found a minus, followed by a number so
|
||||
// we fall through to proceed with scanning
|
||||
// numbers
|
||||
case 48 /* _0 */:
|
||||
case 49 /* _1 */:
|
||||
case 50 /* _2 */:
|
||||
case 51 /* _3 */:
|
||||
case 52 /* _4 */:
|
||||
case 53 /* _5 */:
|
||||
case 54 /* _6 */:
|
||||
case 55 /* _7 */:
|
||||
case 56 /* _8 */:
|
||||
case 57 /* _9 */:
|
||||
value += scanNumber();
|
||||
return token = 11 /* NumericLiteral */;
|
||||
// literals and unknown symbols
|
||||
default:
|
||||
// is a literal? Read the full word.
|
||||
while (pos < len && isUnknownContentCharacter(code)) {
|
||||
pos++;
|
||||
code = text.charCodeAt(pos);
|
||||
}
|
||||
if (tokenOffset !== pos) {
|
||||
value = text.substring(tokenOffset, pos);
|
||||
// keywords: true, false, null
|
||||
switch (value) {
|
||||
case 'true': return token = 8 /* TrueKeyword */;
|
||||
case 'false': return token = 9 /* FalseKeyword */;
|
||||
case 'null': return token = 7 /* NullKeyword */;
|
||||
}
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
// some
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
}
|
||||
function isUnknownContentCharacter(code) {
|
||||
if (isWhiteSpace(code) || isLineBreak(code)) {
|
||||
return false;
|
||||
}
|
||||
switch (code) {
|
||||
case 125 /* closeBrace */:
|
||||
case 93 /* closeBracket */:
|
||||
case 123 /* openBrace */:
|
||||
case 91 /* openBracket */:
|
||||
case 34 /* doubleQuote */:
|
||||
case 58 /* colon */:
|
||||
case 44 /* comma */:
|
||||
case 47 /* slash */:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function scanNextNonTrivia() {
|
||||
var result;
|
||||
do {
|
||||
result = scanNext();
|
||||
} while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */);
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
setPosition: setPosition,
|
||||
getPosition: function () { return pos; },
|
||||
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
||||
getToken: function () { return token; },
|
||||
getTokenValue: function () { return value; },
|
||||
getTokenOffset: function () { return tokenOffset; },
|
||||
getTokenLength: function () { return pos - tokenOffset; },
|
||||
getTokenStartLine: function () { return lineStartOffset; },
|
||||
getTokenStartCharacter: function () { return tokenOffset - prevTokenLineStartOffset; },
|
||||
getTokenError: function () { return scanError; },
|
||||
};
|
||||
}
|
||||
function isWhiteSpace(ch) {
|
||||
return ch === 32 /* space */ || ch === 9 /* tab */ || ch === 11 /* verticalTab */ || ch === 12 /* formFeed */ ||
|
||||
ch === 160 /* nonBreakingSpace */ || ch === 5760 /* ogham */ || ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ ||
|
||||
ch === 8239 /* narrowNoBreakSpace */ || ch === 8287 /* mathematicalSpace */ || ch === 12288 /* ideographicSpace */ || ch === 65279 /* byteOrderMark */;
|
||||
}
|
||||
function isLineBreak(ch) {
|
||||
return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */;
|
||||
}
|
||||
function isDigit(ch) {
|
||||
return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
|
||||
}
|
||||
Reference in New Issue
Block a user