UNPKG

@difizen/mana-core

Version:

1,318 lines (1,299 loc) 47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SyntaxKind = exports.ScanError = exports.ParseOptions = exports.ParseErrorCode = void 0; exports.contains = contains; exports.createScanner = createScanner; exports.findNodeAtLocation = findNodeAtLocation; exports.findNodeAtOffset = findNodeAtOffset; exports.getLocation = getLocation; exports.getNodePath = getNodePath; exports.getNodeType = getNodeType; exports.getNodeValue = getNodeValue; exports.parse = parse; exports.parseTree = parseTree; exports.stripComments = stripComments; exports.visit = visit; 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. *--------------------------------------------------------------------------------------------*/ var ScanError = exports.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; }({}); var SyntaxKind = exports.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. */ var ParseErrorCode = exports.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; }({}); var ParseOptions; (function (_ParseOptions) { var DEFAULT = _ParseOptions.DEFAULT = { allowTrailingComma: true }; })(ParseOptions || (exports.ParseOptions = ParseOptions = {})); /** * Creates a JSON scanner on the given text. * If ignoreTrivia is set, whitespaces or comments are ignored. */ 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. */ 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. */ 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. */ 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. */ 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 */ 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 */ 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; } } 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. */ 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. */ 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 */ 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(''); } 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'; } }