jsonc-parser
Advanced tools
Comparing version 3.0.0 to 3.1.0
@@ -0,1 +1,5 @@ | ||
3.1.0 2022-07-07 | ||
================== | ||
* added new API `FormattingOptions.keepLines` : It leaves the initial line positions in the formatting | ||
3.0.0 2020-11-13 | ||
@@ -2,0 +6,0 @@ ================== |
@@ -6,2 +6,13 @@ /*--------------------------------------------------------------------------------------------- | ||
'use strict'; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
import { format, isEOL } from './format'; | ||
@@ -75,3 +86,3 @@ import { parseTree, findNodeAtLocation } from './parser'; | ||
} | ||
var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value); | ||
var newProperty = "".concat(JSON.stringify(lastSegment), ": ").concat(JSON.stringify(value)); | ||
var index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length; | ||
@@ -96,3 +107,3 @@ var edit = void 0; | ||
// Insert | ||
var newProperty = "" + JSON.stringify(value); | ||
var newProperty = "".concat(JSON.stringify(value)); | ||
var edit = void 0; | ||
@@ -131,3 +142,3 @@ if (parent.children.length === 0) { | ||
var edit = void 0; | ||
var newProperty = "" + JSON.stringify(value); | ||
var newProperty = "".concat(JSON.stringify(value)); | ||
if (!options.isArrayInsertion && parent.children.length > lastSegment) { | ||
@@ -148,7 +159,7 @@ var toModify = parent.children[lastSegment]; | ||
else { | ||
throw new Error("Can not " + (value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')) + " Array index " + insertIndex + " as length is not sufficient"); | ||
throw new Error("Can not ".concat(value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify'), " Array index ").concat(insertIndex, " as length is not sufficient")); | ||
} | ||
} | ||
else { | ||
throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type); | ||
throw new Error("Can not add ".concat(typeof lastSegment !== 'number' ? 'index' : 'property', " to parent of type ").concat(parent.type)); | ||
} | ||
@@ -173,3 +184,3 @@ } | ||
} | ||
var edits = format(newText, { offset: begin, length: end - begin }, options.formattingOptions); | ||
var edits = format(newText, { offset: begin, length: end - begin }, __assign(__assign({}, options.formattingOptions), { keepLines: false })); | ||
// apply the formatting edits and track the begin and end offsets of the changes | ||
@@ -176,0 +187,0 @@ for (var i = edits.length - 1; i >= 0; i--) { |
@@ -35,3 +35,3 @@ /*--------------------------------------------------------------------------------------------- | ||
var eol = getEOL(options, documentText); | ||
var lineBreak = false; | ||
var numberLineBreaks = 0; | ||
var indentLevel = 0; | ||
@@ -47,13 +47,23 @@ var indentValue; | ||
var hasError = false; | ||
function newLineAndIndent() { | ||
return eol + repeat(indentValue, initialIndentLevel + indentLevel); | ||
function newLinesAndIndent() { | ||
if (numberLineBreaks > 1) { | ||
return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel); | ||
} | ||
else { | ||
return eol + repeat(indentValue, initialIndentLevel + indentLevel); | ||
} | ||
} | ||
function scanNext() { | ||
var token = scanner.scan(); | ||
lineBreak = false; | ||
while (token === 15 /* Trivia */ || token === 14 /* LineBreakTrivia */) { | ||
lineBreak = lineBreak || (token === 14 /* LineBreakTrivia */); | ||
numberLineBreaks = 0; | ||
while (token === 15 /* SyntaxKind.Trivia */ || token === 14 /* SyntaxKind.LineBreakTrivia */) { | ||
if (token === 14 /* SyntaxKind.LineBreakTrivia */ && options.keepLines) { | ||
numberLineBreaks += 1; | ||
} | ||
else if (token === 14 /* SyntaxKind.LineBreakTrivia */) { | ||
numberLineBreaks = 1; | ||
} | ||
token = scanner.scan(); | ||
} | ||
hasError = token === 16 /* Unknown */ || scanner.getTokenError() !== 0 /* None */; | ||
hasError = token === 16 /* SyntaxKind.Unknown */ || scanner.getTokenError() !== 0 /* ScanError.None */; | ||
return token; | ||
@@ -68,3 +78,6 @@ } | ||
var firstToken = scanNext(); | ||
if (firstToken !== 17 /* EOF */) { | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
addEdit(repeat(eol, numberLineBreaks), 0, 0); | ||
} | ||
if (firstToken !== 17 /* SyntaxKind.EOF */) { | ||
var firstTokenStart = scanner.getTokenOffset() + formatTextStart; | ||
@@ -74,3 +87,3 @@ var initialIndent = repeat(indentValue, initialIndentLevel); | ||
} | ||
while (firstToken !== 17 /* EOF */) { | ||
while (firstToken !== 17 /* SyntaxKind.EOF */) { | ||
var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; | ||
@@ -80,81 +93,114 @@ var secondToken = scanNext(); | ||
var needsLineBreak = false; | ||
while (!lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) { | ||
// comments on the same line: keep them on the same line, but ignore them otherwise | ||
while (numberLineBreaks === 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) { | ||
var commentTokenStart = scanner.getTokenOffset() + formatTextStart; | ||
addEdit(' ', firstTokenEnd, commentTokenStart); | ||
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; | ||
needsLineBreak = secondToken === 12 /* LineCommentTrivia */; | ||
replaceContent = needsLineBreak ? newLineAndIndent() : ''; | ||
needsLineBreak = secondToken === 12 /* SyntaxKind.LineCommentTrivia */; | ||
replaceContent = needsLineBreak ? newLinesAndIndent() : ''; | ||
secondToken = scanNext(); | ||
} | ||
if (secondToken === 2 /* CloseBraceToken */) { | ||
if (firstToken !== 1 /* OpenBraceToken */) { | ||
if (secondToken === 2 /* SyntaxKind.CloseBraceToken */) { | ||
if (firstToken !== 1 /* SyntaxKind.OpenBraceToken */) { | ||
indentLevel--; | ||
replaceContent = newLineAndIndent(); | ||
} | ||
; | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 1 /* SyntaxKind.OpenBraceToken */) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (options.keepLines) { | ||
replaceContent = ' '; | ||
} | ||
} | ||
else if (secondToken === 4 /* CloseBracketToken */) { | ||
if (firstToken !== 3 /* OpenBracketToken */) { | ||
else if (secondToken === 4 /* SyntaxKind.CloseBracketToken */) { | ||
if (firstToken !== 3 /* SyntaxKind.OpenBracketToken */) { | ||
indentLevel--; | ||
replaceContent = newLineAndIndent(); | ||
} | ||
; | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 3 /* SyntaxKind.OpenBracketToken */) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (options.keepLines) { | ||
replaceContent = ' '; | ||
} | ||
} | ||
else { | ||
switch (firstToken) { | ||
case 3 /* OpenBracketToken */: | ||
case 1 /* OpenBraceToken */: | ||
case 3 /* SyntaxKind.OpenBracketToken */: | ||
case 1 /* SyntaxKind.OpenBraceToken */: | ||
indentLevel++; | ||
replaceContent = newLineAndIndent(); | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 5 /* CommaToken */: | ||
case 12 /* LineCommentTrivia */: | ||
replaceContent = newLineAndIndent(); | ||
case 5 /* SyntaxKind.CommaToken */: | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 13 /* BlockCommentTrivia */: | ||
if (lineBreak) { | ||
replaceContent = newLineAndIndent(); | ||
case 12 /* SyntaxKind.LineCommentTrivia */: | ||
replaceContent = newLinesAndIndent(); | ||
break; | ||
case 13 /* SyntaxKind.BlockCommentTrivia */: | ||
if (numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (!needsLineBreak) { | ||
// symbol following comment on the same line: keep on same line, separate with ' ' | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 6 /* ColonToken */: | ||
if (!needsLineBreak) { | ||
case 6 /* SyntaxKind.ColonToken */: | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (!needsLineBreak) { | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 10 /* StringLiteral */: | ||
if (secondToken === 6 /* ColonToken */) { | ||
if (!needsLineBreak) { | ||
replaceContent = ''; | ||
} | ||
break; | ||
case 10 /* SyntaxKind.StringLiteral */: | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
// fall through | ||
case 7 /* NullKeyword */: | ||
case 8 /* TrueKeyword */: | ||
case 9 /* FalseKeyword */: | ||
case 11 /* NumericLiteral */: | ||
case 2 /* CloseBraceToken */: | ||
case 4 /* CloseBracketToken */: | ||
if (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */) { | ||
if (!needsLineBreak) { | ||
else if (secondToken === 6 /* SyntaxKind.ColonToken */ && !needsLineBreak) { | ||
replaceContent = ''; | ||
} | ||
break; | ||
case 7 /* SyntaxKind.NullKeyword */: | ||
case 8 /* SyntaxKind.TrueKeyword */: | ||
case 9 /* SyntaxKind.FalseKeyword */: | ||
case 11 /* SyntaxKind.NumericLiteral */: | ||
case 2 /* SyntaxKind.CloseBraceToken */: | ||
case 4 /* SyntaxKind.CloseBracketToken */: | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
if ((secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */) && !needsLineBreak) { | ||
replaceContent = ' '; | ||
} | ||
else if (secondToken !== 5 /* SyntaxKind.CommaToken */ && secondToken !== 17 /* SyntaxKind.EOF */) { | ||
hasError = true; | ||
} | ||
} | ||
else if (secondToken !== 5 /* CommaToken */ && secondToken !== 17 /* EOF */) { | ||
hasError = true; | ||
} | ||
break; | ||
case 16 /* Unknown */: | ||
case 16 /* SyntaxKind.Unknown */: | ||
hasError = true; | ||
break; | ||
} | ||
if (lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) { | ||
replaceContent = newLineAndIndent(); | ||
if (numberLineBreaks > 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
} | ||
if (secondToken === 17 /* EOF */) { | ||
replaceContent = options.insertFinalNewline ? eol : ''; | ||
if (secondToken === 17 /* SyntaxKind.EOF */) { | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
replaceContent = options.insertFinalNewline ? eol : ''; | ||
} | ||
} | ||
@@ -161,0 +207,0 @@ var secondTokenStart = scanner.getTokenOffset() + formatTextStart; |
@@ -263,3 +263,3 @@ /*--------------------------------------------------------------------------------------------- | ||
var propertyNode = _b[_a]; | ||
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment) { | ||
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) { | ||
node = propertyNode.children[1]; | ||
@@ -359,9 +359,18 @@ found = true; | ||
var _scanner = createScanner(text, false); | ||
// Important: Only pass copies of this to visitor functions to prevent accidental modification, and | ||
// to not affect visitor functions which stored a reference to a previous JSONPath | ||
var _jsonPath = []; | ||
function toNoArgVisit(visitFunction) { | ||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : function () { return true; }; | ||
} | ||
function toNoArgVisitWithPath(visitFunction) { | ||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), function () { return _jsonPath.slice(); }); } : function () { return true; }; | ||
} | ||
function toOneArgVisit(visitFunction) { | ||
return visitFunction ? function (arg) { return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : 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), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError); | ||
function toOneArgVisitWithPath(visitFunction) { | ||
return visitFunction ? function (arg) { return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), function () { return _jsonPath.slice(); }); } : function () { return true; }; | ||
} | ||
var onObjectBegin = toNoArgVisitWithPath(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toNoArgVisit(visitor.onObjectEnd), onArrayBegin = toNoArgVisitWithPath(visitor.onArrayBegin), onArrayEnd = toNoArgVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError); | ||
var disallowComments = options && options.disallowComments; | ||
@@ -373,28 +382,28 @@ var allowTrailingComma = options && options.allowTrailingComma; | ||
switch (_scanner.getTokenError()) { | ||
case 4 /* InvalidUnicode */: | ||
handleError(14 /* InvalidUnicode */); | ||
case 4 /* ScanError.InvalidUnicode */: | ||
handleError(14 /* ParseErrorCode.InvalidUnicode */); | ||
break; | ||
case 5 /* InvalidEscapeCharacter */: | ||
handleError(15 /* InvalidEscapeCharacter */); | ||
case 5 /* ScanError.InvalidEscapeCharacter */: | ||
handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */); | ||
break; | ||
case 3 /* UnexpectedEndOfNumber */: | ||
handleError(13 /* UnexpectedEndOfNumber */); | ||
case 3 /* ScanError.UnexpectedEndOfNumber */: | ||
handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */); | ||
break; | ||
case 1 /* UnexpectedEndOfComment */: | ||
case 1 /* ScanError.UnexpectedEndOfComment */: | ||
if (!disallowComments) { | ||
handleError(11 /* UnexpectedEndOfComment */); | ||
handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */); | ||
} | ||
break; | ||
case 2 /* UnexpectedEndOfString */: | ||
handleError(12 /* UnexpectedEndOfString */); | ||
case 2 /* ScanError.UnexpectedEndOfString */: | ||
handleError(12 /* ParseErrorCode.UnexpectedEndOfString */); | ||
break; | ||
case 6 /* InvalidCharacter */: | ||
handleError(16 /* InvalidCharacter */); | ||
case 6 /* ScanError.InvalidCharacter */: | ||
handleError(16 /* ParseErrorCode.InvalidCharacter */); | ||
break; | ||
} | ||
switch (token) { | ||
case 12 /* LineCommentTrivia */: | ||
case 13 /* BlockCommentTrivia */: | ||
case 12 /* SyntaxKind.LineCommentTrivia */: | ||
case 13 /* SyntaxKind.BlockCommentTrivia */: | ||
if (disallowComments) { | ||
handleError(10 /* InvalidCommentToken */); | ||
handleError(10 /* ParseErrorCode.InvalidCommentToken */); | ||
} | ||
@@ -405,7 +414,7 @@ else { | ||
break; | ||
case 16 /* Unknown */: | ||
handleError(1 /* InvalidSymbol */); | ||
case 16 /* SyntaxKind.Unknown */: | ||
handleError(1 /* ParseErrorCode.InvalidSymbol */); | ||
break; | ||
case 15 /* Trivia */: | ||
case 14 /* LineBreakTrivia */: | ||
case 15 /* SyntaxKind.Trivia */: | ||
case 14 /* SyntaxKind.LineBreakTrivia */: | ||
break; | ||
@@ -423,3 +432,3 @@ default: | ||
var token = _scanner.getToken(); | ||
while (token !== 17 /* EOF */) { | ||
while (token !== 17 /* SyntaxKind.EOF */) { | ||
if (skipUntilAfter.indexOf(token) !== -1) { | ||
@@ -443,2 +452,4 @@ scanNext(); | ||
onObjectProperty(value); | ||
// add property name afterwards | ||
_jsonPath.push(value); | ||
} | ||
@@ -450,7 +461,7 @@ scanNext(); | ||
switch (_scanner.getToken()) { | ||
case 11 /* NumericLiteral */: | ||
case 11 /* SyntaxKind.NumericLiteral */: | ||
var tokenValue = _scanner.getTokenValue(); | ||
var value = Number(tokenValue); | ||
if (isNaN(value)) { | ||
handleError(2 /* InvalidNumberFormat */); | ||
handleError(2 /* ParseErrorCode.InvalidNumberFormat */); | ||
value = 0; | ||
@@ -460,9 +471,9 @@ } | ||
break; | ||
case 7 /* NullKeyword */: | ||
case 7 /* SyntaxKind.NullKeyword */: | ||
onLiteralValue(null); | ||
break; | ||
case 8 /* TrueKeyword */: | ||
case 8 /* SyntaxKind.TrueKeyword */: | ||
onLiteralValue(true); | ||
break; | ||
case 9 /* FalseKeyword */: | ||
case 9 /* SyntaxKind.FalseKeyword */: | ||
onLiteralValue(false); | ||
@@ -477,17 +488,18 @@ break; | ||
function parseProperty() { | ||
if (_scanner.getToken() !== 10 /* StringLiteral */) { | ||
handleError(3 /* PropertyNameExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) { | ||
handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
return false; | ||
} | ||
parseString(false); | ||
if (_scanner.getToken() === 6 /* ColonToken */) { | ||
if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) { | ||
onSeparator(':'); | ||
scanNext(); // consume colon | ||
if (!parseValue()) { | ||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
} | ||
else { | ||
handleError(5 /* ColonExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
_jsonPath.pop(); // remove processed property name | ||
return true; | ||
@@ -499,10 +511,10 @@ } | ||
var needsComma = false; | ||
while (_scanner.getToken() !== 2 /* CloseBraceToken */ && _scanner.getToken() !== 17 /* EOF */) { | ||
if (_scanner.getToken() === 5 /* CommaToken */) { | ||
while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) { | ||
if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) { | ||
if (!needsComma) { | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
} | ||
onSeparator(','); | ||
scanNext(); // consume comma | ||
if (_scanner.getToken() === 2 /* CloseBraceToken */ && allowTrailingComma) { | ||
if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) { | ||
break; | ||
@@ -512,6 +524,6 @@ } | ||
else if (needsComma) { | ||
handleError(6 /* CommaExpected */, [], []); | ||
handleError(6 /* ParseErrorCode.CommaExpected */, [], []); | ||
} | ||
if (!parseProperty()) { | ||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
@@ -521,4 +533,4 @@ needsComma = true; | ||
onObjectEnd(); | ||
if (_scanner.getToken() !== 2 /* CloseBraceToken */) { | ||
handleError(7 /* CloseBraceExpected */, [2 /* CloseBraceToken */], []); | ||
if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) { | ||
handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []); | ||
} | ||
@@ -533,11 +545,12 @@ else { | ||
scanNext(); // consume open bracket | ||
var isFirstElement = true; | ||
var needsComma = false; | ||
while (_scanner.getToken() !== 4 /* CloseBracketToken */ && _scanner.getToken() !== 17 /* EOF */) { | ||
if (_scanner.getToken() === 5 /* CommaToken */) { | ||
while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) { | ||
if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) { | ||
if (!needsComma) { | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
} | ||
onSeparator(','); | ||
scanNext(); // consume comma | ||
if (_scanner.getToken() === 4 /* CloseBracketToken */ && allowTrailingComma) { | ||
if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) { | ||
break; | ||
@@ -547,6 +560,13 @@ } | ||
else if (needsComma) { | ||
handleError(6 /* CommaExpected */, [], []); | ||
handleError(6 /* ParseErrorCode.CommaExpected */, [], []); | ||
} | ||
if (isFirstElement) { | ||
_jsonPath.push(0); | ||
isFirstElement = false; | ||
} | ||
else { | ||
_jsonPath[_jsonPath.length - 1]++; | ||
} | ||
if (!parseValue()) { | ||
handleError(4 /* ValueExpected */, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
@@ -556,5 +576,8 @@ needsComma = true; | ||
onArrayEnd(); | ||
if (_scanner.getToken() !== 4 /* CloseBracketToken */) { | ||
handleError(8 /* CloseBracketExpected */, [4 /* CloseBracketToken */], []); | ||
if (!isFirstElement) { | ||
_jsonPath.pop(); // remove array index | ||
} | ||
if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) { | ||
handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []); | ||
} | ||
else { | ||
@@ -567,7 +590,7 @@ scanNext(); // consume close bracket | ||
switch (_scanner.getToken()) { | ||
case 3 /* OpenBracketToken */: | ||
case 3 /* SyntaxKind.OpenBracketToken */: | ||
return parseArray(); | ||
case 1 /* OpenBraceToken */: | ||
case 1 /* SyntaxKind.OpenBraceToken */: | ||
return parseObject(); | ||
case 10 /* StringLiteral */: | ||
case 10 /* SyntaxKind.StringLiteral */: | ||
return parseString(true); | ||
@@ -579,15 +602,15 @@ default: | ||
scanNext(); | ||
if (_scanner.getToken() === 17 /* EOF */) { | ||
if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) { | ||
if (options.allowEmptyContent) { | ||
return true; | ||
} | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
return false; | ||
} | ||
if (!parseValue()) { | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
return false; | ||
} | ||
if (_scanner.getToken() !== 17 /* EOF */) { | ||
handleError(9 /* EndOfFileExpected */, [], []); | ||
if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) { | ||
handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []); | ||
} | ||
@@ -607,5 +630,5 @@ return true; | ||
switch (kind) { | ||
case 12 /* LineCommentTrivia */: | ||
case 13 /* BlockCommentTrivia */: | ||
case 17 /* EOF */: | ||
case 12 /* SyntaxKind.LineCommentTrivia */: | ||
case 13 /* SyntaxKind.BlockCommentTrivia */: | ||
case 17 /* SyntaxKind.EOF */: | ||
if (offset !== pos) { | ||
@@ -620,3 +643,3 @@ parts.push(text.substring(offset, pos)); | ||
} | ||
} while (kind !== 17 /* EOF */); | ||
} while (kind !== 17 /* SyntaxKind.EOF */); | ||
return parts.join(''); | ||
@@ -623,0 +646,0 @@ } |
@@ -13,3 +13,3 @@ /*--------------------------------------------------------------------------------------------- | ||
var len = text.length; | ||
var pos = 0, value = '', tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */; | ||
var 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) { | ||
@@ -20,10 +20,10 @@ var digits = 0; | ||
var ch = text.charCodeAt(pos); | ||
if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) { | ||
value = value * 16 + ch - 48 /* _0 */; | ||
if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) { | ||
value = value * 16 + ch - 48 /* CharacterCodes._0 */; | ||
} | ||
else if (ch >= 65 /* A */ && ch <= 70 /* F */) { | ||
value = value * 16 + ch - 65 /* A */ + 10; | ||
else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) { | ||
value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10; | ||
} | ||
else if (ch >= 97 /* a */ && ch <= 102 /* f */) { | ||
value = value * 16 + ch - 97 /* a */ + 10; | ||
else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) { | ||
value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10; | ||
} | ||
@@ -45,8 +45,8 @@ else { | ||
tokenOffset = 0; | ||
token = 16 /* Unknown */; | ||
scanError = 0 /* None */; | ||
token = 16 /* SyntaxKind.Unknown */; | ||
scanError = 0 /* ScanError.None */; | ||
} | ||
function scanNumber() { | ||
var start = pos; | ||
if (text.charCodeAt(pos) === 48 /* _0 */) { | ||
if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) { | ||
pos++; | ||
@@ -60,3 +60,3 @@ } | ||
} | ||
if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) { | ||
if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) { | ||
pos++; | ||
@@ -70,3 +70,3 @@ if (pos < text.length && isDigit(text.charCodeAt(pos))) { | ||
else { | ||
scanError = 3 /* UnexpectedEndOfNumber */; | ||
scanError = 3 /* ScanError.UnexpectedEndOfNumber */; | ||
return text.substring(start, pos); | ||
@@ -76,5 +76,5 @@ } | ||
var end = pos; | ||
if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) { | ||
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 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) { | ||
if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) { | ||
pos++; | ||
@@ -90,3 +90,3 @@ } | ||
else { | ||
scanError = 3 /* UnexpectedEndOfNumber */; | ||
scanError = 3 /* ScanError.UnexpectedEndOfNumber */; | ||
} | ||
@@ -101,7 +101,7 @@ } | ||
result += text.substring(start, pos); | ||
scanError = 2 /* UnexpectedEndOfString */; | ||
scanError = 2 /* ScanError.UnexpectedEndOfString */; | ||
break; | ||
} | ||
var ch = text.charCodeAt(pos); | ||
if (ch === 34 /* doubleQuote */) { | ||
if (ch === 34 /* CharacterCodes.doubleQuote */) { | ||
result += text.substring(start, pos); | ||
@@ -111,7 +111,7 @@ pos++; | ||
} | ||
if (ch === 92 /* backslash */) { | ||
if (ch === 92 /* CharacterCodes.backslash */) { | ||
result += text.substring(start, pos); | ||
pos++; | ||
if (pos >= len) { | ||
scanError = 2 /* UnexpectedEndOfString */; | ||
scanError = 2 /* ScanError.UnexpectedEndOfString */; | ||
break; | ||
@@ -121,27 +121,27 @@ } | ||
switch (ch2) { | ||
case 34 /* doubleQuote */: | ||
case 34 /* CharacterCodes.doubleQuote */: | ||
result += '\"'; | ||
break; | ||
case 92 /* backslash */: | ||
case 92 /* CharacterCodes.backslash */: | ||
result += '\\'; | ||
break; | ||
case 47 /* slash */: | ||
case 47 /* CharacterCodes.slash */: | ||
result += '/'; | ||
break; | ||
case 98 /* b */: | ||
case 98 /* CharacterCodes.b */: | ||
result += '\b'; | ||
break; | ||
case 102 /* f */: | ||
case 102 /* CharacterCodes.f */: | ||
result += '\f'; | ||
break; | ||
case 110 /* n */: | ||
case 110 /* CharacterCodes.n */: | ||
result += '\n'; | ||
break; | ||
case 114 /* r */: | ||
case 114 /* CharacterCodes.r */: | ||
result += '\r'; | ||
break; | ||
case 116 /* t */: | ||
case 116 /* CharacterCodes.t */: | ||
result += '\t'; | ||
break; | ||
case 117 /* u */: | ||
case 117 /* CharacterCodes.u */: | ||
var ch3 = scanHexDigits(4, true); | ||
@@ -152,7 +152,7 @@ if (ch3 >= 0) { | ||
else { | ||
scanError = 4 /* InvalidUnicode */; | ||
scanError = 4 /* ScanError.InvalidUnicode */; | ||
} | ||
break; | ||
default: | ||
scanError = 5 /* InvalidEscapeCharacter */; | ||
scanError = 5 /* ScanError.InvalidEscapeCharacter */; | ||
} | ||
@@ -165,7 +165,7 @@ start = pos; | ||
result += text.substring(start, pos); | ||
scanError = 2 /* UnexpectedEndOfString */; | ||
scanError = 2 /* ScanError.UnexpectedEndOfString */; | ||
break; | ||
} | ||
else { | ||
scanError = 6 /* InvalidCharacter */; | ||
scanError = 6 /* ScanError.InvalidCharacter */; | ||
// mark as error but continue with string | ||
@@ -180,3 +180,3 @@ } | ||
value = ''; | ||
scanError = 0 /* None */; | ||
scanError = 0 /* ScanError.None */; | ||
tokenOffset = pos; | ||
@@ -188,3 +188,3 @@ lineStartOffset = lineNumber; | ||
tokenOffset = len; | ||
return token = 17 /* EOF */; | ||
return token = 17 /* SyntaxKind.EOF */; | ||
} | ||
@@ -199,3 +199,3 @@ var code = text.charCodeAt(pos); | ||
} while (isWhiteSpace(code)); | ||
return token = 15 /* Trivia */; | ||
return token = 15 /* SyntaxKind.Trivia */; | ||
} | ||
@@ -206,3 +206,3 @@ // trivia: newlines | ||
value += String.fromCharCode(code); | ||
if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) { | ||
if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) { | ||
pos++; | ||
@@ -213,34 +213,34 @@ value += '\n'; | ||
tokenLineStartOffset = pos; | ||
return token = 14 /* LineBreakTrivia */; | ||
return token = 14 /* SyntaxKind.LineBreakTrivia */; | ||
} | ||
switch (code) { | ||
// tokens: []{}:, | ||
case 123 /* openBrace */: | ||
case 123 /* CharacterCodes.openBrace */: | ||
pos++; | ||
return token = 1 /* OpenBraceToken */; | ||
case 125 /* closeBrace */: | ||
return token = 1 /* SyntaxKind.OpenBraceToken */; | ||
case 125 /* CharacterCodes.closeBrace */: | ||
pos++; | ||
return token = 2 /* CloseBraceToken */; | ||
case 91 /* openBracket */: | ||
return token = 2 /* SyntaxKind.CloseBraceToken */; | ||
case 91 /* CharacterCodes.openBracket */: | ||
pos++; | ||
return token = 3 /* OpenBracketToken */; | ||
case 93 /* closeBracket */: | ||
return token = 3 /* SyntaxKind.OpenBracketToken */; | ||
case 93 /* CharacterCodes.closeBracket */: | ||
pos++; | ||
return token = 4 /* CloseBracketToken */; | ||
case 58 /* colon */: | ||
return token = 4 /* SyntaxKind.CloseBracketToken */; | ||
case 58 /* CharacterCodes.colon */: | ||
pos++; | ||
return token = 6 /* ColonToken */; | ||
case 44 /* comma */: | ||
return token = 6 /* SyntaxKind.ColonToken */; | ||
case 44 /* CharacterCodes.comma */: | ||
pos++; | ||
return token = 5 /* CommaToken */; | ||
return token = 5 /* SyntaxKind.CommaToken */; | ||
// strings | ||
case 34 /* doubleQuote */: | ||
case 34 /* CharacterCodes.doubleQuote */: | ||
pos++; | ||
value = scanString(); | ||
return token = 10 /* StringLiteral */; | ||
return token = 10 /* SyntaxKind.StringLiteral */; | ||
// comments | ||
case 47 /* slash */: | ||
case 47 /* CharacterCodes.slash */: | ||
var start = pos - 1; | ||
// Single-line comment | ||
if (text.charCodeAt(pos + 1) === 47 /* slash */) { | ||
if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) { | ||
pos += 2; | ||
@@ -254,6 +254,6 @@ while (pos < len) { | ||
value = text.substring(start, pos); | ||
return token = 12 /* LineCommentTrivia */; | ||
return token = 12 /* SyntaxKind.LineCommentTrivia */; | ||
} | ||
// Multi-line comment | ||
if (text.charCodeAt(pos + 1) === 42 /* asterisk */) { | ||
if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) { | ||
pos += 2; | ||
@@ -264,3 +264,3 @@ var safeLength = len - 1; // For lookahead. | ||
var ch = text.charCodeAt(pos); | ||
if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) { | ||
if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) { | ||
pos += 2; | ||
@@ -272,3 +272,3 @@ commentClosed = true; | ||
if (isLineBreak(ch)) { | ||
if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) { | ||
if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) { | ||
pos++; | ||
@@ -282,6 +282,6 @@ } | ||
pos++; | ||
scanError = 1 /* UnexpectedEndOfComment */; | ||
scanError = 1 /* ScanError.UnexpectedEndOfComment */; | ||
} | ||
value = text.substring(start, pos); | ||
return token = 13 /* BlockCommentTrivia */; | ||
return token = 13 /* SyntaxKind.BlockCommentTrivia */; | ||
} | ||
@@ -291,9 +291,9 @@ // just a single slash | ||
pos++; | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
// numbers | ||
case 45 /* minus */: | ||
case 45 /* CharacterCodes.minus */: | ||
value += String.fromCharCode(code); | ||
pos++; | ||
if (pos === len || !isDigit(text.charCodeAt(pos))) { | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
} | ||
@@ -303,14 +303,14 @@ // found a minus, followed by a number so | ||
// numbers | ||
case 48 /* _0 */: | ||
case 49 /* _1 */: | ||
case 50 /* _2 */: | ||
case 51 /* _3 */: | ||
case 52 /* _4 */: | ||
case 53 /* _5 */: | ||
case 54 /* _6 */: | ||
case 55 /* _7 */: | ||
case 56 /* _8 */: | ||
case 57 /* _9 */: | ||
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 /* NumericLiteral */; | ||
return token = 11 /* SyntaxKind.NumericLiteral */; | ||
// literals and unknown symbols | ||
@@ -327,7 +327,7 @@ default: | ||
switch (value) { | ||
case 'true': return token = 8 /* TrueKeyword */; | ||
case 'false': return token = 9 /* FalseKeyword */; | ||
case 'null': return token = 7 /* NullKeyword */; | ||
case 'true': return token = 8 /* SyntaxKind.TrueKeyword */; | ||
case 'false': return token = 9 /* SyntaxKind.FalseKeyword */; | ||
case 'null': return token = 7 /* SyntaxKind.NullKeyword */; | ||
} | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
} | ||
@@ -337,3 +337,3 @@ // some | ||
pos++; | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
} | ||
@@ -346,10 +346,10 @@ } | ||
switch (code) { | ||
case 125 /* closeBrace */: | ||
case 93 /* closeBracket */: | ||
case 123 /* openBrace */: | ||
case 91 /* openBracket */: | ||
case 34 /* doubleQuote */: | ||
case 58 /* colon */: | ||
case 44 /* comma */: | ||
case 47 /* slash */: | ||
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; | ||
@@ -363,3 +363,3 @@ } | ||
result = scanNext(); | ||
} while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */); | ||
} while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */); | ||
return result; | ||
@@ -381,11 +381,9 @@ } | ||
function isWhiteSpace(ch) { | ||
return ch === 32 /* space */ || ch === 9 /* tab */ || ch === 11 /* verticalTab */ || ch === 12 /* formFeed */ || | ||
ch === 160 /* nonBreakingSpace */ || ch === 5760 /* ogham */ || ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ || | ||
ch === 8239 /* narrowNoBreakSpace */ || ch === 8287 /* mathematicalSpace */ || ch === 12288 /* ideographicSpace */ || ch === 65279 /* byteOrderMark */; | ||
return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */; | ||
} | ||
function isLineBreak(ch) { | ||
return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */; | ||
return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */; | ||
} | ||
function isDigit(ch) { | ||
return ch >= 48 /* _0 */ && ch <= 57 /* _9 */; | ||
return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */; | ||
} |
@@ -47,3 +47,3 @@ /** | ||
/** | ||
* Returns the current scan position, which is after the last read token. | ||
* Returns the zero-based current scan position, which is after the last read token. | ||
*/ | ||
@@ -60,3 +60,3 @@ getPosition(): number; | ||
/** | ||
* The start offset of the last read token. | ||
* The zero-based start offset of the last read token. | ||
*/ | ||
@@ -154,2 +154,6 @@ getTokenOffset(): number; | ||
} | ||
/** | ||
* A {@linkcode JSONPath} segment. Either a string representing an object property name | ||
* or a number (starting at 0) for array indices. | ||
*/ | ||
export declare type Segment = string | number; | ||
@@ -183,2 +187,13 @@ export declare type JSONPath = Segment[]; | ||
} | ||
/** | ||
* Visitor called by {@linkcode visit} when parsing JSON. | ||
* | ||
* The visitor functions have the following common parameters: | ||
* - `offset`: Global offset within the JSON document, starting at 0 | ||
* - `startLine`: Line number, starting at 0 | ||
* - `startCharacter`: Start character (column) within the current line, starting at 0 | ||
* | ||
* Additionally some functions have a `pathSupplier` parameter which can be used to obtain the | ||
* current `JSONPath` within the document. | ||
*/ | ||
export interface JSONVisitor { | ||
@@ -188,7 +203,9 @@ /** | ||
*/ | ||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
* Invoked when a property is encountered. The offset and length represent the location of the property name. | ||
* The `JSONPath` created by the `pathSupplier` refers to the enclosing JSON object, it does not include the | ||
* property name yet. | ||
*/ | ||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -201,3 +218,3 @@ * Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace. | ||
*/ | ||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -210,3 +227,3 @@ * Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket. | ||
*/ | ||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -226,2 +243,13 @@ * Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator. | ||
/** | ||
* An edit result describes a textual edit operation. It is the result of a {@linkcode format} and {@linkcode modify} operation. | ||
* It consist of one or more edits describing insertions, replacements or removals of text segments. | ||
* * The offsets of the edits refer to the original state of the document. | ||
* * No two edits change or remove the same range of text in the original document. | ||
* * Multiple edits can have the same offset if they are multiple inserts, or an insert followed by a remove or replace. | ||
* * The order in the array defines which edit is applied first. | ||
* To apply an edit result use {@linkcode applyEdits}. | ||
* In general multiple EditResults must not be concatenated because they might impact each other, producing incorrect or malformed JSON data. | ||
*/ | ||
export declare type EditResult = Edit[]; | ||
/** | ||
* Represents a text modification | ||
@@ -256,2 +284,5 @@ */ | ||
} | ||
/** | ||
* Options used by {@linkcode format} when computing the formatting edit operations | ||
*/ | ||
export interface FormattingOptions { | ||
@@ -274,5 +305,9 @@ /** | ||
insertFinalNewline?: boolean; | ||
/** | ||
* If true, will keep line positions as is in the formatting | ||
*/ | ||
keepLines?: boolean; | ||
} | ||
/** | ||
* Computes the edits needed to format a JSON document. | ||
* Computes the edit operations needed to format a JSON document. | ||
* | ||
@@ -282,11 +317,8 @@ * @param documentText The input text | ||
* @param options The formatting options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
export declare function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[]; | ||
export declare function format(documentText: string, range: Range | undefined, options: FormattingOptions): EditResult; | ||
/** | ||
* Options used when computing the modification edits | ||
* Options used by {@linkcode modify} when computing the modification edit operations | ||
*/ | ||
@@ -299,4 +331,4 @@ export interface ModificationOptions { | ||
/** | ||
* Default false. If `JSONPath` refers to an index of an array and {@property isArrayInsertion} is `true`, then | ||
* {@function modify} will insert a new item at that location instead of overwriting its contents. | ||
* Default false. If `JSONPath` refers to an index of an array and `isArrayInsertion` is `true`, then | ||
* {@linkcode modify} will insert a new item at that location instead of overwriting its contents. | ||
*/ | ||
@@ -310,3 +342,3 @@ isArrayInsertion?: boolean; | ||
/** | ||
* Computes the edits needed to modify a value in the JSON document. | ||
* Computes the edit operations needed to modify a value in the JSON document. | ||
* | ||
@@ -319,12 +351,13 @@ * @param documentText The input text | ||
* @param options Options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
export declare function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): Edit[]; | ||
export declare function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): EditResult; | ||
/** | ||
* Applies edits to a input string. | ||
* Applies edits to an input string. | ||
* @param text The input text | ||
* @param edits Edit operations following the format described in {@linkcode EditResult}. | ||
* @returns The text with the applied edits. | ||
* @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}. | ||
*/ | ||
export declare function applyEdits(text: string, edits: Edit[]): string; | ||
export declare function applyEdits(text: string, edits: EditResult): string; |
@@ -56,18 +56,18 @@ /*--------------------------------------------------------------------------------------------- | ||
switch (code) { | ||
case 1 /* InvalidSymbol */: return 'InvalidSymbol'; | ||
case 2 /* InvalidNumberFormat */: return 'InvalidNumberFormat'; | ||
case 3 /* PropertyNameExpected */: return 'PropertyNameExpected'; | ||
case 4 /* ValueExpected */: return 'ValueExpected'; | ||
case 5 /* ColonExpected */: return 'ColonExpected'; | ||
case 6 /* CommaExpected */: return 'CommaExpected'; | ||
case 7 /* CloseBraceExpected */: return 'CloseBraceExpected'; | ||
case 8 /* CloseBracketExpected */: return 'CloseBracketExpected'; | ||
case 9 /* EndOfFileExpected */: return 'EndOfFileExpected'; | ||
case 10 /* InvalidCommentToken */: return 'InvalidCommentToken'; | ||
case 11 /* UnexpectedEndOfComment */: return 'UnexpectedEndOfComment'; | ||
case 12 /* UnexpectedEndOfString */: return 'UnexpectedEndOfString'; | ||
case 13 /* UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber'; | ||
case 14 /* InvalidUnicode */: return 'InvalidUnicode'; | ||
case 15 /* InvalidEscapeCharacter */: return 'InvalidEscapeCharacter'; | ||
case 16 /* InvalidCharacter */: return 'InvalidCharacter'; | ||
case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol'; | ||
case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat'; | ||
case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected'; | ||
case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected'; | ||
case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected'; | ||
case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected'; | ||
case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected'; | ||
case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected'; | ||
case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected'; | ||
case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken'; | ||
case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment'; | ||
case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString'; | ||
case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber'; | ||
case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode'; | ||
case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter'; | ||
case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter'; | ||
} | ||
@@ -77,3 +77,3 @@ return '<unknown ParseErrorCode>'; | ||
/** | ||
* Computes the edits needed to format a JSON document. | ||
* Computes the edit operations needed to format a JSON document. | ||
* | ||
@@ -83,7 +83,4 @@ * @param documentText The input text | ||
* @param options The formatting options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
@@ -94,3 +91,3 @@ export function format(documentText, range, options) { | ||
/** | ||
* Computes the edits needed to modify a value in the JSON document. | ||
* Computes the edit operations needed to modify a value in the JSON document. | ||
* | ||
@@ -103,7 +100,4 @@ * @param documentText The input text | ||
* @param options Options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
@@ -114,3 +108,7 @@ export function modify(text, path, value, options) { | ||
/** | ||
* Applies edits to a input string. | ||
* Applies edits to an input string. | ||
* @param text The input text | ||
* @param edits Edit operations following the format described in {@linkcode EditResult}. | ||
* @returns The text with the applied edits. | ||
* @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}. | ||
*/ | ||
@@ -117,0 +115,0 @@ export function applyEdits(text, edits) { |
@@ -0,1 +1,12 @@ | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
(function (factory) { | ||
@@ -27,3 +38,3 @@ if (typeof module === "object" && typeof module.exports === "object") { | ||
var errors = []; | ||
var root = parser_1.parseTree(text, errors); | ||
var root = (0, parser_1.parseTree)(text, errors); | ||
var parent = void 0; | ||
@@ -33,3 +44,3 @@ var lastSegment = void 0; | ||
lastSegment = path.pop(); | ||
parent = parser_1.findNodeAtLocation(root, path); | ||
parent = (0, parser_1.findNodeAtLocation)(root, path); | ||
if (parent === void 0 && value !== void 0) { | ||
@@ -55,3 +66,3 @@ if (typeof lastSegment === 'string') { | ||
else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) { | ||
var existing = parser_1.findNodeAtLocation(parent, [lastSegment]); | ||
var existing = (0, parser_1.findNodeAtLocation)(parent, [lastSegment]); | ||
if (existing !== void 0) { | ||
@@ -89,3 +100,3 @@ if (value === void 0) { // delete | ||
} | ||
var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value); | ||
var newProperty = "".concat(JSON.stringify(lastSegment), ": ").concat(JSON.stringify(value)); | ||
var index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length; | ||
@@ -110,3 +121,3 @@ var edit = void 0; | ||
// Insert | ||
var newProperty = "" + JSON.stringify(value); | ||
var newProperty = "".concat(JSON.stringify(value)); | ||
var edit = void 0; | ||
@@ -145,3 +156,3 @@ if (parent.children.length === 0) { | ||
var edit = void 0; | ||
var newProperty = "" + JSON.stringify(value); | ||
var newProperty = "".concat(JSON.stringify(value)); | ||
if (!options.isArrayInsertion && parent.children.length > lastSegment) { | ||
@@ -162,7 +173,7 @@ var toModify = parent.children[lastSegment]; | ||
else { | ||
throw new Error("Can not " + (value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')) + " Array index " + insertIndex + " as length is not sufficient"); | ||
throw new Error("Can not ".concat(value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify'), " Array index ").concat(insertIndex, " as length is not sufficient")); | ||
} | ||
} | ||
else { | ||
throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type); | ||
throw new Error("Can not add ".concat(typeof lastSegment !== 'number' ? 'index' : 'property', " to parent of type ").concat(parent.type)); | ||
} | ||
@@ -181,10 +192,10 @@ } | ||
if (edit.length === 0 || edit.content.length === 0) { // insert or remove | ||
while (begin > 0 && !format_1.isEOL(newText, begin - 1)) { | ||
while (begin > 0 && !(0, format_1.isEOL)(newText, begin - 1)) { | ||
begin--; | ||
} | ||
while (end < newText.length && !format_1.isEOL(newText, end)) { | ||
while (end < newText.length && !(0, format_1.isEOL)(newText, end)) { | ||
end++; | ||
} | ||
} | ||
var edits = format_1.format(newText, { offset: begin, length: end - begin }, options.formattingOptions); | ||
var edits = (0, format_1.format)(newText, { offset: begin, length: end - begin }, __assign(__assign({}, options.formattingOptions), { keepLines: false })); | ||
// apply the formatting edits and track the begin and end offsets of the changes | ||
@@ -191,0 +202,0 @@ for (var i = edits.length - 1; i >= 0; i--) { |
@@ -46,3 +46,3 @@ (function (factory) { | ||
var eol = getEOL(options, documentText); | ||
var lineBreak = false; | ||
var numberLineBreaks = 0; | ||
var indentLevel = 0; | ||
@@ -56,15 +56,25 @@ var indentValue; | ||
} | ||
var scanner = scanner_1.createScanner(formatText, false); | ||
var scanner = (0, scanner_1.createScanner)(formatText, false); | ||
var hasError = false; | ||
function newLineAndIndent() { | ||
return eol + repeat(indentValue, initialIndentLevel + indentLevel); | ||
function newLinesAndIndent() { | ||
if (numberLineBreaks > 1) { | ||
return repeat(eol, numberLineBreaks) + repeat(indentValue, initialIndentLevel + indentLevel); | ||
} | ||
else { | ||
return eol + repeat(indentValue, initialIndentLevel + indentLevel); | ||
} | ||
} | ||
function scanNext() { | ||
var token = scanner.scan(); | ||
lineBreak = false; | ||
while (token === 15 /* Trivia */ || token === 14 /* LineBreakTrivia */) { | ||
lineBreak = lineBreak || (token === 14 /* LineBreakTrivia */); | ||
numberLineBreaks = 0; | ||
while (token === 15 /* SyntaxKind.Trivia */ || token === 14 /* SyntaxKind.LineBreakTrivia */) { | ||
if (token === 14 /* SyntaxKind.LineBreakTrivia */ && options.keepLines) { | ||
numberLineBreaks += 1; | ||
} | ||
else if (token === 14 /* SyntaxKind.LineBreakTrivia */) { | ||
numberLineBreaks = 1; | ||
} | ||
token = scanner.scan(); | ||
} | ||
hasError = token === 16 /* Unknown */ || scanner.getTokenError() !== 0 /* None */; | ||
hasError = token === 16 /* SyntaxKind.Unknown */ || scanner.getTokenError() !== 0 /* ScanError.None */; | ||
return token; | ||
@@ -79,3 +89,6 @@ } | ||
var firstToken = scanNext(); | ||
if (firstToken !== 17 /* EOF */) { | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
addEdit(repeat(eol, numberLineBreaks), 0, 0); | ||
} | ||
if (firstToken !== 17 /* SyntaxKind.EOF */) { | ||
var firstTokenStart = scanner.getTokenOffset() + formatTextStart; | ||
@@ -85,3 +98,3 @@ var initialIndent = repeat(indentValue, initialIndentLevel); | ||
} | ||
while (firstToken !== 17 /* EOF */) { | ||
while (firstToken !== 17 /* SyntaxKind.EOF */) { | ||
var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; | ||
@@ -91,81 +104,114 @@ var secondToken = scanNext(); | ||
var needsLineBreak = false; | ||
while (!lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) { | ||
// comments on the same line: keep them on the same line, but ignore them otherwise | ||
while (numberLineBreaks === 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) { | ||
var commentTokenStart = scanner.getTokenOffset() + formatTextStart; | ||
addEdit(' ', firstTokenEnd, commentTokenStart); | ||
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; | ||
needsLineBreak = secondToken === 12 /* LineCommentTrivia */; | ||
replaceContent = needsLineBreak ? newLineAndIndent() : ''; | ||
needsLineBreak = secondToken === 12 /* SyntaxKind.LineCommentTrivia */; | ||
replaceContent = needsLineBreak ? newLinesAndIndent() : ''; | ||
secondToken = scanNext(); | ||
} | ||
if (secondToken === 2 /* CloseBraceToken */) { | ||
if (firstToken !== 1 /* OpenBraceToken */) { | ||
if (secondToken === 2 /* SyntaxKind.CloseBraceToken */) { | ||
if (firstToken !== 1 /* SyntaxKind.OpenBraceToken */) { | ||
indentLevel--; | ||
replaceContent = newLineAndIndent(); | ||
} | ||
; | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 1 /* SyntaxKind.OpenBraceToken */) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (options.keepLines) { | ||
replaceContent = ' '; | ||
} | ||
} | ||
else if (secondToken === 4 /* CloseBracketToken */) { | ||
if (firstToken !== 3 /* OpenBracketToken */) { | ||
else if (secondToken === 4 /* SyntaxKind.CloseBracketToken */) { | ||
if (firstToken !== 3 /* SyntaxKind.OpenBracketToken */) { | ||
indentLevel--; | ||
replaceContent = newLineAndIndent(); | ||
} | ||
; | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines && firstToken !== 3 /* SyntaxKind.OpenBracketToken */) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (options.keepLines) { | ||
replaceContent = ' '; | ||
} | ||
} | ||
else { | ||
switch (firstToken) { | ||
case 3 /* OpenBracketToken */: | ||
case 1 /* OpenBraceToken */: | ||
case 3 /* SyntaxKind.OpenBracketToken */: | ||
case 1 /* SyntaxKind.OpenBraceToken */: | ||
indentLevel++; | ||
replaceContent = newLineAndIndent(); | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 5 /* CommaToken */: | ||
case 12 /* LineCommentTrivia */: | ||
replaceContent = newLineAndIndent(); | ||
case 5 /* SyntaxKind.CommaToken */: | ||
if (options.keepLines && numberLineBreaks > 0 || !options.keepLines) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 13 /* BlockCommentTrivia */: | ||
if (lineBreak) { | ||
replaceContent = newLineAndIndent(); | ||
case 12 /* SyntaxKind.LineCommentTrivia */: | ||
replaceContent = newLinesAndIndent(); | ||
break; | ||
case 13 /* SyntaxKind.BlockCommentTrivia */: | ||
if (numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (!needsLineBreak) { | ||
// symbol following comment on the same line: keep on same line, separate with ' ' | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 6 /* ColonToken */: | ||
if (!needsLineBreak) { | ||
case 6 /* SyntaxKind.ColonToken */: | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else if (!needsLineBreak) { | ||
replaceContent = ' '; | ||
} | ||
break; | ||
case 10 /* StringLiteral */: | ||
if (secondToken === 6 /* ColonToken */) { | ||
if (!needsLineBreak) { | ||
replaceContent = ''; | ||
} | ||
break; | ||
case 10 /* SyntaxKind.StringLiteral */: | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
// fall through | ||
case 7 /* NullKeyword */: | ||
case 8 /* TrueKeyword */: | ||
case 9 /* FalseKeyword */: | ||
case 11 /* NumericLiteral */: | ||
case 2 /* CloseBraceToken */: | ||
case 4 /* CloseBracketToken */: | ||
if (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */) { | ||
if (!needsLineBreak) { | ||
else if (secondToken === 6 /* SyntaxKind.ColonToken */ && !needsLineBreak) { | ||
replaceContent = ''; | ||
} | ||
break; | ||
case 7 /* SyntaxKind.NullKeyword */: | ||
case 8 /* SyntaxKind.TrueKeyword */: | ||
case 9 /* SyntaxKind.FalseKeyword */: | ||
case 11 /* SyntaxKind.NumericLiteral */: | ||
case 2 /* SyntaxKind.CloseBraceToken */: | ||
case 4 /* SyntaxKind.CloseBracketToken */: | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
if ((secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */) && !needsLineBreak) { | ||
replaceContent = ' '; | ||
} | ||
else if (secondToken !== 5 /* SyntaxKind.CommaToken */ && secondToken !== 17 /* SyntaxKind.EOF */) { | ||
hasError = true; | ||
} | ||
} | ||
else if (secondToken !== 5 /* CommaToken */ && secondToken !== 17 /* EOF */) { | ||
hasError = true; | ||
} | ||
break; | ||
case 16 /* Unknown */: | ||
case 16 /* SyntaxKind.Unknown */: | ||
hasError = true; | ||
break; | ||
} | ||
if (lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) { | ||
replaceContent = newLineAndIndent(); | ||
if (numberLineBreaks > 0 && (secondToken === 12 /* SyntaxKind.LineCommentTrivia */ || secondToken === 13 /* SyntaxKind.BlockCommentTrivia */)) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
} | ||
if (secondToken === 17 /* EOF */) { | ||
replaceContent = options.insertFinalNewline ? eol : ''; | ||
if (secondToken === 17 /* SyntaxKind.EOF */) { | ||
if (options.keepLines && numberLineBreaks > 0) { | ||
replaceContent = newLinesAndIndent(); | ||
} | ||
else { | ||
replaceContent = options.insertFinalNewline ? eol : ''; | ||
} | ||
} | ||
@@ -172,0 +218,0 @@ var secondTokenStart = scanner.getTokenOffset() + formatTextStart; |
@@ -277,3 +277,3 @@ (function (factory) { | ||
var propertyNode = _b[_a]; | ||
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment) { | ||
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) { | ||
node = propertyNode.children[1]; | ||
@@ -377,10 +377,19 @@ found = true; | ||
if (options === void 0) { options = ParseOptions.DEFAULT; } | ||
var _scanner = scanner_1.createScanner(text, false); | ||
var _scanner = (0, scanner_1.createScanner)(text, false); | ||
// Important: Only pass copies of this to visitor functions to prevent accidental modification, and | ||
// to not affect visitor functions which stored a reference to a previous JSONPath | ||
var _jsonPath = []; | ||
function toNoArgVisit(visitFunction) { | ||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : function () { return true; }; | ||
} | ||
function toNoArgVisitWithPath(visitFunction) { | ||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), function () { return _jsonPath.slice(); }); } : function () { return true; }; | ||
} | ||
function toOneArgVisit(visitFunction) { | ||
return visitFunction ? function (arg) { return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : 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), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError); | ||
function toOneArgVisitWithPath(visitFunction) { | ||
return visitFunction ? function (arg) { return visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), function () { return _jsonPath.slice(); }); } : function () { return true; }; | ||
} | ||
var onObjectBegin = toNoArgVisitWithPath(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toNoArgVisit(visitor.onObjectEnd), onArrayBegin = toNoArgVisitWithPath(visitor.onArrayBegin), onArrayEnd = toNoArgVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError); | ||
var disallowComments = options && options.disallowComments; | ||
@@ -392,28 +401,28 @@ var allowTrailingComma = options && options.allowTrailingComma; | ||
switch (_scanner.getTokenError()) { | ||
case 4 /* InvalidUnicode */: | ||
handleError(14 /* InvalidUnicode */); | ||
case 4 /* ScanError.InvalidUnicode */: | ||
handleError(14 /* ParseErrorCode.InvalidUnicode */); | ||
break; | ||
case 5 /* InvalidEscapeCharacter */: | ||
handleError(15 /* InvalidEscapeCharacter */); | ||
case 5 /* ScanError.InvalidEscapeCharacter */: | ||
handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */); | ||
break; | ||
case 3 /* UnexpectedEndOfNumber */: | ||
handleError(13 /* UnexpectedEndOfNumber */); | ||
case 3 /* ScanError.UnexpectedEndOfNumber */: | ||
handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */); | ||
break; | ||
case 1 /* UnexpectedEndOfComment */: | ||
case 1 /* ScanError.UnexpectedEndOfComment */: | ||
if (!disallowComments) { | ||
handleError(11 /* UnexpectedEndOfComment */); | ||
handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */); | ||
} | ||
break; | ||
case 2 /* UnexpectedEndOfString */: | ||
handleError(12 /* UnexpectedEndOfString */); | ||
case 2 /* ScanError.UnexpectedEndOfString */: | ||
handleError(12 /* ParseErrorCode.UnexpectedEndOfString */); | ||
break; | ||
case 6 /* InvalidCharacter */: | ||
handleError(16 /* InvalidCharacter */); | ||
case 6 /* ScanError.InvalidCharacter */: | ||
handleError(16 /* ParseErrorCode.InvalidCharacter */); | ||
break; | ||
} | ||
switch (token) { | ||
case 12 /* LineCommentTrivia */: | ||
case 13 /* BlockCommentTrivia */: | ||
case 12 /* SyntaxKind.LineCommentTrivia */: | ||
case 13 /* SyntaxKind.BlockCommentTrivia */: | ||
if (disallowComments) { | ||
handleError(10 /* InvalidCommentToken */); | ||
handleError(10 /* ParseErrorCode.InvalidCommentToken */); | ||
} | ||
@@ -424,7 +433,7 @@ else { | ||
break; | ||
case 16 /* Unknown */: | ||
handleError(1 /* InvalidSymbol */); | ||
case 16 /* SyntaxKind.Unknown */: | ||
handleError(1 /* ParseErrorCode.InvalidSymbol */); | ||
break; | ||
case 15 /* Trivia */: | ||
case 14 /* LineBreakTrivia */: | ||
case 15 /* SyntaxKind.Trivia */: | ||
case 14 /* SyntaxKind.LineBreakTrivia */: | ||
break; | ||
@@ -442,3 +451,3 @@ default: | ||
var token = _scanner.getToken(); | ||
while (token !== 17 /* EOF */) { | ||
while (token !== 17 /* SyntaxKind.EOF */) { | ||
if (skipUntilAfter.indexOf(token) !== -1) { | ||
@@ -462,2 +471,4 @@ scanNext(); | ||
onObjectProperty(value); | ||
// add property name afterwards | ||
_jsonPath.push(value); | ||
} | ||
@@ -469,7 +480,7 @@ scanNext(); | ||
switch (_scanner.getToken()) { | ||
case 11 /* NumericLiteral */: | ||
case 11 /* SyntaxKind.NumericLiteral */: | ||
var tokenValue = _scanner.getTokenValue(); | ||
var value = Number(tokenValue); | ||
if (isNaN(value)) { | ||
handleError(2 /* InvalidNumberFormat */); | ||
handleError(2 /* ParseErrorCode.InvalidNumberFormat */); | ||
value = 0; | ||
@@ -479,9 +490,9 @@ } | ||
break; | ||
case 7 /* NullKeyword */: | ||
case 7 /* SyntaxKind.NullKeyword */: | ||
onLiteralValue(null); | ||
break; | ||
case 8 /* TrueKeyword */: | ||
case 8 /* SyntaxKind.TrueKeyword */: | ||
onLiteralValue(true); | ||
break; | ||
case 9 /* FalseKeyword */: | ||
case 9 /* SyntaxKind.FalseKeyword */: | ||
onLiteralValue(false); | ||
@@ -496,17 +507,18 @@ break; | ||
function parseProperty() { | ||
if (_scanner.getToken() !== 10 /* StringLiteral */) { | ||
handleError(3 /* PropertyNameExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) { | ||
handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
return false; | ||
} | ||
parseString(false); | ||
if (_scanner.getToken() === 6 /* ColonToken */) { | ||
if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) { | ||
onSeparator(':'); | ||
scanNext(); // consume colon | ||
if (!parseValue()) { | ||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
} | ||
else { | ||
handleError(5 /* ColonExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
_jsonPath.pop(); // remove processed property name | ||
return true; | ||
@@ -518,10 +530,10 @@ } | ||
var needsComma = false; | ||
while (_scanner.getToken() !== 2 /* CloseBraceToken */ && _scanner.getToken() !== 17 /* EOF */) { | ||
if (_scanner.getToken() === 5 /* CommaToken */) { | ||
while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) { | ||
if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) { | ||
if (!needsComma) { | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
} | ||
onSeparator(','); | ||
scanNext(); // consume comma | ||
if (_scanner.getToken() === 2 /* CloseBraceToken */ && allowTrailingComma) { | ||
if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) { | ||
break; | ||
@@ -531,6 +543,6 @@ } | ||
else if (needsComma) { | ||
handleError(6 /* CommaExpected */, [], []); | ||
handleError(6 /* ParseErrorCode.CommaExpected */, [], []); | ||
} | ||
if (!parseProperty()) { | ||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
@@ -540,4 +552,4 @@ needsComma = true; | ||
onObjectEnd(); | ||
if (_scanner.getToken() !== 2 /* CloseBraceToken */) { | ||
handleError(7 /* CloseBraceExpected */, [2 /* CloseBraceToken */], []); | ||
if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) { | ||
handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []); | ||
} | ||
@@ -552,11 +564,12 @@ else { | ||
scanNext(); // consume open bracket | ||
var isFirstElement = true; | ||
var needsComma = false; | ||
while (_scanner.getToken() !== 4 /* CloseBracketToken */ && _scanner.getToken() !== 17 /* EOF */) { | ||
if (_scanner.getToken() === 5 /* CommaToken */) { | ||
while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) { | ||
if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) { | ||
if (!needsComma) { | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
} | ||
onSeparator(','); | ||
scanNext(); // consume comma | ||
if (_scanner.getToken() === 4 /* CloseBracketToken */ && allowTrailingComma) { | ||
if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) { | ||
break; | ||
@@ -566,6 +579,13 @@ } | ||
else if (needsComma) { | ||
handleError(6 /* CommaExpected */, [], []); | ||
handleError(6 /* ParseErrorCode.CommaExpected */, [], []); | ||
} | ||
if (isFirstElement) { | ||
_jsonPath.push(0); | ||
isFirstElement = false; | ||
} | ||
else { | ||
_jsonPath[_jsonPath.length - 1]++; | ||
} | ||
if (!parseValue()) { | ||
handleError(4 /* ValueExpected */, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]); | ||
} | ||
@@ -575,5 +595,8 @@ needsComma = true; | ||
onArrayEnd(); | ||
if (_scanner.getToken() !== 4 /* CloseBracketToken */) { | ||
handleError(8 /* CloseBracketExpected */, [4 /* CloseBracketToken */], []); | ||
if (!isFirstElement) { | ||
_jsonPath.pop(); // remove array index | ||
} | ||
if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) { | ||
handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []); | ||
} | ||
else { | ||
@@ -586,7 +609,7 @@ scanNext(); // consume close bracket | ||
switch (_scanner.getToken()) { | ||
case 3 /* OpenBracketToken */: | ||
case 3 /* SyntaxKind.OpenBracketToken */: | ||
return parseArray(); | ||
case 1 /* OpenBraceToken */: | ||
case 1 /* SyntaxKind.OpenBraceToken */: | ||
return parseObject(); | ||
case 10 /* StringLiteral */: | ||
case 10 /* SyntaxKind.StringLiteral */: | ||
return parseString(true); | ||
@@ -598,15 +621,15 @@ default: | ||
scanNext(); | ||
if (_scanner.getToken() === 17 /* EOF */) { | ||
if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) { | ||
if (options.allowEmptyContent) { | ||
return true; | ||
} | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
return false; | ||
} | ||
if (!parseValue()) { | ||
handleError(4 /* ValueExpected */, [], []); | ||
handleError(4 /* ParseErrorCode.ValueExpected */, [], []); | ||
return false; | ||
} | ||
if (_scanner.getToken() !== 17 /* EOF */) { | ||
handleError(9 /* EndOfFileExpected */, [], []); | ||
if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) { | ||
handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []); | ||
} | ||
@@ -622,3 +645,3 @@ return true; | ||
function stripComments(text, replaceCh) { | ||
var _scanner = scanner_1.createScanner(text), parts = [], kind, offset = 0, pos; | ||
var _scanner = (0, scanner_1.createScanner)(text), parts = [], kind, offset = 0, pos; | ||
do { | ||
@@ -628,5 +651,5 @@ pos = _scanner.getPosition(); | ||
switch (kind) { | ||
case 12 /* LineCommentTrivia */: | ||
case 13 /* BlockCommentTrivia */: | ||
case 17 /* EOF */: | ||
case 12 /* SyntaxKind.LineCommentTrivia */: | ||
case 13 /* SyntaxKind.BlockCommentTrivia */: | ||
case 17 /* SyntaxKind.EOF */: | ||
if (offset !== pos) { | ||
@@ -641,3 +664,3 @@ parts.push(text.substring(offset, pos)); | ||
} | ||
} while (kind !== 17 /* EOF */); | ||
} while (kind !== 17 /* SyntaxKind.EOF */); | ||
return parts.join(''); | ||
@@ -644,0 +667,0 @@ } |
@@ -24,3 +24,3 @@ (function (factory) { | ||
var len = text.length; | ||
var pos = 0, value = '', tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */; | ||
var 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) { | ||
@@ -31,10 +31,10 @@ var digits = 0; | ||
var ch = text.charCodeAt(pos); | ||
if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) { | ||
value = value * 16 + ch - 48 /* _0 */; | ||
if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) { | ||
value = value * 16 + ch - 48 /* CharacterCodes._0 */; | ||
} | ||
else if (ch >= 65 /* A */ && ch <= 70 /* F */) { | ||
value = value * 16 + ch - 65 /* A */ + 10; | ||
else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) { | ||
value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10; | ||
} | ||
else if (ch >= 97 /* a */ && ch <= 102 /* f */) { | ||
value = value * 16 + ch - 97 /* a */ + 10; | ||
else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) { | ||
value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10; | ||
} | ||
@@ -56,8 +56,8 @@ else { | ||
tokenOffset = 0; | ||
token = 16 /* Unknown */; | ||
scanError = 0 /* None */; | ||
token = 16 /* SyntaxKind.Unknown */; | ||
scanError = 0 /* ScanError.None */; | ||
} | ||
function scanNumber() { | ||
var start = pos; | ||
if (text.charCodeAt(pos) === 48 /* _0 */) { | ||
if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) { | ||
pos++; | ||
@@ -71,3 +71,3 @@ } | ||
} | ||
if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) { | ||
if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) { | ||
pos++; | ||
@@ -81,3 +81,3 @@ if (pos < text.length && isDigit(text.charCodeAt(pos))) { | ||
else { | ||
scanError = 3 /* UnexpectedEndOfNumber */; | ||
scanError = 3 /* ScanError.UnexpectedEndOfNumber */; | ||
return text.substring(start, pos); | ||
@@ -87,5 +87,5 @@ } | ||
var end = pos; | ||
if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) { | ||
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 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) { | ||
if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) { | ||
pos++; | ||
@@ -101,3 +101,3 @@ } | ||
else { | ||
scanError = 3 /* UnexpectedEndOfNumber */; | ||
scanError = 3 /* ScanError.UnexpectedEndOfNumber */; | ||
} | ||
@@ -112,7 +112,7 @@ } | ||
result += text.substring(start, pos); | ||
scanError = 2 /* UnexpectedEndOfString */; | ||
scanError = 2 /* ScanError.UnexpectedEndOfString */; | ||
break; | ||
} | ||
var ch = text.charCodeAt(pos); | ||
if (ch === 34 /* doubleQuote */) { | ||
if (ch === 34 /* CharacterCodes.doubleQuote */) { | ||
result += text.substring(start, pos); | ||
@@ -122,7 +122,7 @@ pos++; | ||
} | ||
if (ch === 92 /* backslash */) { | ||
if (ch === 92 /* CharacterCodes.backslash */) { | ||
result += text.substring(start, pos); | ||
pos++; | ||
if (pos >= len) { | ||
scanError = 2 /* UnexpectedEndOfString */; | ||
scanError = 2 /* ScanError.UnexpectedEndOfString */; | ||
break; | ||
@@ -132,27 +132,27 @@ } | ||
switch (ch2) { | ||
case 34 /* doubleQuote */: | ||
case 34 /* CharacterCodes.doubleQuote */: | ||
result += '\"'; | ||
break; | ||
case 92 /* backslash */: | ||
case 92 /* CharacterCodes.backslash */: | ||
result += '\\'; | ||
break; | ||
case 47 /* slash */: | ||
case 47 /* CharacterCodes.slash */: | ||
result += '/'; | ||
break; | ||
case 98 /* b */: | ||
case 98 /* CharacterCodes.b */: | ||
result += '\b'; | ||
break; | ||
case 102 /* f */: | ||
case 102 /* CharacterCodes.f */: | ||
result += '\f'; | ||
break; | ||
case 110 /* n */: | ||
case 110 /* CharacterCodes.n */: | ||
result += '\n'; | ||
break; | ||
case 114 /* r */: | ||
case 114 /* CharacterCodes.r */: | ||
result += '\r'; | ||
break; | ||
case 116 /* t */: | ||
case 116 /* CharacterCodes.t */: | ||
result += '\t'; | ||
break; | ||
case 117 /* u */: | ||
case 117 /* CharacterCodes.u */: | ||
var ch3 = scanHexDigits(4, true); | ||
@@ -163,7 +163,7 @@ if (ch3 >= 0) { | ||
else { | ||
scanError = 4 /* InvalidUnicode */; | ||
scanError = 4 /* ScanError.InvalidUnicode */; | ||
} | ||
break; | ||
default: | ||
scanError = 5 /* InvalidEscapeCharacter */; | ||
scanError = 5 /* ScanError.InvalidEscapeCharacter */; | ||
} | ||
@@ -176,7 +176,7 @@ start = pos; | ||
result += text.substring(start, pos); | ||
scanError = 2 /* UnexpectedEndOfString */; | ||
scanError = 2 /* ScanError.UnexpectedEndOfString */; | ||
break; | ||
} | ||
else { | ||
scanError = 6 /* InvalidCharacter */; | ||
scanError = 6 /* ScanError.InvalidCharacter */; | ||
// mark as error but continue with string | ||
@@ -191,3 +191,3 @@ } | ||
value = ''; | ||
scanError = 0 /* None */; | ||
scanError = 0 /* ScanError.None */; | ||
tokenOffset = pos; | ||
@@ -199,3 +199,3 @@ lineStartOffset = lineNumber; | ||
tokenOffset = len; | ||
return token = 17 /* EOF */; | ||
return token = 17 /* SyntaxKind.EOF */; | ||
} | ||
@@ -210,3 +210,3 @@ var code = text.charCodeAt(pos); | ||
} while (isWhiteSpace(code)); | ||
return token = 15 /* Trivia */; | ||
return token = 15 /* SyntaxKind.Trivia */; | ||
} | ||
@@ -217,3 +217,3 @@ // trivia: newlines | ||
value += String.fromCharCode(code); | ||
if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) { | ||
if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) { | ||
pos++; | ||
@@ -224,34 +224,34 @@ value += '\n'; | ||
tokenLineStartOffset = pos; | ||
return token = 14 /* LineBreakTrivia */; | ||
return token = 14 /* SyntaxKind.LineBreakTrivia */; | ||
} | ||
switch (code) { | ||
// tokens: []{}:, | ||
case 123 /* openBrace */: | ||
case 123 /* CharacterCodes.openBrace */: | ||
pos++; | ||
return token = 1 /* OpenBraceToken */; | ||
case 125 /* closeBrace */: | ||
return token = 1 /* SyntaxKind.OpenBraceToken */; | ||
case 125 /* CharacterCodes.closeBrace */: | ||
pos++; | ||
return token = 2 /* CloseBraceToken */; | ||
case 91 /* openBracket */: | ||
return token = 2 /* SyntaxKind.CloseBraceToken */; | ||
case 91 /* CharacterCodes.openBracket */: | ||
pos++; | ||
return token = 3 /* OpenBracketToken */; | ||
case 93 /* closeBracket */: | ||
return token = 3 /* SyntaxKind.OpenBracketToken */; | ||
case 93 /* CharacterCodes.closeBracket */: | ||
pos++; | ||
return token = 4 /* CloseBracketToken */; | ||
case 58 /* colon */: | ||
return token = 4 /* SyntaxKind.CloseBracketToken */; | ||
case 58 /* CharacterCodes.colon */: | ||
pos++; | ||
return token = 6 /* ColonToken */; | ||
case 44 /* comma */: | ||
return token = 6 /* SyntaxKind.ColonToken */; | ||
case 44 /* CharacterCodes.comma */: | ||
pos++; | ||
return token = 5 /* CommaToken */; | ||
return token = 5 /* SyntaxKind.CommaToken */; | ||
// strings | ||
case 34 /* doubleQuote */: | ||
case 34 /* CharacterCodes.doubleQuote */: | ||
pos++; | ||
value = scanString(); | ||
return token = 10 /* StringLiteral */; | ||
return token = 10 /* SyntaxKind.StringLiteral */; | ||
// comments | ||
case 47 /* slash */: | ||
case 47 /* CharacterCodes.slash */: | ||
var start = pos - 1; | ||
// Single-line comment | ||
if (text.charCodeAt(pos + 1) === 47 /* slash */) { | ||
if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) { | ||
pos += 2; | ||
@@ -265,6 +265,6 @@ while (pos < len) { | ||
value = text.substring(start, pos); | ||
return token = 12 /* LineCommentTrivia */; | ||
return token = 12 /* SyntaxKind.LineCommentTrivia */; | ||
} | ||
// Multi-line comment | ||
if (text.charCodeAt(pos + 1) === 42 /* asterisk */) { | ||
if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) { | ||
pos += 2; | ||
@@ -275,3 +275,3 @@ var safeLength = len - 1; // For lookahead. | ||
var ch = text.charCodeAt(pos); | ||
if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) { | ||
if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) { | ||
pos += 2; | ||
@@ -283,3 +283,3 @@ commentClosed = true; | ||
if (isLineBreak(ch)) { | ||
if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) { | ||
if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) { | ||
pos++; | ||
@@ -293,6 +293,6 @@ } | ||
pos++; | ||
scanError = 1 /* UnexpectedEndOfComment */; | ||
scanError = 1 /* ScanError.UnexpectedEndOfComment */; | ||
} | ||
value = text.substring(start, pos); | ||
return token = 13 /* BlockCommentTrivia */; | ||
return token = 13 /* SyntaxKind.BlockCommentTrivia */; | ||
} | ||
@@ -302,9 +302,9 @@ // just a single slash | ||
pos++; | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
// numbers | ||
case 45 /* minus */: | ||
case 45 /* CharacterCodes.minus */: | ||
value += String.fromCharCode(code); | ||
pos++; | ||
if (pos === len || !isDigit(text.charCodeAt(pos))) { | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
} | ||
@@ -314,14 +314,14 @@ // found a minus, followed by a number so | ||
// numbers | ||
case 48 /* _0 */: | ||
case 49 /* _1 */: | ||
case 50 /* _2 */: | ||
case 51 /* _3 */: | ||
case 52 /* _4 */: | ||
case 53 /* _5 */: | ||
case 54 /* _6 */: | ||
case 55 /* _7 */: | ||
case 56 /* _8 */: | ||
case 57 /* _9 */: | ||
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 /* NumericLiteral */; | ||
return token = 11 /* SyntaxKind.NumericLiteral */; | ||
// literals and unknown symbols | ||
@@ -338,7 +338,7 @@ default: | ||
switch (value) { | ||
case 'true': return token = 8 /* TrueKeyword */; | ||
case 'false': return token = 9 /* FalseKeyword */; | ||
case 'null': return token = 7 /* NullKeyword */; | ||
case 'true': return token = 8 /* SyntaxKind.TrueKeyword */; | ||
case 'false': return token = 9 /* SyntaxKind.FalseKeyword */; | ||
case 'null': return token = 7 /* SyntaxKind.NullKeyword */; | ||
} | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
} | ||
@@ -348,3 +348,3 @@ // some | ||
pos++; | ||
return token = 16 /* Unknown */; | ||
return token = 16 /* SyntaxKind.Unknown */; | ||
} | ||
@@ -357,10 +357,10 @@ } | ||
switch (code) { | ||
case 125 /* closeBrace */: | ||
case 93 /* closeBracket */: | ||
case 123 /* openBrace */: | ||
case 91 /* openBracket */: | ||
case 34 /* doubleQuote */: | ||
case 58 /* colon */: | ||
case 44 /* comma */: | ||
case 47 /* slash */: | ||
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; | ||
@@ -374,3 +374,3 @@ } | ||
result = scanNext(); | ||
} while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */); | ||
} while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */); | ||
return result; | ||
@@ -393,12 +393,10 @@ } | ||
function isWhiteSpace(ch) { | ||
return ch === 32 /* space */ || ch === 9 /* tab */ || ch === 11 /* verticalTab */ || ch === 12 /* formFeed */ || | ||
ch === 160 /* nonBreakingSpace */ || ch === 5760 /* ogham */ || ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ || | ||
ch === 8239 /* narrowNoBreakSpace */ || ch === 8287 /* mathematicalSpace */ || ch === 12288 /* ideographicSpace */ || ch === 65279 /* byteOrderMark */; | ||
return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */; | ||
} | ||
function isLineBreak(ch) { | ||
return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */; | ||
return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */; | ||
} | ||
function isDigit(ch) { | ||
return ch >= 48 /* _0 */ && ch <= 57 /* _9 */; | ||
return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */; | ||
} | ||
}); |
@@ -47,3 +47,3 @@ /** | ||
/** | ||
* Returns the current scan position, which is after the last read token. | ||
* Returns the zero-based current scan position, which is after the last read token. | ||
*/ | ||
@@ -60,3 +60,3 @@ getPosition(): number; | ||
/** | ||
* The start offset of the last read token. | ||
* The zero-based start offset of the last read token. | ||
*/ | ||
@@ -154,2 +154,6 @@ getTokenOffset(): number; | ||
} | ||
/** | ||
* A {@linkcode JSONPath} segment. Either a string representing an object property name | ||
* or a number (starting at 0) for array indices. | ||
*/ | ||
export declare type Segment = string | number; | ||
@@ -183,2 +187,13 @@ export declare type JSONPath = Segment[]; | ||
} | ||
/** | ||
* Visitor called by {@linkcode visit} when parsing JSON. | ||
* | ||
* The visitor functions have the following common parameters: | ||
* - `offset`: Global offset within the JSON document, starting at 0 | ||
* - `startLine`: Line number, starting at 0 | ||
* - `startCharacter`: Start character (column) within the current line, starting at 0 | ||
* | ||
* Additionally some functions have a `pathSupplier` parameter which can be used to obtain the | ||
* current `JSONPath` within the document. | ||
*/ | ||
export interface JSONVisitor { | ||
@@ -188,7 +203,9 @@ /** | ||
*/ | ||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
* Invoked when a property is encountered. The offset and length represent the location of the property name. | ||
* The `JSONPath` created by the `pathSupplier` refers to the enclosing JSON object, it does not include the | ||
* property name yet. | ||
*/ | ||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -201,3 +218,3 @@ * Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace. | ||
*/ | ||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -210,3 +227,3 @@ * Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket. | ||
*/ | ||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -226,2 +243,13 @@ * Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator. | ||
/** | ||
* An edit result describes a textual edit operation. It is the result of a {@linkcode format} and {@linkcode modify} operation. | ||
* It consist of one or more edits describing insertions, replacements or removals of text segments. | ||
* * The offsets of the edits refer to the original state of the document. | ||
* * No two edits change or remove the same range of text in the original document. | ||
* * Multiple edits can have the same offset if they are multiple inserts, or an insert followed by a remove or replace. | ||
* * The order in the array defines which edit is applied first. | ||
* To apply an edit result use {@linkcode applyEdits}. | ||
* In general multiple EditResults must not be concatenated because they might impact each other, producing incorrect or malformed JSON data. | ||
*/ | ||
export declare type EditResult = Edit[]; | ||
/** | ||
* Represents a text modification | ||
@@ -256,2 +284,5 @@ */ | ||
} | ||
/** | ||
* Options used by {@linkcode format} when computing the formatting edit operations | ||
*/ | ||
export interface FormattingOptions { | ||
@@ -274,5 +305,9 @@ /** | ||
insertFinalNewline?: boolean; | ||
/** | ||
* If true, will keep line positions as is in the formatting | ||
*/ | ||
keepLines?: boolean; | ||
} | ||
/** | ||
* Computes the edits needed to format a JSON document. | ||
* Computes the edit operations needed to format a JSON document. | ||
* | ||
@@ -282,11 +317,8 @@ * @param documentText The input text | ||
* @param options The formatting options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
export declare function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[]; | ||
export declare function format(documentText: string, range: Range | undefined, options: FormattingOptions): EditResult; | ||
/** | ||
* Options used when computing the modification edits | ||
* Options used by {@linkcode modify} when computing the modification edit operations | ||
*/ | ||
@@ -299,4 +331,4 @@ export interface ModificationOptions { | ||
/** | ||
* Default false. If `JSONPath` refers to an index of an array and {@property isArrayInsertion} is `true`, then | ||
* {@function modify} will insert a new item at that location instead of overwriting its contents. | ||
* Default false. If `JSONPath` refers to an index of an array and `isArrayInsertion` is `true`, then | ||
* {@linkcode modify} will insert a new item at that location instead of overwriting its contents. | ||
*/ | ||
@@ -310,3 +342,3 @@ isArrayInsertion?: boolean; | ||
/** | ||
* Computes the edits needed to modify a value in the JSON document. | ||
* Computes the edit operations needed to modify a value in the JSON document. | ||
* | ||
@@ -319,12 +351,13 @@ * @param documentText The input text | ||
* @param options Options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
export declare function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): Edit[]; | ||
export declare function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): EditResult; | ||
/** | ||
* Applies edits to a input string. | ||
* Applies edits to an input string. | ||
* @param text The input text | ||
* @param edits Edit operations following the format described in {@linkcode EditResult}. | ||
* @returns The text with the applied edits. | ||
* @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}. | ||
*/ | ||
export declare function applyEdits(text: string, edits: Edit[]): string; | ||
export declare function applyEdits(text: string, edits: EditResult): string; |
@@ -67,18 +67,18 @@ (function (factory) { | ||
switch (code) { | ||
case 1 /* InvalidSymbol */: return 'InvalidSymbol'; | ||
case 2 /* InvalidNumberFormat */: return 'InvalidNumberFormat'; | ||
case 3 /* PropertyNameExpected */: return 'PropertyNameExpected'; | ||
case 4 /* ValueExpected */: return 'ValueExpected'; | ||
case 5 /* ColonExpected */: return 'ColonExpected'; | ||
case 6 /* CommaExpected */: return 'CommaExpected'; | ||
case 7 /* CloseBraceExpected */: return 'CloseBraceExpected'; | ||
case 8 /* CloseBracketExpected */: return 'CloseBracketExpected'; | ||
case 9 /* EndOfFileExpected */: return 'EndOfFileExpected'; | ||
case 10 /* InvalidCommentToken */: return 'InvalidCommentToken'; | ||
case 11 /* UnexpectedEndOfComment */: return 'UnexpectedEndOfComment'; | ||
case 12 /* UnexpectedEndOfString */: return 'UnexpectedEndOfString'; | ||
case 13 /* UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber'; | ||
case 14 /* InvalidUnicode */: return 'InvalidUnicode'; | ||
case 15 /* InvalidEscapeCharacter */: return 'InvalidEscapeCharacter'; | ||
case 16 /* InvalidCharacter */: return 'InvalidCharacter'; | ||
case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol'; | ||
case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat'; | ||
case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected'; | ||
case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected'; | ||
case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected'; | ||
case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected'; | ||
case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected'; | ||
case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected'; | ||
case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected'; | ||
case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken'; | ||
case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment'; | ||
case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString'; | ||
case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber'; | ||
case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode'; | ||
case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter'; | ||
case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter'; | ||
} | ||
@@ -89,3 +89,3 @@ return '<unknown ParseErrorCode>'; | ||
/** | ||
* Computes the edits needed to format a JSON document. | ||
* Computes the edit operations needed to format a JSON document. | ||
* | ||
@@ -95,7 +95,4 @@ * @param documentText The input text | ||
* @param options The formatting options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
@@ -107,3 +104,3 @@ function format(documentText, range, options) { | ||
/** | ||
* Computes the edits needed to modify a value in the JSON document. | ||
* Computes the edit operations needed to modify a value in the JSON document. | ||
* | ||
@@ -116,7 +113,4 @@ * @param documentText The input text | ||
* @param options Options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits`. | ||
* @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
@@ -128,3 +122,7 @@ function modify(text, path, value, options) { | ||
/** | ||
* Applies edits to a input string. | ||
* Applies edits to an input string. | ||
* @param text The input text | ||
* @param edits Edit operations following the format described in {@linkcode EditResult}. | ||
* @returns The text with the applied edits. | ||
* @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}. | ||
*/ | ||
@@ -131,0 +129,0 @@ function applyEdits(text, edits) { |
{ | ||
"name": "jsonc-parser", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"description": "Scanner and parser for JSON with comments.", | ||
"main": "./lib/umd/main.js", | ||
"typings": "./lib/umd/main", | ||
"typings": "./lib/umd/main.d.ts", | ||
"module": "./lib/esm/main.js", | ||
@@ -18,9 +18,9 @@ "author": "Microsoft Corporation", | ||
"devDependencies": { | ||
"mocha": "^8.2.1", | ||
"typescript": "^4.0.5", | ||
"@types/node": "^10.12.12", | ||
"@types/mocha": "^5.2.7", | ||
"@typescript-eslint/eslint-plugin": "^4.7.0", | ||
"@typescript-eslint/parser": "^4.7.0", | ||
"eslint": "^7.13.0", | ||
"mocha": "^10.0.0", | ||
"typescript": "^4.7.4", | ||
"@types/node": "^16.x", | ||
"@types/mocha": "^9.1.1", | ||
"@typescript-eslint/eslint-plugin": "^5.30.5", | ||
"@typescript-eslint/parser": "^5.30.5", | ||
"eslint": "^8.19.0", | ||
"rimraf": "^3.0.2" | ||
@@ -27,0 +27,0 @@ }, |
182
README.md
@@ -6,3 +6,3 @@ # jsonc-parser | ||
[![NPM Downloads](https://img.shields.io/npm/dm/jsonc-parser.svg)](https://npmjs.org/package/jsonc-parser) | ||
[![Build Status](https://travis-ci.org/Microsoft/node-jsonc-parser.svg?branch=master)](https://travis-ci.org/Microsoft/node-jsonc-parser) | ||
[![Build Status](https://travis-ci.org/microsoft/node-jsonc-parser.svg?branch=main)](https://travis-ci.org/Microsoft/node-jsonc-parser) | ||
@@ -25,5 +25,6 @@ Why? | ||
npm install --save jsonc-parser | ||
``` | ||
npm install --save jsonc-parser | ||
``` | ||
API | ||
@@ -39,3 +40,3 @@ --- | ||
*/ | ||
export function createScanner(text:string, ignoreTrivia:boolean = false):JSONScanner; | ||
export function createScanner(text: string, ignoreTrivia: boolean = false): JSONScanner; | ||
@@ -55,3 +56,3 @@ /** | ||
/** | ||
* Returns the current scan position, which is after the last read token. | ||
* Returns the zero-based current scan position, which is after the last read token. | ||
*/ | ||
@@ -64,7 +65,7 @@ getPosition(): number; | ||
/** | ||
* Returns the last read token value. The value for strings is the decoded string content. For numbers its of type number, for boolean it's true or false. | ||
* Returns the last read token value. The value for strings is the decoded string content. For numbers it's of type number, for boolean it's true or false. | ||
*/ | ||
getTokenValue(): string; | ||
/** | ||
* The start offset of the last read token. | ||
* The zero-based start offset of the last read token. | ||
*/ | ||
@@ -96,2 +97,4 @@ getTokenOffset(): number; | ||
disallowComments?: boolean; | ||
allowTrailingComma?: boolean; | ||
allowEmptyContent?: boolean; | ||
} | ||
@@ -109,2 +112,13 @@ /** | ||
/** | ||
* Visitor called by {@linkcode visit} when parsing JSON. | ||
* | ||
* The visitor functions have the following common parameters: | ||
* - `offset`: Global offset within the JSON document, starting at 0 | ||
* - `startLine`: Line number, starting at 0 | ||
* - `startCharacter`: Start character (column) within the current line, starting at 0 | ||
* | ||
* Additionally some functions have a `pathSupplier` parameter which can be used to obtain the | ||
* current `JSONPath` within the document. | ||
*/ | ||
export interface JSONVisitor { | ||
@@ -114,7 +128,10 @@ /** | ||
*/ | ||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
* Invoked when a property is encountered. The offset and length represent the location of the property name. | ||
* The `JSONPath` created by the `pathSupplier` refers to the enclosing JSON object, it does not include the | ||
* property name yet. | ||
*/ | ||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -127,3 +144,3 @@ * Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace. | ||
*/ | ||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -136,3 +153,3 @@ * Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket. | ||
*/ | ||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number) => void; | ||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number, pathSupplier: () => JSONPath) => void; | ||
/** | ||
@@ -184,3 +201,8 @@ * Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator. | ||
/** | ||
* A {@linkcode JSONPath} segment. Either a string representing an object property name | ||
* or a number (starting at 0) for array indices. | ||
*/ | ||
export declare type Segment = string | number; | ||
export declare type JSONPath = Segment[]; | ||
export interface Location { | ||
@@ -195,9 +217,9 @@ /** | ||
*/ | ||
path: Segment[]; | ||
path: JSONPath; | ||
/** | ||
* Matches the locations path against a pattern consisting of strings (for properties) and numbers (for array indices). | ||
* '*' will match a single segment, of any property name or index. | ||
* '**' will match a sequece of segments or no segment, of any property name or index. | ||
* '**' will match a sequence of segments or no segment, of any property name or index. | ||
*/ | ||
matches: (patterns: Segment[]) => boolean; | ||
matches: (patterns: JSONPath) => boolean; | ||
/** | ||
@@ -222,3 +244,3 @@ * If set, the location's offset is at a property key. | ||
*/ | ||
export function getNodePath(node: Node) : JSONPath; | ||
export function getNodePath(node: Node): JSONPath; | ||
@@ -231,3 +253,3 @@ /** | ||
/** | ||
* Computes the edits needed to format a JSON document. | ||
* Computes the edit operations needed to format a JSON document. | ||
* | ||
@@ -237,13 +259,9 @@ * @param documentText The input text | ||
* @param options The formatting options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits` | ||
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
export function format(documentText: string, range: Range, options: FormattingOptions): Edit[]; | ||
export function format(documentText: string, range: Range, options: FormattingOptions): EditResult; | ||
/** | ||
* Computes the edits needed to modify a value in the JSON document. | ||
* Computes the edit operations needed to modify a value in the JSON document. | ||
* | ||
@@ -256,31 +274,44 @@ * @param documentText The input text | ||
* @param options Options | ||
* @returns A list of edit operations describing the formatting changes to the original document. Edits can be either inserts, replacements or | ||
* removals of text segments. All offsets refer to the original state of the document. No two edits must change or remove the same range of | ||
* text in the original document. However, multiple edits can have | ||
* the same offset, for example multiple inserts, or an insert followed by a remove or replace. The order in the array defines which edit is applied first. | ||
* To apply edits to an input, you can use `applyEdits` | ||
* @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}. | ||
* To apply the edit operations to the input, use {@linkcode applyEdits}. | ||
*/ | ||
export function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): Edit[]; | ||
export function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): EditResult; | ||
/** | ||
* Applies edits to a input string. | ||
* Applies edits to an input string. | ||
* @param text The input text | ||
* @param edits Edit operations following the format described in {@linkcode EditResult}. | ||
* @returns The text with the applied edits. | ||
* @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}. | ||
*/ | ||
export function applyEdits(text: string, edits: Edit[]): string; | ||
export function applyEdits(text: string, edits: EditResult): string; | ||
/** | ||
* An edit result describes a textual edit operation. It is the result of a {@linkcode format} and {@linkcode modify} operation. | ||
* It consist of one or more edits describing insertions, replacements or removals of text segments. | ||
* * The offsets of the edits refer to the original state of the document. | ||
* * No two edits change or remove the same range of text in the original document. | ||
* * Multiple edits can have the same offset if they are multiple inserts, or an insert followed by a remove or replace. | ||
* * The order in the array defines which edit is applied first. | ||
* To apply an edit result use {@linkcode applyEdits}. | ||
* In general multiple EditResults must not be concatenated because they might impact each other, producing incorrect or malformed JSON data. | ||
*/ | ||
export type EditResult = Edit[]; | ||
/** | ||
* Represents a text modification | ||
*/ | ||
export interface Edit { | ||
/** | ||
* The start offset of the modification. | ||
*/ | ||
offset: number; | ||
/** | ||
* The length of the modification. Must not be negative. Empty length represents an *insert*. | ||
*/ | ||
length: number; | ||
/** | ||
* The new content. Empty content represents a *remove*. | ||
*/ | ||
content: string; | ||
/** | ||
* The start offset of the modification. | ||
*/ | ||
offset: number; | ||
/** | ||
* The length of the modification. Must not be negative. Empty length represents an *insert*. | ||
*/ | ||
length: number; | ||
/** | ||
* The new content. Empty content represents a *remove*. | ||
*/ | ||
content: string; | ||
} | ||
@@ -292,27 +323,48 @@ | ||
export interface Range { | ||
/** | ||
* The start offset of the range. | ||
*/ | ||
offset: number; | ||
/** | ||
* The length of the range. Must not be negative. | ||
*/ | ||
length: number; | ||
/** | ||
* The start offset of the range. | ||
*/ | ||
offset: number; | ||
/** | ||
* The length of the range. Must not be negative. | ||
*/ | ||
length: number; | ||
} | ||
/** | ||
* Options used by {@linkcode format} when computing the formatting edit operations | ||
*/ | ||
export interface FormattingOptions { | ||
/** | ||
* If indentation is based on spaces (`insertSpaces` = true), then what is the number of spaces that make an indent? | ||
*/ | ||
tabSize: number; | ||
/** | ||
* Is indentation based on spaces? | ||
*/ | ||
insertSpaces: boolean; | ||
/** | ||
* The default 'end of line' character | ||
*/ | ||
eol: string; | ||
/** | ||
* If indentation is based on spaces (`insertSpaces` = true), then what is the number of spaces that make an indent? | ||
*/ | ||
tabSize: number; | ||
/** | ||
* Is indentation based on spaces? | ||
*/ | ||
insertSpaces: boolean; | ||
/** | ||
* The default 'end of line' character | ||
*/ | ||
eol: string; | ||
} | ||
/** | ||
* Options used by {@linkcode modify} when computing the modification edit operations | ||
*/ | ||
export interface ModificationOptions { | ||
/** | ||
* Formatting options. If undefined, the newly inserted code will be inserted unformatted. | ||
*/ | ||
formattingOptions?: FormattingOptions; | ||
/** | ||
* Default false. If `JSONPath` refers to an index of an array and `isArrayInsertion` is `true`, then | ||
* {@linkcode modify} will insert a new item at that location instead of overwriting its contents. | ||
*/ | ||
isArrayInsertion?: boolean; | ||
/** | ||
* Optional function to define the insertion index given an existing list of properties. | ||
*/ | ||
getInsertionIndex?: (properties: string[]) => number; | ||
} | ||
``` | ||
@@ -319,0 +371,0 @@ |
191441
17
3919
362