jsonc-parser
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -102,2 +102,3 @@ export declare enum ScanError { | ||
export declare type Segment = string | number; | ||
export declare type JSONPath = Segment[]; | ||
export interface Location { | ||
@@ -112,3 +113,3 @@ /** | ||
*/ | ||
path: Segment[]; | ||
path: JSONPath; | ||
/** | ||
@@ -119,3 +120,3 @@ * Matches the locations path against a pattern consisting of strings (for properties) and numbers (for array indices). | ||
*/ | ||
matches: (patterns: Segment[]) => boolean; | ||
matches: (patterns: JSONPath) => boolean; | ||
/** | ||
@@ -142,2 +143,4 @@ * If set, the location's offset is at a property key. | ||
export declare function parseTree(text: string, errors?: ParseError[], options?: ParseOptions): Node; | ||
export declare function findNodeAtLocation(root: Node, path: JSONPath): Node; | ||
export declare function getNodeValue(node: Node): any; | ||
/** | ||
@@ -144,0 +147,0 @@ * Parses the given text and invokes the visitor functions for each object, array and literal reached. |
1834
lib/main.js
@@ -1,91 +0,91 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
'use strict'; | ||
var nls = require('vscode-nls'); | ||
nls.config(process.env['VSCODE_NLS_CONFIG']); | ||
var localize = nls.loadMessageBundle(); | ||
(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"; | ||
})(exports.ScanError || (exports.ScanError = {})); | ||
var ScanError = exports.ScanError; | ||
(function (SyntaxKind) { | ||
SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown"; | ||
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["EOF"] = 16] = "EOF"; | ||
})(exports.SyntaxKind || (exports.SyntaxKind = {})); | ||
var SyntaxKind = exports.SyntaxKind; | ||
/** | ||
* Creates a JSON scanner on the given text. | ||
* If ignoreTrivia is set, whitespaces or comments are ignored. | ||
*/ | ||
function createScanner(text, ignoreTrivia) { | ||
if (ignoreTrivia === void 0) { ignoreTrivia = false; } | ||
var pos = 0, len = text.length, value = '', tokenOffset = 0, token = SyntaxKind.Unknown, scanError = ScanError.None; | ||
function scanHexDigits(count, exact) { | ||
var digits = 0; | ||
var value = 0; | ||
while (digits < count || !exact) { | ||
var ch = text.charCodeAt(pos); | ||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) { | ||
value = value * 16 + ch - CharacterCodes._0; | ||
(function (factory) { | ||
if (typeof module === 'object' && typeof module.exports === 'object') { | ||
var v = factory(require, exports); if (v !== undefined) module.exports = v; | ||
} | ||
else if (typeof define === 'function' && define.amd) { | ||
define(["require", "exports", 'vscode-nls'], factory); | ||
} | ||
})(function (require, exports) { | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
'use strict'; | ||
var nls = require('vscode-nls'); | ||
nls.config(process.env['VSCODE_NLS_CONFIG']); | ||
var localize = nls.loadMessageBundle(); | ||
(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"; | ||
})(exports.ScanError || (exports.ScanError = {})); | ||
var ScanError = exports.ScanError; | ||
(function (SyntaxKind) { | ||
SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown"; | ||
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["EOF"] = 16] = "EOF"; | ||
})(exports.SyntaxKind || (exports.SyntaxKind = {})); | ||
var SyntaxKind = exports.SyntaxKind; | ||
/** | ||
* Creates a JSON scanner on the given text. | ||
* If ignoreTrivia is set, whitespaces or comments are ignored. | ||
*/ | ||
function createScanner(text, ignoreTrivia) { | ||
if (ignoreTrivia === void 0) { ignoreTrivia = false; } | ||
var pos = 0, len = text.length, value = '', tokenOffset = 0, token = SyntaxKind.Unknown, scanError = ScanError.None; | ||
function scanHexDigits(count, exact) { | ||
var digits = 0; | ||
var value = 0; | ||
while (digits < count || !exact) { | ||
var ch = text.charCodeAt(pos); | ||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) { | ||
value = value * 16 + ch - CharacterCodes._0; | ||
} | ||
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) { | ||
value = value * 16 + ch - CharacterCodes.A + 10; | ||
} | ||
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) { | ||
value = value * 16 + ch - CharacterCodes.a + 10; | ||
} | ||
else { | ||
break; | ||
} | ||
pos++; | ||
digits++; | ||
} | ||
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) { | ||
value = value * 16 + ch - CharacterCodes.A + 10; | ||
if (digits < count) { | ||
value = -1; | ||
} | ||
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) { | ||
value = value * 16 + ch - CharacterCodes.a + 10; | ||
} | ||
else { | ||
break; | ||
} | ||
pos++; | ||
digits++; | ||
return value; | ||
} | ||
if (digits < count) { | ||
value = -1; | ||
function setPosition(newPosition) { | ||
pos = newPosition; | ||
value = ''; | ||
tokenOffset = 0; | ||
token = SyntaxKind.Unknown; | ||
scanError = ScanError.None; | ||
} | ||
return value; | ||
} | ||
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))) { | ||
function scanNumber() { | ||
var start = pos; | ||
if (text.charCodeAt(pos) === CharacterCodes._0) { | ||
pos++; | ||
} | ||
} | ||
if (pos < text.length && text.charCodeAt(pos) === CharacterCodes.dot) { | ||
pos++; | ||
if (pos < text.length && isDigit(text.charCodeAt(pos))) { | ||
else { | ||
pos++; | ||
@@ -96,897 +96,961 @@ while (pos < text.length && isDigit(text.charCodeAt(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) { | ||
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); | ||
} | ||
} | ||
if (pos < text.length && isDigit(text.charCodeAt(pos))) { | ||
var end = pos; | ||
if (pos < text.length && (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e)) { | ||
pos++; | ||
while (pos < text.length && isDigit(text.charCodeAt(pos))) { | ||
if (pos < text.length && text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) { | ||
pos++; | ||
} | ||
end = 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; | ||
} | ||
} | ||
else { | ||
scanError = ScanError.UnexpectedEndOfNumber; | ||
} | ||
return text.substring(start, end); | ||
} | ||
return text.substring(start, end); | ||
} | ||
function scanString() { | ||
var result = '', start = pos; | ||
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++; | ||
function scanString() { | ||
var result = '', start = pos; | ||
while (true) { | ||
if (pos >= len) { | ||
result += text.substring(start, pos); | ||
scanError = ScanError.UnexpectedEndOfString; | ||
break; | ||
} | ||
ch = text.charCodeAt(pos++); | ||
switch (ch) { | ||
case CharacterCodes.doubleQuote: | ||
result += '\"'; | ||
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; | ||
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 ch_1 = scanHexDigits(4, true); | ||
if (ch_1 >= 0) { | ||
result += String.fromCharCode(ch_1); | ||
} | ||
else { | ||
scanError = ScanError.InvalidUnicode; | ||
} | ||
break; | ||
default: | ||
scanError = ScanError.InvalidEscapeCharacter; | ||
} | ||
ch = text.charCodeAt(pos++); | ||
switch (ch) { | ||
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 ch_1 = scanHexDigits(4, true); | ||
if (ch_1 >= 0) { | ||
result += String.fromCharCode(ch_1); | ||
} | ||
else { | ||
scanError = ScanError.InvalidUnicode; | ||
} | ||
break; | ||
default: | ||
scanError = ScanError.InvalidEscapeCharacter; | ||
} | ||
start = pos; | ||
continue; | ||
} | ||
start = pos; | ||
continue; | ||
if (isLineBreak(ch)) { | ||
result += text.substring(start, pos); | ||
scanError = ScanError.UnexpectedEndOfString; | ||
break; | ||
} | ||
pos++; | ||
} | ||
if (isLineBreak(ch)) { | ||
result += text.substring(start, pos); | ||
scanError = ScanError.UnexpectedEndOfString; | ||
break; | ||
return result; | ||
} | ||
function scanNext() { | ||
value = ''; | ||
scanError = ScanError.None; | ||
tokenOffset = pos; | ||
if (pos >= len) { | ||
// at the end | ||
tokenOffset = len; | ||
return token = SyntaxKind.EOF; | ||
} | ||
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 { | ||
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); | ||
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'; | ||
if (code === CharacterCodes.carriageReturn && text.charCodeAt(pos) === CharacterCodes.lineFeed) { | ||
pos++; | ||
value += '\n'; | ||
} | ||
return token = SyntaxKind.LineBreakTrivia; | ||
} | ||
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; | ||
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++; | ||
} | ||
pos++; | ||
value = text.substring(start, pos); | ||
return token = SyntaxKind.LineCommentTrivia; | ||
} | ||
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; | ||
// 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++; | ||
} | ||
pos++; | ||
if (!commentClosed) { | ||
pos++; | ||
scanError = ScanError.UnexpectedEndOfComment; | ||
} | ||
value = text.substring(start, pos); | ||
return token = SyntaxKind.BlockCommentTrivia; | ||
} | ||
if (!commentClosed) { | ||
// 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++; | ||
scanError = ScanError.UnexpectedEndOfComment; | ||
code = text.charCodeAt(pos); | ||
} | ||
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)) { | ||
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++; | ||
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; | ||
} | ||
switch (code) { | ||
case CharacterCodes.closeBrace: | ||
case CharacterCodes.closeBracket: | ||
case CharacterCodes.openBrace: | ||
case CharacterCodes.openBracket: | ||
case CharacterCodes.doubleQuote: | ||
case CharacterCodes.colon: | ||
case CharacterCodes.comma: | ||
function isUnknownContentCharacter(code) { | ||
if (isWhiteSpace(code) || isLineBreak(code)) { | ||
return false; | ||
} | ||
switch (code) { | ||
case CharacterCodes.closeBrace: | ||
case CharacterCodes.closeBracket: | ||
case CharacterCodes.openBrace: | ||
case CharacterCodes.openBracket: | ||
case CharacterCodes.doubleQuote: | ||
case CharacterCodes.colon: | ||
case CharacterCodes.comma: | ||
return false; | ||
} | ||
return true; | ||
} | ||
return true; | ||
function scanNextNonTrivia() { | ||
var result; | ||
do { | ||
result = scanNext(); | ||
} while (result >= SyntaxKind.LineCommentTrivia && result <= SyntaxKind.Trivia); | ||
return result; | ||
} | ||
return { | ||
setPosition: setPosition, | ||
getPosition: function () { return pos; }, | ||
scan: ignoreTrivia ? scanNextNonTrivia : scanNext, | ||
getToken: function () { return token; }, | ||
getTokenValue: function () { return value; }, | ||
getTokenOffset: function () { return tokenOffset; }, | ||
getTokenLength: function () { return pos - tokenOffset; }, | ||
getTokenError: function () { return scanError; } | ||
}; | ||
} | ||
function scanNextNonTrivia() { | ||
var result; | ||
exports.createScanner = createScanner; | ||
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; | ||
(function (CharacterCodes) { | ||
CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter"; | ||
CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter"; | ||
CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed"; | ||
CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn"; | ||
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"; | ||
CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed"; | ||
CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark"; | ||
CharacterCodes[CharacterCodes["tab"] = 9] = "tab"; | ||
CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab"; | ||
})(CharacterCodes || (CharacterCodes = {})); | ||
/** | ||
* 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), parts = [], kind, offset = 0, pos; | ||
do { | ||
result = scanNext(); | ||
} while (result >= SyntaxKind.LineCommentTrivia && result <= SyntaxKind.Trivia); | ||
return result; | ||
pos = _scanner.getPosition(); | ||
kind = _scanner.scan(); | ||
switch (kind) { | ||
case SyntaxKind.LineCommentTrivia: | ||
case SyntaxKind.BlockCommentTrivia: | ||
case SyntaxKind.EOF: | ||
if (offset !== pos) { | ||
parts.push(text.substring(offset, pos)); | ||
} | ||
if (replaceCh !== void 0) { | ||
parts.push(_scanner.getTokenValue().replace(/[^\r\n]/g, replaceCh)); | ||
} | ||
offset = _scanner.getPosition(); | ||
break; | ||
} | ||
} while (kind !== SyntaxKind.EOF); | ||
return parts.join(''); | ||
} | ||
return { | ||
setPosition: setPosition, | ||
getPosition: function () { return pos; }, | ||
scan: ignoreTrivia ? scanNextNonTrivia : scanNext, | ||
getToken: function () { return token; }, | ||
getTokenValue: function () { return value; }, | ||
getTokenOffset: function () { return tokenOffset; }, | ||
getTokenLength: function () { return pos - tokenOffset; }, | ||
getTokenError: function () { return scanError; } | ||
}; | ||
} | ||
exports.createScanner = createScanner; | ||
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; | ||
(function (CharacterCodes) { | ||
CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter"; | ||
CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter"; | ||
CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed"; | ||
CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn"; | ||
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"; | ||
CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed"; | ||
CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark"; | ||
CharacterCodes[CharacterCodes["tab"] = 9] = "tab"; | ||
CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab"; | ||
})(CharacterCodes || (CharacterCodes = {})); | ||
/** | ||
* 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), parts = [], kind, offset = 0, pos; | ||
do { | ||
pos = _scanner.getPosition(); | ||
kind = _scanner.scan(); | ||
switch (kind) { | ||
case SyntaxKind.LineCommentTrivia: | ||
case SyntaxKind.BlockCommentTrivia: | ||
case SyntaxKind.EOF: | ||
if (offset !== pos) { | ||
parts.push(text.substring(offset, pos)); | ||
} | ||
if (replaceCh !== void 0) { | ||
parts.push(_scanner.getTokenValue().replace(/[^\r\n]/g, replaceCh)); | ||
} | ||
offset = _scanner.getPosition(); | ||
break; | ||
exports.stripComments = stripComments; | ||
(function (ParseErrorCode) { | ||
ParseErrorCode[ParseErrorCode["InvalidSymbol"] = 0] = "InvalidSymbol"; | ||
ParseErrorCode[ParseErrorCode["InvalidNumberFormat"] = 1] = "InvalidNumberFormat"; | ||
ParseErrorCode[ParseErrorCode["PropertyNameExpected"] = 2] = "PropertyNameExpected"; | ||
ParseErrorCode[ParseErrorCode["ValueExpected"] = 3] = "ValueExpected"; | ||
ParseErrorCode[ParseErrorCode["ColonExpected"] = 4] = "ColonExpected"; | ||
ParseErrorCode[ParseErrorCode["CommaExpected"] = 5] = "CommaExpected"; | ||
ParseErrorCode[ParseErrorCode["CloseBraceExpected"] = 6] = "CloseBraceExpected"; | ||
ParseErrorCode[ParseErrorCode["CloseBracketExpected"] = 7] = "CloseBracketExpected"; | ||
ParseErrorCode[ParseErrorCode["EndOfFileExpected"] = 8] = "EndOfFileExpected"; | ||
})(exports.ParseErrorCode || (exports.ParseErrorCode = {})); | ||
var ParseErrorCode = exports.ParseErrorCode; | ||
function getParseErrorMessage(errorCode) { | ||
switch (errorCode) { | ||
case ParseErrorCode.InvalidSymbol: return localize('error.invalidSymbol', 'Invalid symbol'); | ||
case ParseErrorCode.InvalidNumberFormat: return localize('error.invalidNumberFormat', 'Invalid number format'); | ||
case ParseErrorCode.PropertyNameExpected: return localize('error.propertyNameExpected', 'Property name expected'); | ||
case ParseErrorCode.ValueExpected: return localize('error.valueExpected', 'Value expected'); | ||
case ParseErrorCode.ColonExpected: return localize('error.colonExpected', 'Colon expected'); | ||
case ParseErrorCode.CommaExpected: return localize('error.commaExpected', 'Comma expected'); | ||
case ParseErrorCode.CloseBraceExpected: return localize('error.closeBraceExpected', 'Closing brace expected'); | ||
case ParseErrorCode.CloseBracketExpected: return localize('error.closeBracketExpected', 'Closing bracket expected'); | ||
case ParseErrorCode.EndOfFileExpected: return localize('error.endOfFileExpected', 'End of file expected'); | ||
default: | ||
return ''; | ||
} | ||
} while (kind !== SyntaxKind.EOF); | ||
return parts.join(''); | ||
} | ||
exports.stripComments = stripComments; | ||
(function (ParseErrorCode) { | ||
ParseErrorCode[ParseErrorCode["InvalidSymbol"] = 0] = "InvalidSymbol"; | ||
ParseErrorCode[ParseErrorCode["InvalidNumberFormat"] = 1] = "InvalidNumberFormat"; | ||
ParseErrorCode[ParseErrorCode["PropertyNameExpected"] = 2] = "PropertyNameExpected"; | ||
ParseErrorCode[ParseErrorCode["ValueExpected"] = 3] = "ValueExpected"; | ||
ParseErrorCode[ParseErrorCode["ColonExpected"] = 4] = "ColonExpected"; | ||
ParseErrorCode[ParseErrorCode["CommaExpected"] = 5] = "CommaExpected"; | ||
ParseErrorCode[ParseErrorCode["CloseBraceExpected"] = 6] = "CloseBraceExpected"; | ||
ParseErrorCode[ParseErrorCode["CloseBracketExpected"] = 7] = "CloseBracketExpected"; | ||
ParseErrorCode[ParseErrorCode["EndOfFileExpected"] = 8] = "EndOfFileExpected"; | ||
})(exports.ParseErrorCode || (exports.ParseErrorCode = {})); | ||
var ParseErrorCode = exports.ParseErrorCode; | ||
function getParseErrorMessage(errorCode) { | ||
switch (errorCode) { | ||
case ParseErrorCode.InvalidSymbol: return localize('error.invalidSymbol', 'Invalid symbol'); | ||
case ParseErrorCode.InvalidNumberFormat: return localize('error.invalidNumberFormat', 'Invalid number format'); | ||
case ParseErrorCode.PropertyNameExpected: return localize('error.propertyNameExpected', 'Property name expected'); | ||
case ParseErrorCode.ValueExpected: return localize('error.valueExpected', 'Value expected'); | ||
case ParseErrorCode.ColonExpected: return localize('error.colonExpected', 'Colon expected'); | ||
case ParseErrorCode.CommaExpected: return localize('error.commaExpected', 'Comma expected'); | ||
case ParseErrorCode.CloseBraceExpected: return localize('error.closeBraceExpected', 'Closing brace expected'); | ||
case ParseErrorCode.CloseBracketExpected: return localize('error.closeBracketExpected', 'Closing bracket expected'); | ||
case ParseErrorCode.EndOfFileExpected: return localize('error.endOfFileExpected', 'End of file expected'); | ||
default: | ||
return ''; | ||
} | ||
} | ||
exports.getParseErrorMessage = getParseErrorMessage; | ||
function getLiteralNodeType(value) { | ||
switch (typeof value) { | ||
case 'boolean': return 'boolean'; | ||
case 'number': return 'number'; | ||
case 'string': return 'string'; | ||
default: return 'null'; | ||
exports.getParseErrorMessage = getParseErrorMessage; | ||
function getLiteralNodeType(value) { | ||
switch (typeof value) { | ||
case 'boolean': return 'boolean'; | ||
case 'number': return 'number'; | ||
case 'string': return 'string'; | ||
default: return 'null'; | ||
} | ||
} | ||
} | ||
/** | ||
* 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 | ||
var earlyReturnException = new Object(); | ||
var previousNode = void 0; | ||
var previousNodeInst = { | ||
value: void 0, | ||
offset: void 0, | ||
length: void 0, | ||
type: void 0 | ||
}; | ||
var isAtPropertyKey = false; | ||
function setPreviousNode(value, offset, length, type) { | ||
previousNodeInst.value = value; | ||
previousNodeInst.offset = offset; | ||
previousNodeInst.length = length; | ||
previousNodeInst.type = type; | ||
previousNodeInst.columnOffset = void 0; | ||
previousNode = previousNodeInst; | ||
/** | ||
* 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 | ||
var earlyReturnException = new Object(); | ||
var previousNode = void 0; | ||
var previousNodeInst = { | ||
value: void 0, | ||
offset: void 0, | ||
length: void 0, | ||
type: void 0 | ||
}; | ||
var isAtPropertyKey = false; | ||
function setPreviousNode(value, offset, length, type) { | ||
previousNodeInst.value = value; | ||
previousNodeInst.offset = offset; | ||
previousNodeInst.length = length; | ||
previousNodeInst.type = type; | ||
previousNodeInst.columnOffset = void 0; | ||
previousNode = previousNodeInst; | ||
} | ||
try { | ||
visit(text, { | ||
onObjectBegin: function (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
isAtPropertyKey = position > offset; | ||
segments.push(''); // push a placeholder (will be replaced or removed) | ||
}, | ||
onObjectProperty: function (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 (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
segments.pop(); | ||
}, | ||
onArrayBegin: function (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
segments.push(0); | ||
}, | ||
onArrayEnd: function (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
segments.pop(); | ||
}, | ||
onLiteralValue: function (value, offset, length) { | ||
if (position < offset) { | ||
throw earlyReturnException; | ||
} | ||
setPreviousNode(value, offset, length, getLiteralNodeType(value)); | ||
if (position <= offset + length) { | ||
throw earlyReturnException; | ||
} | ||
}, | ||
onSeparator: function (sep, offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
if (sep === ':' && previousNode.type === 'property') { | ||
previousNode.columnOffset = offset; | ||
isAtPropertyKey = false; | ||
previousNode = void 0; | ||
} | ||
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 = void 0; | ||
} | ||
} | ||
}); | ||
} | ||
catch (e) { | ||
if (e !== earlyReturnException) { | ||
throw e; | ||
} | ||
} | ||
if (segments[segments.length - 1] === '') { | ||
segments.pop(); | ||
} | ||
return { | ||
path: segments, | ||
previousNode: previousNode, | ||
isAtPropertyKey: isAtPropertyKey, | ||
matches: function (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; | ||
} | ||
}; | ||
} | ||
try { | ||
visit(text, { | ||
onObjectBegin: function (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
isAtPropertyKey = position > offset; | ||
segments.push(''); // push a placeholder (will be replaced or removed) | ||
exports.getLocation = getLocation; | ||
/** | ||
* 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, errors, options) { | ||
if (errors === void 0) { errors = []; } | ||
var currentProperty = null; | ||
var currentParent = []; | ||
var previousParents = []; | ||
function onValue(value) { | ||
if (Array.isArray(currentParent)) { | ||
currentParent.push(value); | ||
} | ||
else if (currentProperty) { | ||
currentParent[currentProperty] = value; | ||
} | ||
} | ||
var visitor = { | ||
onObjectBegin: function () { | ||
var object = {}; | ||
onValue(object); | ||
previousParents.push(currentParent); | ||
currentParent = object; | ||
currentProperty = null; | ||
}, | ||
onObjectProperty: function (name) { | ||
currentProperty = name; | ||
}, | ||
onObjectEnd: function () { | ||
currentParent = previousParents.pop(); | ||
}, | ||
onArrayBegin: function () { | ||
var array = []; | ||
onValue(array); | ||
previousParents.push(currentParent); | ||
currentParent = array; | ||
currentProperty = null; | ||
}, | ||
onArrayEnd: function () { | ||
currentParent = previousParents.pop(); | ||
}, | ||
onLiteralValue: onValue, | ||
onError: function (error) { | ||
errors.push({ error: error }); | ||
} | ||
}; | ||
visit(text, visitor, options); | ||
return currentParent[0]; | ||
} | ||
exports.parse = parse; | ||
/** | ||
* 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, errors, options) { | ||
if (errors === void 0) { errors = []; } | ||
var currentParent = { type: 'array', offset: -1, length: -1, children: [] }; // artificial root | ||
function ensurePropertyComplete(endOffset) { | ||
if (currentParent.type === 'property') { | ||
currentParent.length = endOffset - currentParent.offset; | ||
currentParent = currentParent.parent; | ||
} | ||
} | ||
function onValue(valueNode) { | ||
currentParent.children.push(valueNode); | ||
ensurePropertyComplete(valueNode.offset + valueNode.length); | ||
return valueNode; | ||
} | ||
var visitor = { | ||
onObjectBegin: function (offset) { | ||
currentParent = onValue({ type: 'object', offset: offset, length: -1, parent: currentParent, children: [] }); | ||
}, | ||
onObjectProperty: function (name, offset, length) { | ||
if (position < offset) { | ||
throw earlyReturnException; | ||
} | ||
setPreviousNode(name, offset, length, 'property'); | ||
segments[segments.length - 1] = name; | ||
if (position <= offset + length) { | ||
throw earlyReturnException; | ||
} | ||
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 (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
segments.pop(); | ||
ensurePropertyComplete(offset); | ||
currentParent.length = offset + length - currentParent.offset; | ||
currentParent = currentParent.parent; | ||
}, | ||
onArrayBegin: function (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
segments.push(0); | ||
currentParent = onValue({ type: 'array', offset: offset, length: -1, parent: currentParent, children: [] }); | ||
}, | ||
onArrayEnd: function (offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
previousNode = void 0; | ||
segments.pop(); | ||
currentParent.length = offset + length - currentParent.offset; | ||
currentParent = currentParent.parent; | ||
}, | ||
onLiteralValue: function (value, offset, length) { | ||
if (position < offset) { | ||
throw earlyReturnException; | ||
} | ||
setPreviousNode(value, offset, length, getLiteralNodeType(value)); | ||
if (position <= offset + length) { | ||
throw earlyReturnException; | ||
} | ||
onValue({ type: getLiteralNodeType(value), offset: offset, length: length, parent: currentParent, value: value }); | ||
}, | ||
onSeparator: function (sep, offset, length) { | ||
if (position <= offset) { | ||
throw earlyReturnException; | ||
} | ||
if (sep === ':' && previousNode.type === 'property') { | ||
previousNode.columnOffset = offset; | ||
isAtPropertyKey = false; | ||
previousNode = void 0; | ||
} | ||
else if (sep === ',') { | ||
var last = segments[segments.length - 1]; | ||
if (typeof last === 'number') { | ||
segments[segments.length - 1] = last + 1; | ||
if (currentParent.type === 'property') { | ||
if (sep === ':') { | ||
currentParent.columnOffset = offset; | ||
} | ||
else { | ||
isAtPropertyKey = true; | ||
segments[segments.length - 1] = ''; | ||
else if (sep === ',') { | ||
ensurePropertyComplete(offset); | ||
} | ||
previousNode = void 0; | ||
} | ||
}, | ||
onError: function (error) { | ||
errors.push({ error: error }); | ||
} | ||
}); | ||
}; | ||
visit(text, visitor, options); | ||
var result = currentParent.children[0]; | ||
if (result) { | ||
delete result.parent; | ||
} | ||
return result; | ||
} | ||
catch (e) { | ||
if (e !== earlyReturnException) { | ||
throw e; | ||
exports.parseTree = parseTree; | ||
function findNodeAtLocation(root, path) { | ||
if (!root) { | ||
return void 0; | ||
} | ||
} | ||
if (segments[segments.length - 1] === '') { | ||
segments.pop(); | ||
} | ||
return { | ||
path: segments, | ||
previousNode: previousNode, | ||
isAtPropertyKey: isAtPropertyKey, | ||
matches: function (pattern) { | ||
var k = 0; | ||
for (var i = 0; k < pattern.length && i < segments.length; i++) { | ||
if (pattern[k] === segments[i] || pattern[k] === '*') { | ||
k++; | ||
var node = root; | ||
for (var _i = 0, path_1 = path; _i < path_1.length; _i++) { | ||
var segment = path_1[_i]; | ||
if (typeof segment === 'string') { | ||
if (node.type !== 'object') { | ||
return void 0; | ||
} | ||
else if (pattern[k] !== '**') { | ||
return false; | ||
var found = false; | ||
for (var _a = 0, _b = node.children; _a < _b.length; _a++) { | ||
var propertyNode = _b[_a]; | ||
if (propertyNode.children[0].value === segment) { | ||
node = propertyNode.children[1]; | ||
found = true; | ||
break; | ||
} | ||
} | ||
if (!found) { | ||
return void 0; | ||
} | ||
} | ||
return k === pattern.length; | ||
else { | ||
var index = segment; | ||
if (node.type !== 'array' || index < 0 || index >= node.children.length) { | ||
return void 0; | ||
} | ||
node = node.children[index]; | ||
} | ||
} | ||
}; | ||
} | ||
exports.getLocation = getLocation; | ||
/** | ||
* 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, errors, options) { | ||
if (errors === void 0) { errors = []; } | ||
var currentProperty = null; | ||
var currentParent = []; | ||
var previousParents = []; | ||
function onValue(value) { | ||
if (Array.isArray(currentParent)) { | ||
currentParent.push(value); | ||
return node; | ||
} | ||
exports.findNodeAtLocation = findNodeAtLocation; | ||
function getNodeValue(node) { | ||
if (node.type === 'array') { | ||
return node.children.map(getNodeValue); | ||
} | ||
else if (currentProperty) { | ||
currentParent[currentProperty] = value; | ||
else if (node.type === 'object') { | ||
var obj = {}; | ||
for (var _i = 0, _a = node.children; _i < _a.length; _i++) { | ||
var prop = _a[_i]; | ||
obj[prop.children[0].value] = getNodeValue(prop.children[1]); | ||
} | ||
return obj; | ||
} | ||
return node.value; | ||
} | ||
var visitor = { | ||
onObjectBegin: function () { | ||
var object = {}; | ||
onValue(object); | ||
previousParents.push(currentParent); | ||
currentParent = object; | ||
currentProperty = null; | ||
}, | ||
onObjectProperty: function (name) { | ||
currentProperty = name; | ||
}, | ||
onObjectEnd: function () { | ||
currentParent = previousParents.pop(); | ||
}, | ||
onArrayBegin: function () { | ||
var array = []; | ||
onValue(array); | ||
previousParents.push(currentParent); | ||
currentParent = array; | ||
currentProperty = null; | ||
}, | ||
onArrayEnd: function () { | ||
currentParent = previousParents.pop(); | ||
}, | ||
onLiteralValue: onValue, | ||
onError: function (error) { | ||
errors.push({ error: error }); | ||
exports.getNodeValue = getNodeValue; | ||
/** | ||
* Parses the given text and invokes the visitor functions for each object, array and literal reached. | ||
*/ | ||
function visit(text, visitor, options) { | ||
var _scanner = createScanner(text, false); | ||
function toNoArgVisit(visitFunction) { | ||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength()); } : function () { return true; }; | ||
} | ||
}; | ||
visit(text, visitor, options); | ||
return currentParent[0]; | ||
} | ||
exports.parse = parse; | ||
/** | ||
* 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, errors, options) { | ||
if (errors === void 0) { errors = []; } | ||
var currentParent = { type: 'array', offset: -1, length: -1, children: [] }; // artificial root | ||
function ensurePropertyComplete(endOffset) { | ||
if (currentParent.type === 'property') { | ||
currentParent.length = endOffset - currentParent.offset; | ||
currentParent = currentParent.parent; | ||
function toOneArgVisit(visitFunction) { | ||
return visitFunction ? function (arg) { return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength()); } : function () { return true; }; | ||
} | ||
} | ||
function onValue(valueNode) { | ||
currentParent.children.push(valueNode); | ||
ensurePropertyComplete(valueNode.offset + valueNode.length); | ||
return valueNode; | ||
} | ||
var visitor = { | ||
onObjectBegin: function (offset) { | ||
currentParent = onValue({ type: 'object', offset: offset, length: -1, parent: currentParent, children: [] }); | ||
}, | ||
onObjectProperty: function (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 (offset, length) { | ||
ensurePropertyComplete(offset); | ||
currentParent.length = offset + length - currentParent.offset; | ||
currentParent = currentParent.parent; | ||
}, | ||
onArrayBegin: function (offset, length) { | ||
currentParent = onValue({ type: 'array', offset: offset, length: -1, parent: currentParent, children: [] }); | ||
}, | ||
onArrayEnd: function (offset, length) { | ||
currentParent.length = offset + length - currentParent.offset; | ||
currentParent = currentParent.parent; | ||
}, | ||
onLiteralValue: function (value, offset, length) { | ||
onValue({ type: getLiteralNodeType(value), offset: offset, length: length, parent: currentParent, value: value }); | ||
}, | ||
onSeparator: function (sep, offset, length) { | ||
if (currentParent.type === 'property') { | ||
if (sep === ':') { | ||
currentParent.columnOffset = offset; | ||
var onObjectBegin = toNoArgVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisit(visitor.onObjectProperty), onObjectEnd = toNoArgVisit(visitor.onObjectEnd), onArrayBegin = toNoArgVisit(visitor.onArrayBegin), onArrayEnd = toNoArgVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisit(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onError = toOneArgVisit(visitor.onError); | ||
var disallowComments = options && options.disallowComments; | ||
function scanNext() { | ||
while (true) { | ||
var token = _scanner.scan(); | ||
switch (token) { | ||
case SyntaxKind.LineCommentTrivia: | ||
case SyntaxKind.BlockCommentTrivia: | ||
if (disallowComments) { | ||
handleError(ParseErrorCode.InvalidSymbol); | ||
} | ||
break; | ||
case SyntaxKind.Unknown: | ||
handleError(ParseErrorCode.InvalidSymbol); | ||
break; | ||
case SyntaxKind.Trivia: | ||
case SyntaxKind.LineBreakTrivia: | ||
break; | ||
default: | ||
return token; | ||
} | ||
else if (sep === ',') { | ||
ensurePropertyComplete(offset); | ||
} | ||
} | ||
function handleError(error, skipUntilAfter, skipUntil) { | ||
if (skipUntilAfter === void 0) { skipUntilAfter = []; } | ||
if (skipUntil === void 0) { skipUntil = []; } | ||
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(); | ||
} | ||
} | ||
}, | ||
onError: function (error) { | ||
errors.push({ error: error }); | ||
} | ||
}; | ||
visit(text, visitor, options); | ||
var result = currentParent.children[0]; | ||
delete result.parent; | ||
return result; | ||
} | ||
exports.parseTree = parseTree; | ||
/** | ||
* Parses the given text and invokes the visitor functions for each object, array and literal reached. | ||
*/ | ||
function visit(text, visitor, options) { | ||
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), onObjectProperty = toOneArgVisit(visitor.onObjectProperty), onObjectEnd = toNoArgVisit(visitor.onObjectEnd), onArrayBegin = toNoArgVisit(visitor.onArrayBegin), onArrayEnd = toNoArgVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisit(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onError = toOneArgVisit(visitor.onError); | ||
var disallowComments = options && options.disallowComments; | ||
function scanNext() { | ||
while (true) { | ||
var token = _scanner.scan(); | ||
switch (token) { | ||
case SyntaxKind.LineCommentTrivia: | ||
case SyntaxKind.BlockCommentTrivia: | ||
if (disallowComments) { | ||
handleError(ParseErrorCode.InvalidSymbol); | ||
function parseString(isValue) { | ||
if (_scanner.getToken() !== SyntaxKind.StringLiteral) { | ||
return false; | ||
} | ||
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.Unknown: | ||
handleError(ParseErrorCode.InvalidSymbol); | ||
case SyntaxKind.NullKeyword: | ||
onLiteralValue(null); | ||
break; | ||
case SyntaxKind.Trivia: | ||
case SyntaxKind.LineBreakTrivia: | ||
case SyntaxKind.TrueKeyword: | ||
onLiteralValue(true); | ||
break; | ||
case SyntaxKind.FalseKeyword: | ||
onLiteralValue(false); | ||
break; | ||
default: | ||
return token; | ||
return false; | ||
} | ||
scanNext(); | ||
return true; | ||
} | ||
} | ||
function handleError(error, skipUntilAfter, skipUntil) { | ||
if (skipUntilAfter === void 0) { skipUntilAfter = []; } | ||
if (skipUntil === void 0) { skipUntil = []; } | ||
onError(error); | ||
if (skipUntilAfter.length + skipUntil.length > 0) { | ||
var token = _scanner.getToken(); | ||
while (token !== SyntaxKind.EOF) { | ||
if (skipUntilAfter.indexOf(token) !== -1) { | ||
scanNext(); | ||
break; | ||
function parseProperty() { | ||
if (!parseString(false)) { | ||
handleError(ParseErrorCode.PropertyNameExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]); | ||
return false; | ||
} | ||
if (_scanner.getToken() === SyntaxKind.ColonToken) { | ||
onSeparator(':'); | ||
scanNext(); // consume colon | ||
if (!parseValue()) { | ||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]); | ||
} | ||
else if (skipUntil.indexOf(token) !== -1) { | ||
break; | ||
} | ||
token = scanNext(); | ||
} | ||
else { | ||
handleError(ParseErrorCode.ColonExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]); | ||
} | ||
return true; | ||
} | ||
} | ||
function parseString(isValue) { | ||
if (_scanner.getToken() !== SyntaxKind.StringLiteral) { | ||
return false; | ||
} | ||
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; | ||
function parseObject() { | ||
if (_scanner.getToken() !== SyntaxKind.OpenBraceToken) { | ||
return false; | ||
} | ||
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 | ||
} | ||
catch (e) { | ||
handleError(ParseErrorCode.InvalidNumberFormat); | ||
else if (needsComma) { | ||
handleError(ParseErrorCode.CommaExpected, [], []); | ||
} | ||
onLiteralValue(value); | ||
break; | ||
case SyntaxKind.NullKeyword: | ||
onLiteralValue(null); | ||
break; | ||
case SyntaxKind.TrueKeyword: | ||
onLiteralValue(true); | ||
break; | ||
case SyntaxKind.FalseKeyword: | ||
onLiteralValue(false); | ||
break; | ||
default: | ||
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() { | ||
if (_scanner.getToken() !== SyntaxKind.OpenBracketToken) { | ||
return false; | ||
} | ||
scanNext(); | ||
return true; | ||
} | ||
function parseProperty() { | ||
if (!parseString(false)) { | ||
handleError(ParseErrorCode.PropertyNameExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]); | ||
return 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() { | ||
if (_scanner.getToken() !== SyntaxKind.OpenBraceToken) { | ||
return false; | ||
} | ||
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, [], []); | ||
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 | ||
} | ||
onSeparator(','); | ||
scanNext(); // consume comma | ||
else if (needsComma) { | ||
handleError(ParseErrorCode.CommaExpected, [], []); | ||
} | ||
if (!parseValue()) { | ||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken]); | ||
} | ||
needsComma = true; | ||
} | ||
else if (needsComma) { | ||
handleError(ParseErrorCode.CommaExpected, [], []); | ||
onArrayEnd(); | ||
if (_scanner.getToken() !== SyntaxKind.CloseBracketToken) { | ||
handleError(ParseErrorCode.CloseBracketExpected, [SyntaxKind.CloseBracketToken], []); | ||
} | ||
if (!parseProperty()) { | ||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBraceToken, SyntaxKind.CommaToken]); | ||
else { | ||
scanNext(); // consume close bracket | ||
} | ||
needsComma = true; | ||
return true; | ||
} | ||
onObjectEnd(); | ||
if (_scanner.getToken() !== SyntaxKind.CloseBraceToken) { | ||
handleError(ParseErrorCode.CloseBraceExpected, [SyntaxKind.CloseBraceToken], []); | ||
function parseValue() { | ||
return parseArray() || parseObject() || parseString(true) || parseLiteral(); | ||
} | ||
else { | ||
scanNext(); // consume close brace | ||
scanNext(); | ||
if (_scanner.getToken() === SyntaxKind.EOF) { | ||
return true; | ||
} | ||
return true; | ||
} | ||
function parseArray() { | ||
if (_scanner.getToken() !== SyntaxKind.OpenBracketToken) { | ||
if (!parseValue()) { | ||
handleError(ParseErrorCode.ValueExpected, [], []); | ||
return false; | ||
} | ||
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 | ||
} | ||
else if (needsComma) { | ||
handleError(ParseErrorCode.CommaExpected, [], []); | ||
} | ||
if (!parseValue()) { | ||
handleError(ParseErrorCode.ValueExpected, [], [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken]); | ||
} | ||
needsComma = true; | ||
if (_scanner.getToken() !== SyntaxKind.EOF) { | ||
handleError(ParseErrorCode.EndOfFileExpected, [], []); | ||
} | ||
onArrayEnd(); | ||
if (_scanner.getToken() !== SyntaxKind.CloseBracketToken) { | ||
handleError(ParseErrorCode.CloseBracketExpected, [SyntaxKind.CloseBracketToken], []); | ||
} | ||
else { | ||
scanNext(); // consume close bracket | ||
} | ||
return true; | ||
} | ||
function parseValue() { | ||
return parseArray() || parseObject() || parseString(true) || parseLiteral(); | ||
} | ||
scanNext(); | ||
if (!parseValue()) { | ||
handleError(ParseErrorCode.ValueExpected, [], []); | ||
return false; | ||
} | ||
if (_scanner.getToken() !== SyntaxKind.EOF) { | ||
handleError(ParseErrorCode.EndOfFileExpected, [], []); | ||
} | ||
return true; | ||
} | ||
exports.visit = visit; | ||
exports.visit = visit; | ||
}); | ||
//# sourceMappingURL=main.js.map |
{ | ||
"name": "jsonc-parser", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "Scanner and parser for JSON with comments.", | ||
@@ -5,0 +5,0 @@ "main": "./lib/main.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
65363
1234