@difizen/mana-core
Version:
1,303 lines (1,282 loc) • 46.5 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
/* eslint-disable no-fallthrough */
/* eslint-disable no-case-declarations */
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export var ScanError = /*#__PURE__*/function (ScanError) {
ScanError[ScanError["None"] = 0] = "None";
ScanError[ScanError["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
ScanError[ScanError["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
ScanError[ScanError["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
ScanError[ScanError["InvalidUnicode"] = 4] = "InvalidUnicode";
ScanError[ScanError["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
ScanError[ScanError["InvalidCharacter"] = 6] = "InvalidCharacter";
return ScanError;
}({});
export var SyntaxKind = /*#__PURE__*/function (SyntaxKind) {
SyntaxKind[SyntaxKind["OpenBraceToken"] = 1] = "OpenBraceToken";
SyntaxKind[SyntaxKind["CloseBraceToken"] = 2] = "CloseBraceToken";
SyntaxKind[SyntaxKind["OpenBracketToken"] = 3] = "OpenBracketToken";
SyntaxKind[SyntaxKind["CloseBracketToken"] = 4] = "CloseBracketToken";
SyntaxKind[SyntaxKind["CommaToken"] = 5] = "CommaToken";
SyntaxKind[SyntaxKind["ColonToken"] = 6] = "ColonToken";
SyntaxKind[SyntaxKind["NullKeyword"] = 7] = "NullKeyword";
SyntaxKind[SyntaxKind["TrueKeyword"] = 8] = "TrueKeyword";
SyntaxKind[SyntaxKind["FalseKeyword"] = 9] = "FalseKeyword";
SyntaxKind[SyntaxKind["StringLiteral"] = 10] = "StringLiteral";
SyntaxKind[SyntaxKind["NumericLiteral"] = 11] = "NumericLiteral";
SyntaxKind[SyntaxKind["LineCommentTrivia"] = 12] = "LineCommentTrivia";
SyntaxKind[SyntaxKind["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
SyntaxKind[SyntaxKind["LineBreakTrivia"] = 14] = "LineBreakTrivia";
SyntaxKind[SyntaxKind["Trivia"] = 15] = "Trivia";
SyntaxKind[SyntaxKind["Unknown"] = 16] = "Unknown";
SyntaxKind[SyntaxKind["EOF"] = 17] = "EOF";
return SyntaxKind;
}({});
/**
* The scanner object, representing a JSON scanner at a position in the input string.
*/
export var ParseErrorCode = /*#__PURE__*/function (ParseErrorCode) {
ParseErrorCode[ParseErrorCode["InvalidSymbol"] = 1] = "InvalidSymbol";
ParseErrorCode[ParseErrorCode["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
ParseErrorCode[ParseErrorCode["PropertyNameExpected"] = 3] = "PropertyNameExpected";
ParseErrorCode[ParseErrorCode["ValueExpected"] = 4] = "ValueExpected";
ParseErrorCode[ParseErrorCode["ColonExpected"] = 5] = "ColonExpected";
ParseErrorCode[ParseErrorCode["CommaExpected"] = 6] = "CommaExpected";
ParseErrorCode[ParseErrorCode["CloseBraceExpected"] = 7] = "CloseBraceExpected";
ParseErrorCode[ParseErrorCode["CloseBracketExpected"] = 8] = "CloseBracketExpected";
ParseErrorCode[ParseErrorCode["EndOfFileExpected"] = 9] = "EndOfFileExpected";
ParseErrorCode[ParseErrorCode["InvalidCommentToken"] = 10] = "InvalidCommentToken";
ParseErrorCode[ParseErrorCode["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
ParseErrorCode[ParseErrorCode["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
ParseErrorCode[ParseErrorCode["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
ParseErrorCode[ParseErrorCode["InvalidUnicode"] = 14] = "InvalidUnicode";
ParseErrorCode[ParseErrorCode["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
ParseErrorCode[ParseErrorCode["InvalidCharacter"] = 16] = "InvalidCharacter";
return ParseErrorCode;
}({});
export var ParseOptions;
(function (_ParseOptions) {
var DEFAULT = _ParseOptions.DEFAULT = {
allowTrailingComma: true
};
})(ParseOptions || (ParseOptions = {}));
/**
* Creates a JSON scanner on the given text.
* If ignoreTrivia is set, whitespaces or comments are ignored.
*/
export function createScanner(text) {
var ignoreTrivia = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var pos = 0;
var len = text.length;
var value = '';
var tokenOffset = 0;
var token = SyntaxKind.Unknown;
var scanError = ScanError.None;
function scanHexDigits(count) {
var digits = 0;
var hexValue = 0;
while (digits < count) {
var ch = text.charCodeAt(pos);
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
hexValue = hexValue * 16 + ch - CharacterCodes._0;
} else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
hexValue = hexValue * 16 + ch - CharacterCodes.A + 10;
} else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) {
hexValue = hexValue * 16 + ch - CharacterCodes.a + 10;
} else {
break;
}
pos++;
digits++;
}
if (digits < count) {
hexValue = -1;
}
return hexValue;
}
function setPosition(newPosition) {
pos = newPosition;
value = '';
tokenOffset = 0;
token = SyntaxKind.Unknown;
scanError = ScanError.None;
}
function scanNumber() {
var start = pos;
if (text.charCodeAt(pos) === CharacterCodes._0) {
pos++;
} else {
pos++;
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
pos++;
}
}
if (pos < text.length && text.charCodeAt(pos) === CharacterCodes.dot) {
pos++;
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
pos++;
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
pos++;
}
} else {
scanError = ScanError.UnexpectedEndOfNumber;
return text.substring(start, pos);
}
}
var end = pos;
if (pos < text.length && (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e)) {
pos++;
if (pos < text.length && text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) {
pos++;
}
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
pos++;
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
pos++;
}
end = pos;
} else {
scanError = ScanError.UnexpectedEndOfNumber;
}
}
return text.substring(start, end);
}
function scanString() {
var result = '';
var start = pos;
// eslint-disable-next-line no-constant-condition
while (true) {
if (pos >= len) {
result += text.substring(start, pos);
scanError = ScanError.UnexpectedEndOfString;
break;
}
var ch = text.charCodeAt(pos);
if (ch === CharacterCodes.doubleQuote) {
result += text.substring(start, pos);
pos++;
break;
}
if (ch === CharacterCodes.backslash) {
result += text.substring(start, pos);
pos++;
if (pos >= len) {
scanError = ScanError.UnexpectedEndOfString;
break;
}
var ch2 = text.charCodeAt(pos++);
switch (ch2) {
case CharacterCodes.doubleQuote:
result += '"';
break;
case CharacterCodes.backslash:
result += '\\';
break;
case CharacterCodes.slash:
result += '/';
break;
case CharacterCodes.b:
result += '\b';
break;
case CharacterCodes.f:
result += '\f';
break;
case CharacterCodes.n:
result += '\n';
break;
case CharacterCodes.r:
result += '\r';
break;
case CharacterCodes.t:
result += '\t';
break;
case CharacterCodes.u:
var ch3 = scanHexDigits(4);
if (ch3 >= 0) {
result += String.fromCharCode(ch3);
} else {
scanError = ScanError.InvalidUnicode;
}
break;
default:
scanError = ScanError.InvalidEscapeCharacter;
}
start = pos;
continue;
}
if (ch >= 0 && ch <= 0x1f) {
if (isLineBreak(ch)) {
result += text.substring(start, pos);
scanError = ScanError.UnexpectedEndOfString;
break;
} else {
scanError = ScanError.InvalidCharacter;
// mark as error but continue with string
}
}
pos++;
}
return result;
}
function scanNext() {
value = '';
scanError = ScanError.None;
tokenOffset = pos;
if (pos >= len) {
// at the end
tokenOffset = len;
return token = SyntaxKind.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 = SyntaxKind.Trivia;
}
// trivia: newlines
if (isLineBreak(code)) {
pos++;
value += String.fromCharCode(code);
if (code === CharacterCodes.carriageReturn && text.charCodeAt(pos) === CharacterCodes.lineFeed) {
pos++;
value += '\n';
}
return token = SyntaxKind.LineBreakTrivia;
}
switch (code) {
// tokens: []{}:,
case CharacterCodes.openBrace:
pos++;
return token = SyntaxKind.OpenBraceToken;
case CharacterCodes.closeBrace:
pos++;
return token = SyntaxKind.CloseBraceToken;
case CharacterCodes.openBracket:
pos++;
return token = SyntaxKind.OpenBracketToken;
case CharacterCodes.closeBracket:
pos++;
return token = SyntaxKind.CloseBracketToken;
case CharacterCodes.colon:
pos++;
return token = SyntaxKind.ColonToken;
case CharacterCodes.comma:
pos++;
return token = SyntaxKind.CommaToken;
// strings
case CharacterCodes.doubleQuote:
pos++;
value = scanString();
return token = SyntaxKind.StringLiteral;
// comments
case CharacterCodes.slash:
var start = pos - 1;
// Single-line comment
if (text.charCodeAt(pos + 1) === CharacterCodes.slash) {
pos += 2;
while (pos < len) {
if (isLineBreak(text.charCodeAt(pos))) {
break;
}
pos++;
}
value = text.substring(start, pos);
return token = SyntaxKind.LineCommentTrivia;
}
// Multi-line comment
if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) {
pos += 2;
var safeLength = len - 1; // For lookahead.
var commentClosed = false;
while (pos < safeLength) {
var ch = text.charCodeAt(pos);
if (ch === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) {
pos += 2;
commentClosed = true;
break;
}
pos++;
}
if (!commentClosed) {
pos++;
scanError = ScanError.UnexpectedEndOfComment;
}
value = text.substring(start, pos);
return token = SyntaxKind.BlockCommentTrivia;
}
// just a single slash
value += String.fromCharCode(code);
pos++;
return token = SyntaxKind.Unknown;
// numbers
case CharacterCodes.minus:
value += String.fromCharCode(code);
pos++;
if (pos === len || !isDigit(text.charCodeAt(pos))) {
return token = SyntaxKind.Unknown;
}
// found a minus, followed by a number so
// we fall through to proceed with scanning
// numbers
case CharacterCodes._0:
case CharacterCodes._1:
case CharacterCodes._2:
case CharacterCodes._3:
case CharacterCodes._4:
case CharacterCodes._5:
case CharacterCodes._6:
case CharacterCodes._7:
case CharacterCodes._8:
case CharacterCodes._9:
value += scanNumber();
return token = SyntaxKind.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 = SyntaxKind.TrueKeyword;
case 'false':
return token = SyntaxKind.FalseKeyword;
case 'null':
return token = SyntaxKind.NullKeyword;
}
return token = SyntaxKind.Unknown;
}
// some
value += String.fromCharCode(code);
pos++;
return token = SyntaxKind.Unknown;
}
}
function isUnknownContentCharacter(code) {
if (isWhitespace(code) || isLineBreak(code)) {
return false;
}
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (code) {
case CharacterCodes.closeBrace:
case CharacterCodes.closeBracket:
case CharacterCodes.openBrace:
case CharacterCodes.openBracket:
case CharacterCodes.doubleQuote:
case CharacterCodes.colon:
case CharacterCodes.comma:
case CharacterCodes.slash:
return false;
}
return true;
}
function scanNextNonTrivia() {
var result;
do {
result = scanNext();
} while (result >= SyntaxKind.LineCommentTrivia && result <= SyntaxKind.Trivia);
return result;
}
return {
setPosition: setPosition,
getPosition: function getPosition() {
return pos;
},
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
getToken: function getToken() {
return token;
},
getTokenValue: function getTokenValue() {
return value;
},
getTokenOffset: function getTokenOffset() {
return tokenOffset;
},
getTokenLength: function getTokenLength() {
return pos - tokenOffset;
},
getTokenError: function getTokenError() {
return scanError;
}
};
}
function isWhitespace(ch) {
return ch === CharacterCodes.space || ch === CharacterCodes.tab || ch === CharacterCodes.verticalTab || ch === CharacterCodes.formFeed || ch === CharacterCodes.nonBreakingSpace || ch === CharacterCodes.ogham || ch >= CharacterCodes.enQuad && ch <= CharacterCodes.zeroWidthSpace || ch === CharacterCodes.narrowNoBreakSpace || ch === CharacterCodes.mathematicalSpace || ch === CharacterCodes.ideographicSpace || ch === CharacterCodes.byteOrderMark;
}
function isLineBreak(ch) {
return ch === CharacterCodes.lineFeed || ch === CharacterCodes.carriageReturn || ch === CharacterCodes.lineSeparator || ch === CharacterCodes.paragraphSeparator;
}
function isDigit(ch) {
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
}
var CharacterCodes = /*#__PURE__*/function (CharacterCodes) {
CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
// \n
CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
// \r
CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
// REVIEW: do we need to support this? The scanner doesn't, but our IText does. This seems
// like an odd disparity? (Or maybe it's completely fine for them to be different).
CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
// Unicode 3.0 space characters
CharacterCodes[CharacterCodes["space"] = 32] = "space";
// " "
CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
//
CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
CharacterCodes[CharacterCodes["_"] = 95] = "_";
CharacterCodes[CharacterCodes["$"] = 36] = "$";
CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
CharacterCodes[CharacterCodes["a"] = 97] = "a";
CharacterCodes[CharacterCodes["b"] = 98] = "b";
CharacterCodes[CharacterCodes["c"] = 99] = "c";
CharacterCodes[CharacterCodes["d"] = 100] = "d";
CharacterCodes[CharacterCodes["e"] = 101] = "e";
CharacterCodes[CharacterCodes["f"] = 102] = "f";
CharacterCodes[CharacterCodes["g"] = 103] = "g";
CharacterCodes[CharacterCodes["h"] = 104] = "h";
CharacterCodes[CharacterCodes["i"] = 105] = "i";
CharacterCodes[CharacterCodes["j"] = 106] = "j";
CharacterCodes[CharacterCodes["k"] = 107] = "k";
CharacterCodes[CharacterCodes["l"] = 108] = "l";
CharacterCodes[CharacterCodes["m"] = 109] = "m";
CharacterCodes[CharacterCodes["n"] = 110] = "n";
CharacterCodes[CharacterCodes["o"] = 111] = "o";
CharacterCodes[CharacterCodes["p"] = 112] = "p";
CharacterCodes[CharacterCodes["q"] = 113] = "q";
CharacterCodes[CharacterCodes["r"] = 114] = "r";
CharacterCodes[CharacterCodes["s"] = 115] = "s";
CharacterCodes[CharacterCodes["t"] = 116] = "t";
CharacterCodes[CharacterCodes["u"] = 117] = "u";
CharacterCodes[CharacterCodes["v"] = 118] = "v";
CharacterCodes[CharacterCodes["w"] = 119] = "w";
CharacterCodes[CharacterCodes["x"] = 120] = "x";
CharacterCodes[CharacterCodes["y"] = 121] = "y";
CharacterCodes[CharacterCodes["z"] = 122] = "z";
CharacterCodes[CharacterCodes["A"] = 65] = "A";
CharacterCodes[CharacterCodes["B"] = 66] = "B";
CharacterCodes[CharacterCodes["C"] = 67] = "C";
CharacterCodes[CharacterCodes["D"] = 68] = "D";
CharacterCodes[CharacterCodes["E"] = 69] = "E";
CharacterCodes[CharacterCodes["F"] = 70] = "F";
CharacterCodes[CharacterCodes["G"] = 71] = "G";
CharacterCodes[CharacterCodes["H"] = 72] = "H";
CharacterCodes[CharacterCodes["I"] = 73] = "I";
CharacterCodes[CharacterCodes["J"] = 74] = "J";
CharacterCodes[CharacterCodes["K"] = 75] = "K";
CharacterCodes[CharacterCodes["L"] = 76] = "L";
CharacterCodes[CharacterCodes["M"] = 77] = "M";
CharacterCodes[CharacterCodes["N"] = 78] = "N";
CharacterCodes[CharacterCodes["O"] = 79] = "O";
CharacterCodes[CharacterCodes["P"] = 80] = "P";
CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
CharacterCodes[CharacterCodes["R"] = 82] = "R";
CharacterCodes[CharacterCodes["S"] = 83] = "S";
CharacterCodes[CharacterCodes["T"] = 84] = "T";
CharacterCodes[CharacterCodes["U"] = 85] = "U";
CharacterCodes[CharacterCodes["V"] = 86] = "V";
CharacterCodes[CharacterCodes["W"] = 87] = "W";
CharacterCodes[CharacterCodes["X"] = 88] = "X";
CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
// &
CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
// *
CharacterCodes[CharacterCodes["at"] = 64] = "at";
// @
CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
// \
CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
// |
CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
// ^
CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
// }
CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
// ]
CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
// )
CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
// :
CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
// ,
CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
// .
CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
// "
CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
// =
CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
// !
CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
// >
CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
// <
CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
// -
CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
// {
CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
// [
CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
// (
CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
// %
CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
// +
CharacterCodes[CharacterCodes["question"] = 63] = "question";
// ?
CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
// ;
CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
// '
CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
// /
CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
// ~
CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
// \b
CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
// \f
CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
// \t
CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
return CharacterCodes;
}(CharacterCodes || {}); // \v
/**
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
*/
export function getLocation(text, position) {
var segments = []; // strings or numbers
// eslint-disable-next-line no-new-object
var earlyReturnException = new Object();
var previousNode;
var previousNodeInst = {
value: {},
offset: 0,
length: 0,
type: 'object',
parent: undefined
};
var isAtPropertyKey = false;
function setPreviousNode(value, offset, length, type) {
previousNodeInst.value = value;
previousNodeInst.offset = offset;
previousNodeInst.length = length;
previousNodeInst.type = type;
previousNodeInst.colonOffset = undefined;
previousNode = previousNodeInst;
}
try {
visit(text, {
onObjectBegin: function onObjectBegin(offset, _length) {
if (position <= offset) {
throw earlyReturnException;
}
previousNode = undefined;
isAtPropertyKey = position > offset;
segments.push(''); // push a placeholder (will be replaced)
},
onObjectProperty: function onObjectProperty(name, offset, length) {
if (position < offset) {
throw earlyReturnException;
}
setPreviousNode(name, offset, length, 'property');
segments[segments.length - 1] = name;
if (position <= offset + length) {
throw earlyReturnException;
}
},
onObjectEnd: function onObjectEnd(offset, _length) {
if (position <= offset) {
throw earlyReturnException;
}
previousNode = undefined;
segments.pop();
},
onArrayBegin: function onArrayBegin(offset, _length) {
if (position <= offset) {
throw earlyReturnException;
}
previousNode = undefined;
segments.push(0);
},
onArrayEnd: function onArrayEnd(offset, _length) {
if (position <= offset) {
throw earlyReturnException;
}
previousNode = undefined;
segments.pop();
},
onLiteralValue: function onLiteralValue(value, offset, length) {
if (position < offset) {
throw earlyReturnException;
}
setPreviousNode(value, offset, length, getNodeType(value));
if (position <= offset + length) {
throw earlyReturnException;
}
},
onSeparator: function onSeparator(sep, offset, _length) {
if (position <= offset) {
throw earlyReturnException;
}
if (sep === ':' && previousNode && previousNode.type === 'property') {
previousNode.colonOffset = offset;
isAtPropertyKey = false;
previousNode = undefined;
} else if (sep === ',') {
var last = segments[segments.length - 1];
if (typeof last === 'number') {
segments[segments.length - 1] = last + 1;
} else {
isAtPropertyKey = true;
segments[segments.length - 1] = '';
}
previousNode = undefined;
}
}
});
} catch (e) {
if (e !== earlyReturnException) {
throw e;
}
}
return {
path: segments,
previousNode: previousNode,
isAtPropertyKey: isAtPropertyKey,
matches: function matches(pattern) {
var k = 0;
for (var i = 0; k < pattern.length && i < segments.length; i++) {
if (pattern[k] === segments[i] || pattern[k] === '*') {
k++;
} else if (pattern[k] !== '**') {
return false;
}
}
return k === pattern.length;
}
};
}
/**
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
* Therefore always check the errors list to find out if the input was valid.
*/
export function parse(text) {
var errors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ParseOptions.DEFAULT;
var currentProperty = null;
var currentParent = [];
var previousParents = [];
function onValue(value) {
if (Array.isArray(currentParent)) {
currentParent.push(value);
} else if (currentProperty !== null) {
currentParent[currentProperty] = value;
}
}
var visitor = {
onObjectBegin: function onObjectBegin() {
var object = {};
onValue(object);
previousParents.push(currentParent);
currentParent = object;
currentProperty = null;
},
onObjectProperty: function onObjectProperty(name) {
currentProperty = name;
},
onObjectEnd: function onObjectEnd() {
currentParent = previousParents.pop();
},
onArrayBegin: function onArrayBegin() {
var array = [];
onValue(array);
previousParents.push(currentParent);
currentParent = array;
currentProperty = null;
},
onArrayEnd: function onArrayEnd() {
currentParent = previousParents.pop();
},
onLiteralValue: onValue,
onError: function onError(error, offset, length) {
errors.push({
error: error,
offset: offset,
length: length
});
}
};
visit(text, visitor, options);
return currentParent[0];
}
/**
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
*/
export function parseTree(text) {
var errors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ParseOptions.DEFAULT;
var currentParent = {
type: 'array',
offset: -1,
length: -1,
children: [],
parent: undefined
}; // artificial root
function ensurePropertyComplete(endOffset) {
if (currentParent.type === 'property') {
currentParent.length = endOffset - currentParent.offset;
currentParent = currentParent.parent;
}
}
function onValue(valueNode) {
currentParent.children.push(valueNode);
return valueNode;
}
var visitor = {
onObjectBegin: function onObjectBegin(offset) {
currentParent = onValue({
type: 'object',
offset: offset,
length: -1,
parent: currentParent,
children: []
});
},
onObjectProperty: function onObjectProperty(name, offset, length) {
currentParent = onValue({
type: 'property',
offset: offset,
length: -1,
parent: currentParent,
children: []
});
currentParent.children.push({
type: 'string',
value: name,
offset: offset,
length: length,
parent: currentParent
});
},
onObjectEnd: function onObjectEnd(offset, length) {
currentParent.length = offset + length - currentParent.offset;
currentParent = currentParent.parent;
ensurePropertyComplete(offset + length);
},
onArrayBegin: function onArrayBegin(offset, _length) {
currentParent = onValue({
type: 'array',
offset: offset,
length: -1,
parent: currentParent,
children: []
});
},
onArrayEnd: function onArrayEnd(offset, length) {
currentParent.length = offset + length - currentParent.offset;
currentParent = currentParent.parent;
ensurePropertyComplete(offset + length);
},
onLiteralValue: function onLiteralValue(value, offset, length) {
onValue({
type: getNodeType(value),
offset: offset,
length: length,
parent: currentParent,
value: value
});
ensurePropertyComplete(offset + length);
},
onSeparator: function onSeparator(sep, offset, _length) {
if (currentParent.type === 'property') {
if (sep === ':') {
currentParent.colonOffset = offset;
} else if (sep === ',') {
ensurePropertyComplete(offset);
}
}
},
onError: function onError(error, offset, length) {
errors.push({
error: error,
offset: offset,
length: length
});
}
};
visit(text, visitor, options);
var result = currentParent.children[0];
if (result) {
delete result.parent;
}
return result;
}
/**
* Finds the node at the given path in a JSON DOM.
*/
export function findNodeAtLocation(root, path) {
if (!root) {
return undefined;
}
var node = root;
var _iterator = _createForOfIteratorHelper(path),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var segment = _step.value;
if (typeof segment === 'string') {
if (node.type !== 'object' || !Array.isArray(node.children)) {
return undefined;
}
var found = false;
var _iterator2 = _createForOfIteratorHelper(node.children),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var propertyNode = _step2.value;
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment) {
// eslint-disable-next-line prefer-destructuring
node = propertyNode.children[1];
found = true;
break;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
if (!found) {
return undefined;
}
} else {
var index = segment;
if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
return undefined;
}
node = node.children[index];
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return node;
}
/**
* Gets the JSON path of the given JSON DOM node
*/
export function getNodePath(node) {
if (!node.parent || !node.parent.children) {
return [];
}
var path = getNodePath(node.parent);
if (node.parent.type === 'property') {
var key = node.parent.children[0].value;
path.push(key);
} else if (node.parent.type === 'array') {
var index = node.parent.children.indexOf(node);
if (index !== -1) {
path.push(index);
}
}
return path;
}
/**
* Evaluates the JavaScript object of the given JSON DOM node
*/
export function getNodeValue(node) {
switch (node.type) {
case 'array':
return node.children.map(getNodeValue);
case 'object':
var obj = Object.create(null);
var _iterator3 = _createForOfIteratorHelper(node.children),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var prop = _step3.value;
var valueNode = prop.children[1];
if (valueNode) {
obj[prop.children[0].value] = getNodeValue(valueNode);
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
return obj;
case 'null':
case 'string':
case 'number':
case 'boolean':
return node.value;
default:
return undefined;
}
}
export function contains(node, offset) {
var includeRightBound = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
return offset >= node.offset && offset < node.offset + node.length || includeRightBound && offset === node.offset + node.length;
}
/**
* Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
*/
export function findNodeAtOffset(node, offset) {
var includeRightBound = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (contains(node, offset, includeRightBound)) {
var children = node.children;
if (Array.isArray(children)) {
for (var i = 0; i < children.length && children[i].offset <= offset; i++) {
var item = findNodeAtOffset(children[i], offset, includeRightBound);
if (item) {
return item;
}
}
}
return node;
}
return undefined;
}
/**
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
*/
export function visit(text, visitor) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ParseOptions.DEFAULT;
var _scanner = createScanner(text, false);
function toNoArgVisit(visitFunction) {
return visitFunction ? function () {
return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength());
} : function () {
return true;
};
}
function toOneArgVisit(visitFunction) {
return visitFunction ? function (arg) {
return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength());
} : function () {
return true;
};
}
var onObjectBegin = toNoArgVisit(visitor.onObjectBegin);
var onObjectProperty = toOneArgVisit(visitor.onObjectProperty);
var onObjectEnd = toNoArgVisit(visitor.onObjectEnd);
var onArrayBegin = toNoArgVisit(visitor.onArrayBegin);
var onArrayEnd = toNoArgVisit(visitor.onArrayEnd);
var onLiteralValue = toOneArgVisit(visitor.onLiteralValue);
var onSeparator = toOneArgVisit(visitor.onSeparator);
var onComment = toNoArgVisit(visitor.onComment);
var onError = toOneArgVisit(visitor.onError);
var disallowComments = options && options.disallowComments;
var allowTrailingComma = options && options.allowTrailingComma;
function scanNext() {
// eslint-disable-next-line no-constant-condition
while (true) {
var token = _scanner.scan();
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (_scanner.getTokenError()) {
case ScanError.InvalidUnicode:
handleError(ParseErrorCode.InvalidUnicode);
break;
case ScanError.InvalidEscapeCharacter:
handleError(ParseErrorCode.InvalidEscapeCharacter);
break;
case ScanError.UnexpectedEndOfNumber:
handleError(ParseErrorCode.UnexpectedEndOfNumber);
break;
case ScanError.UnexpectedEndOfComment:
if (!disallowComments) {
handleError(ParseErrorCode.UnexpectedEndOfComment);
}
break;
case ScanError.UnexpectedEndOfString:
handleError(ParseErrorCode.UnexpectedEndOfString);
break;
case ScanError.InvalidCharacter:
handleError(ParseErrorCode.InvalidCharacter);
break;
}
switch (token) {
case SyntaxKind.LineCommentTrivia:
case SyntaxKind.BlockCommentTrivia:
if (disallowComments) {
handleError(ParseErrorCode.InvalidCommentToken);
} else {
onComment();
}
break;
case SyntaxKind.Unknown:
handleError(ParseErrorCode.InvalidSymbol);
break;
case SyntaxKind.Trivia:
case SyntaxKind.LineBreakTrivia:
break;
default:
return token;
}
}
}
function handleError(error) {
var skipUntilAfter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var skipUntil = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
onError(error);
if (skipUntilAfter.length + skipUntil.length > 0) {
var token = _scanner.getToken();
while (token !== SyntaxKind.EOF) {
if (skipUntilAfter.indexOf(token) !== -1) {
scanNext();
break;
} else if (skipUntil.indexOf(token) !== -1) {
break;
}
token = scanNext();
}
}
}
function parseString(isValue) {
var value = _scanner.getTokenValue();
if (isValue) {
onLiteralValue(value);
} else {
onObjectProperty(value);
}
scanNext();
return true;
}
function parseLiteral() {
switch (_scanner.getToken()) {
case SyntaxKind.NumericLiteral:
var _value = 0;
try {
_value = JSON.parse(_scanner.getTokenValue());
if (typeof _value !== 'number') {
handleError(ParseErrorCode.InvalidNumberFormat);
_value = 0;
}
} catch (e) {
handleError(ParseErrorCode.InvalidNumberFormat);
}
onLiteralValue(_value);
break;
case SyntaxKind.NullKeyword:
onLiteralValue(null);
break;
case SyntaxKind.TrueKeyword:
onLiteralValue(true);
break;
case SyntaxKind.FalseKeyword:
onLiteralValue(false);
break;
default:
return false;
}
scanNext();
return true;
}
function parseProperty() {
if (_scanner.getToken() !== SyntaxKind.StringLiteral) {
handleError(ParseErrorCode.PropertyNameExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]);
return false;
}
parseString(false);
if (_scanner.getToken() === SyntaxKind.ColonToken) {
onSeparator(':');
scanNext(); // consume colon
if (!parseValue()) {
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]);
}
} else {
handleError(ParseErrorCode.ColonExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]);
}
return true;
}
function parseObject() {
onObjectBegin();
scanNext(); // consume open brace
var needsComma = false;
while (_scanner.getToken() !== SyntaxKind.CloseBraceToken && _scanner.getToken() !== SyntaxKind.EOF) {
if (_scanner.getToken() === SyntaxKind.CommaToken) {
if (!needsComma) {
handleError(ParseErrorCode.ValueExpected, [], []);
}
onSeparator(',');
scanNext(); // consume comma
if (_scanner.getToken() === SyntaxKind.CloseBraceToken && allowTrailingComma) {
break;
}
} else if (needsComma) {
handleError(ParseErrorCode.CommaExpected, [], []);
}
if (!parseProperty()) {
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]);
}
needsComma = true;
}
onObjectEnd();
if (_scanner.getToken() !== SyntaxKind.CloseBraceToken) {
handleError(ParseErrorCode.CloseBraceExpected, [SyntaxKind.CloseBraceToken], []);
} else {
scanNext(); // consume close brace
}
return true;
}
function parseArray() {
onArrayBegin();
scanNext(); // consume open bracket
var needsComma = false;
while (_scanner.getToken() !== SyntaxKind.CloseBracketToken && _scanner.getToken() !== SyntaxKind.EOF) {
if (_scanner.getToken() === SyntaxKind.CommaToken) {
if (!needsComma) {
handleError(ParseErrorCode.ValueExpected, [], []);
}
onSeparator(',');
scanNext(); // consume comma
if (_scanner.getToken() === SyntaxKind.CloseBracketToken && allowTrailingComma) {
break;
}
} else if (needsComma) {
handleError(ParseErrorCode.CommaExpected, [], []);
}
if (!parseValue()) {
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken]);
}
needsComma = true;
}
onArrayEnd();
if (_scanner.getToken() !== SyntaxKind.CloseBracketToken) {
handleError(ParseErrorCode.CloseBracketExpected, [SyntaxKind.CloseBracketToken], []);
} else {
scanNext(); // consume close bracket
}
return true;
}
function parseValue() {
switch (_scanner.getToken()) {
case SyntaxKind.OpenBracketToken:
return parseArray();
case SyntaxKind.OpenBraceToken:
return parseObject();
case SyntaxKind.StringLiteral:
return parseString(true);
default:
return parseLiteral();
}
}
scanNext();
if (_scanner.getToken() === SyntaxKind.EOF) {
if (options.allowEmptyContent) {
return true;
}
handleError(ParseErrorCode.ValueExpected, [], []);
return false;
}
if (!parseValue()) {
handleError(ParseErrorCode.ValueExpected, [], []);
return false;
}
if (_scanner.getToken() !== SyntaxKind.EOF) {
handleError(ParseErrorCode.EndOfFileExpected, [], []);
}
return true;
}
/**
* Takes JSON with JavaScript-style comments and remove
* them. Optionally replaces every none-newline character
* of comments with a replaceCharacter
*/
export function stripComments(text, replaceCh) {
var _scanner = createScanner(text);
var parts = [];
var kind;
var offset = 0;
var pos;
do {
pos = _scanner.getPosition();
kind = _scanner.scan();
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (kind) {
case SyntaxKind.LineCommentTrivia:
case SyntaxKind.BlockCommentTrivia:
case SyntaxKind.EOF:
if (offset !== pos) {
parts.push(text.substring(offset, pos));
}
if (replaceCh !== undefined) {
parts.push(_scanner.getTokenValue().replace(/[^\r\n]/g, replaceCh));
}
offset = _scanner.getPosition();
break;
}
} while (kind !== SyntaxKind.EOF);
return parts.join('');
}
export function getNodeType(value) {
switch (_typeof(value)) {
case 'boolean':
return 'boolean';
case 'number':
return 'number';
case 'string':
return 'string';
case 'object':
{
if (!value) {
return 'null';
}
if (Array.isArray(value)) {
return 'array';
}
return 'object';
}
default:
return 'null';
}
}