123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- /*---------------------------------------------------------------------------------------------
- * 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 = false) {
- const len = text.length;
- let pos = 0, value = '', tokenOffset = 0, token = 16 /* SyntaxKind.Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* ScanError.None */;
- function scanHexDigits(count, exact) {
- let digits = 0;
- let value = 0;
- while (digits < count || !exact) {
- let ch = text.charCodeAt(pos);
- if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) {
- value = value * 16 + ch - 48 /* CharacterCodes._0 */;
- }
- else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) {
- value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10;
- }
- else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) {
- value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10;
- }
- else {
- break;
- }
- pos++;
- digits++;
- }
- if (digits < count) {
- value = -1;
- }
- return value;
- }
- function setPosition(newPosition) {
- pos = newPosition;
- value = '';
- tokenOffset = 0;
- token = 16 /* SyntaxKind.Unknown */;
- scanError = 0 /* ScanError.None */;
- }
- function scanNumber() {
- let start = pos;
- if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) {
- pos++;
- }
- else {
- pos++;
- while (pos < text.length && isDigit(text.charCodeAt(pos))) {
- pos++;
- }
- }
- if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) {
- pos++;
- if (pos < text.length && isDigit(text.charCodeAt(pos))) {
- pos++;
- while (pos < text.length && isDigit(text.charCodeAt(pos))) {
- pos++;
- }
- }
- else {
- scanError = 3 /* ScanError.UnexpectedEndOfNumber */;
- return text.substring(start, pos);
- }
- }
- let end = pos;
- if (pos < text.length && (text.charCodeAt(pos) === 69 /* CharacterCodes.E */ || text.charCodeAt(pos) === 101 /* CharacterCodes.e */)) {
- pos++;
- if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* 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 = 3 /* ScanError.UnexpectedEndOfNumber */;
- }
- }
- return text.substring(start, end);
- }
- function scanString() {
- let result = '', start = pos;
- while (true) {
- if (pos >= len) {
- result += text.substring(start, pos);
- scanError = 2 /* ScanError.UnexpectedEndOfString */;
- break;
- }
- const ch = text.charCodeAt(pos);
- if (ch === 34 /* CharacterCodes.doubleQuote */) {
- result += text.substring(start, pos);
- pos++;
- break;
- }
- if (ch === 92 /* CharacterCodes.backslash */) {
- result += text.substring(start, pos);
- pos++;
- if (pos >= len) {
- scanError = 2 /* ScanError.UnexpectedEndOfString */;
- break;
- }
- const ch2 = text.charCodeAt(pos++);
- switch (ch2) {
- case 34 /* CharacterCodes.doubleQuote */:
- result += '\"';
- break;
- case 92 /* CharacterCodes.backslash */:
- result += '\\';
- break;
- case 47 /* CharacterCodes.slash */:
- result += '/';
- break;
- case 98 /* CharacterCodes.b */:
- result += '\b';
- break;
- case 102 /* CharacterCodes.f */:
- result += '\f';
- break;
- case 110 /* CharacterCodes.n */:
- result += '\n';
- break;
- case 114 /* CharacterCodes.r */:
- result += '\r';
- break;
- case 116 /* CharacterCodes.t */:
- result += '\t';
- break;
- case 117 /* CharacterCodes.u */:
- const ch3 = scanHexDigits(4, true);
- if (ch3 >= 0) {
- result += String.fromCharCode(ch3);
- }
- else {
- scanError = 4 /* ScanError.InvalidUnicode */;
- }
- break;
- default:
- scanError = 5 /* ScanError.InvalidEscapeCharacter */;
- }
- start = pos;
- continue;
- }
- if (ch >= 0 && ch <= 0x1f) {
- if (isLineBreak(ch)) {
- result += text.substring(start, pos);
- scanError = 2 /* ScanError.UnexpectedEndOfString */;
- break;
- }
- else {
- scanError = 6 /* ScanError.InvalidCharacter */;
- // mark as error but continue with string
- }
- }
- pos++;
- }
- return result;
- }
- function scanNext() {
- value = '';
- scanError = 0 /* ScanError.None */;
- tokenOffset = pos;
- lineStartOffset = lineNumber;
- prevTokenLineStartOffset = tokenLineStartOffset;
- if (pos >= len) {
- // at the end
- tokenOffset = len;
- return token = 17 /* SyntaxKind.EOF */;
- }
- let 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 /* SyntaxKind.Trivia */;
- }
- // trivia: newlines
- if (isLineBreak(code)) {
- pos++;
- value += String.fromCharCode(code);
- if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {
- pos++;
- value += '\n';
- }
- lineNumber++;
- tokenLineStartOffset = pos;
- return token = 14 /* SyntaxKind.LineBreakTrivia */;
- }
- switch (code) {
- // tokens: []{}:,
- case 123 /* CharacterCodes.openBrace */:
- pos++;
- return token = 1 /* SyntaxKind.OpenBraceToken */;
- case 125 /* CharacterCodes.closeBrace */:
- pos++;
- return token = 2 /* SyntaxKind.CloseBraceToken */;
- case 91 /* CharacterCodes.openBracket */:
- pos++;
- return token = 3 /* SyntaxKind.OpenBracketToken */;
- case 93 /* CharacterCodes.closeBracket */:
- pos++;
- return token = 4 /* SyntaxKind.CloseBracketToken */;
- case 58 /* CharacterCodes.colon */:
- pos++;
- return token = 6 /* SyntaxKind.ColonToken */;
- case 44 /* CharacterCodes.comma */:
- pos++;
- return token = 5 /* SyntaxKind.CommaToken */;
- // strings
- case 34 /* CharacterCodes.doubleQuote */:
- pos++;
- value = scanString();
- return token = 10 /* SyntaxKind.StringLiteral */;
- // comments
- case 47 /* CharacterCodes.slash */:
- const start = pos - 1;
- // Single-line comment
- if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {
- pos += 2;
- while (pos < len) {
- if (isLineBreak(text.charCodeAt(pos))) {
- break;
- }
- pos++;
- }
- value = text.substring(start, pos);
- return token = 12 /* SyntaxKind.LineCommentTrivia */;
- }
- // Multi-line comment
- if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) {
- pos += 2;
- const safeLength = len - 1; // For lookahead.
- let commentClosed = false;
- while (pos < safeLength) {
- const ch = text.charCodeAt(pos);
- if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {
- pos += 2;
- commentClosed = true;
- break;
- }
- pos++;
- if (isLineBreak(ch)) {
- if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {
- pos++;
- }
- lineNumber++;
- tokenLineStartOffset = pos;
- }
- }
- if (!commentClosed) {
- pos++;
- scanError = 1 /* ScanError.UnexpectedEndOfComment */;
- }
- value = text.substring(start, pos);
- return token = 13 /* SyntaxKind.BlockCommentTrivia */;
- }
- // just a single slash
- value += String.fromCharCode(code);
- pos++;
- return token = 16 /* SyntaxKind.Unknown */;
- // numbers
- case 45 /* CharacterCodes.minus */:
- value += String.fromCharCode(code);
- pos++;
- if (pos === len || !isDigit(text.charCodeAt(pos))) {
- return token = 16 /* SyntaxKind.Unknown */;
- }
- // found a minus, followed by a number so
- // we fall through to proceed with scanning
- // numbers
- case 48 /* CharacterCodes._0 */:
- case 49 /* CharacterCodes._1 */:
- case 50 /* CharacterCodes._2 */:
- case 51 /* CharacterCodes._3 */:
- case 52 /* CharacterCodes._4 */:
- case 53 /* CharacterCodes._5 */:
- case 54 /* CharacterCodes._6 */:
- case 55 /* CharacterCodes._7 */:
- case 56 /* CharacterCodes._8 */:
- case 57 /* CharacterCodes._9 */:
- value += scanNumber();
- return token = 11 /* 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 = 8 /* SyntaxKind.TrueKeyword */;
- case 'false': return token = 9 /* SyntaxKind.FalseKeyword */;
- case 'null': return token = 7 /* SyntaxKind.NullKeyword */;
- }
- return token = 16 /* SyntaxKind.Unknown */;
- }
- // some
- value += String.fromCharCode(code);
- pos++;
- return token = 16 /* SyntaxKind.Unknown */;
- }
- }
- function isUnknownContentCharacter(code) {
- if (isWhiteSpace(code) || isLineBreak(code)) {
- return false;
- }
- switch (code) {
- case 125 /* CharacterCodes.closeBrace */:
- case 93 /* CharacterCodes.closeBracket */:
- case 123 /* CharacterCodes.openBrace */:
- case 91 /* CharacterCodes.openBracket */:
- case 34 /* CharacterCodes.doubleQuote */:
- case 58 /* CharacterCodes.colon */:
- case 44 /* CharacterCodes.comma */:
- case 47 /* CharacterCodes.slash */:
- return false;
- }
- return true;
- }
- function scanNextNonTrivia() {
- let result;
- do {
- result = scanNext();
- } while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */);
- return result;
- }
- return {
- setPosition: setPosition,
- getPosition: () => pos,
- scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
- getToken: () => token,
- getTokenValue: () => value,
- getTokenOffset: () => tokenOffset,
- getTokenLength: () => pos - tokenOffset,
- getTokenStartLine: () => lineStartOffset,
- getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
- getTokenError: () => scanError,
- };
- }
- function isWhiteSpace(ch) {
- return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */;
- }
- function isLineBreak(ch) {
- return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */;
- }
- function isDigit(ch) {
- return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */;
- }
- var CharacterCodes;
- (function (CharacterCodes) {
- CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
- CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
- CharacterCodes[CharacterCodes["space"] = 32] = "space";
- 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["asterisk"] = 42] = "asterisk";
- CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
- CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
- CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
- CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
- CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
- CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
- CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
- CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
- CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
- CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
- CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
- CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
- CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
- CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
- })(CharacterCodes || (CharacterCodes = {}));
|