Conexio amb la api
This commit is contained in:
parent
207c0ba819
commit
b12369cb47
48513 changed files with 7391639 additions and 7 deletions
62
node_modules/jsonc-parser/CHANGELOG.md
generated
vendored
Executable file
62
node_modules/jsonc-parser/CHANGELOG.md
generated
vendored
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
3.0.0 2020-11-13
|
||||
==================
|
||||
* fixed API spec for `parseTree`. Can return `undefine` for empty input.
|
||||
* added new API `FormattingOptions.insertFinalNewline`.
|
||||
|
||||
|
||||
2.3.0 2020-07-03
|
||||
==================
|
||||
* new API `ModificationOptions.isArrayInsertion`: If `JSONPath` refers to an index of an array and `isArrayInsertion` is `true`, then `modify` will insert a new item at that location instead of overwriting its contents.
|
||||
* `ModificationOptions.formattingOptions` is now optional. If not set, newly inserted content will not be formatted.
|
||||
|
||||
|
||||
2.2.0 2019-10-25
|
||||
==================
|
||||
* added `ParseOptions.allowEmptyContent`. Default is `false`.
|
||||
* new API `getNodeType`: Returns the type of a value returned by parse.
|
||||
* `parse`: Fix issue with empty property name
|
||||
|
||||
2.1.0 2019-03-29
|
||||
==================
|
||||
* `JSONScanner` and `JSONVisitor` return lineNumber / character.
|
||||
|
||||
2.0.0 2018-04-12
|
||||
==================
|
||||
* renamed `Node.columnOffset` to `Node.colonOffset`
|
||||
* new API `getNodePath`: Gets the JSON path of the given JSON DOM node
|
||||
* new API `findNodeAtOffset`: Finds the most inner node at the given offset. If `includeRightBound` is set, also finds nodes that end at the given offset.
|
||||
|
||||
1.0.3 2018-03-07
|
||||
==================
|
||||
* provide ems modules
|
||||
|
||||
1.0.2 2018-03-05
|
||||
==================
|
||||
* added the `visit.onComment` API, reported when comments are allowed.
|
||||
* added the `ParseErrorCode.InvalidCommentToken` enum value, reported when comments are disallowed.
|
||||
|
||||
1.0.1
|
||||
==================
|
||||
* added the `format` API: computes edits to format a JSON document.
|
||||
* added the `modify` API: computes edits to insert, remove or replace a property or value in a JSON document.
|
||||
* added the `allyEdits` API: applies edits to a document
|
||||
|
||||
1.0.0
|
||||
==================
|
||||
* remove nls dependency (remove `getParseErrorMessage`)
|
||||
|
||||
0.4.2 / 2017-05-05
|
||||
==================
|
||||
* added `ParseError.offset` & `ParseError.length`
|
||||
|
||||
0.4.1 / 2017-04-02
|
||||
==================
|
||||
* added `ParseOptions.allowTrailingComma`
|
||||
|
||||
0.4.0 / 2017-02-23
|
||||
==================
|
||||
* fix for `getLocation`. Now `getLocation` inside an object will always return a property from inside that property. Can be empty string if the object has no properties or if the offset is before a actual property `{ "a": { | }} will return location ['a', ' ']`
|
||||
|
||||
0.3.0 / 2017-01-17
|
||||
==================
|
||||
* Updating to typescript 2.0
|
||||
21
node_modules/jsonc-parser/LICENSE.md
generated
vendored
Executable file
21
node_modules/jsonc-parser/LICENSE.md
generated
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
309
node_modules/jsonc-parser/README.md
generated
vendored
Executable file
309
node_modules/jsonc-parser/README.md
generated
vendored
Executable file
|
|
@ -0,0 +1,309 @@
|
|||
# jsonc-parser
|
||||
Scanner and parser for JSON with comments.
|
||||
|
||||
[](https://www.npmjs.org/package/jsonc-parser)
|
||||
[](https://npmjs.org/package/jsonc-parser)
|
||||
[](https://travis-ci.org/Microsoft/node-jsonc-parser)
|
||||
|
||||
Why?
|
||||
----
|
||||
JSONC is JSON with JavaScript style comments. This node module provides a scanner and fault tolerant parser that can process JSONC but is also useful for standard JSON.
|
||||
- the *scanner* tokenizes the input string into tokens and token offsets
|
||||
- the *visit* function implements a 'SAX' style parser with callbacks for the encountered properties and values.
|
||||
- the *parseTree* function computes a hierarchical DOM with offsets representing the encountered properties and values.
|
||||
- the *parse* function evaluates the JavaScript object represented by JSON string in a fault tolerant fashion.
|
||||
- the *getLocation* API returns a location object that describes the property or value located at a given offset in a JSON document.
|
||||
- the *findNodeAtLocation* API finds the node at a given location path in a JSON DOM.
|
||||
- the *format* API computes edits to format a JSON document.
|
||||
- the *modify* API computes edits to insert, remove or replace a property or value in a JSON document.
|
||||
- the *applyEdits* API applies edits to a document.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
npm install --save jsonc-parser
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
### Scanner:
|
||||
```typescript
|
||||
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export function createScanner(text:string, ignoreTrivia:boolean = false):JSONScanner;
|
||||
|
||||
/**
|
||||
* The scanner object, representing a JSON scanner at a position in the input string.
|
||||
*/
|
||||
export interface JSONScanner {
|
||||
/**
|
||||
* Sets the scan position to a new offset. A call to 'scan' is needed to get the first token.
|
||||
*/
|
||||
setPosition(pos: number): any;
|
||||
/**
|
||||
* Read the next token. Returns the token code.
|
||||
*/
|
||||
scan(): SyntaxKind;
|
||||
/**
|
||||
* Returns the current scan position, which is after the last read token.
|
||||
*/
|
||||
getPosition(): number;
|
||||
/**
|
||||
* Returns the last read token.
|
||||
*/
|
||||
getToken(): SyntaxKind;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
getTokenValue(): string;
|
||||
/**
|
||||
* The start offset of the last read token.
|
||||
*/
|
||||
getTokenOffset(): number;
|
||||
/**
|
||||
* The length of the last read token.
|
||||
*/
|
||||
getTokenLength(): number;
|
||||
/**
|
||||
* The zero-based start line number of the last read token.
|
||||
*/
|
||||
getTokenStartLine(): number;
|
||||
/**
|
||||
* The zero-based start character (column) of the last read token.
|
||||
*/
|
||||
getTokenStartCharacter(): number;
|
||||
/**
|
||||
* An error code of the last scan.
|
||||
*/
|
||||
getTokenError(): ScanError;
|
||||
}
|
||||
```
|
||||
|
||||
### Parser:
|
||||
```typescript
|
||||
|
||||
export interface ParseOptions {
|
||||
disallowComments?: boolean;
|
||||
}
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
export declare function parse(text: string, errors?: {error: ParseErrorCode;}[], options?: ParseOptions): any;
|
||||
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
export declare function visit(text: string, visitor: JSONVisitor, options?: ParseOptions): any;
|
||||
|
||||
export interface JSONVisitor {
|
||||
/**
|
||||
* Invoked when an open brace is encountered and an object is started. The offset and length represent the location of the open brace.
|
||||
*/
|
||||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a property is encountered. The offset and length represent the location of the property name.
|
||||
*/
|
||||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace.
|
||||
*/
|
||||
onObjectEnd?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when an open bracket is encountered. The offset and length represent the location of the open bracket.
|
||||
*/
|
||||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket.
|
||||
*/
|
||||
onArrayEnd?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a literal value is encountered. The offset and length represent the location of the literal value.
|
||||
*/
|
||||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator.
|
||||
*/
|
||||
onSeparator?: (character: string, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* When comments are allowed, invoked when a line or block comment is encountered. The offset and length represent the location of the comment.
|
||||
*/
|
||||
onComment?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked on an error.
|
||||
*/
|
||||
onError?: (error: ParseErrorCode, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
export declare function parseTree(text: string, errors?: ParseError[], options?: ParseOptions): Node | undefined;
|
||||
|
||||
export declare type NodeType = "object" | "array" | "property" | "string" | "number" | "boolean" | "null";
|
||||
export interface Node {
|
||||
type: NodeType;
|
||||
value?: any;
|
||||
offset: number;
|
||||
length: number;
|
||||
colonOffset?: number;
|
||||
parent?: Node;
|
||||
children?: Node[];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Utilities:
|
||||
```typescript
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
export declare function stripComments(text: string, replaceCh?: string): string;
|
||||
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
export declare function getLocation(text: string, position: number): Location;
|
||||
|
||||
export declare type Segment = string | number;
|
||||
export interface Location {
|
||||
/**
|
||||
* The previous property key or literal value (string, number, boolean or null) or undefined.
|
||||
*/
|
||||
previousNode?: Node;
|
||||
/**
|
||||
* The path describing the location in the JSON document. The path consists of a sequence strings
|
||||
* representing an object property or numbers for array indices.
|
||||
*/
|
||||
path: Segment[];
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
matches: (patterns: Segment[]) => boolean;
|
||||
/**
|
||||
* If set, the location's offset is at a property key.
|
||||
*/
|
||||
isAtPropertyKey: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
export function findNodeAtLocation(root: Node, path: JSONPath): Node | undefined;
|
||||
|
||||
/**
|
||||
* Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
export function findNodeAtOffset(root: Node, offset: number, includeRightBound?: boolean) : Node | undefined;
|
||||
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
export function getNodePath(node: Node) : JSONPath;
|
||||
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
export function getNodeValue(node: Node): any;
|
||||
|
||||
/**
|
||||
* Computes the edits needed to format a JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param range The range to format or `undefined` to format the full content
|
||||
* @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`
|
||||
*/
|
||||
export function format(documentText: string, range: Range, options: FormattingOptions): Edit[];
|
||||
|
||||
|
||||
/**
|
||||
* Computes the edits needed to modify a value in the JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param path The path of the value to change. The path represents either to the document root, a property or an array item.
|
||||
* If the path points to an non-existing property or item, it will be created.
|
||||
* @param value The new value for the specified property or item. If the value is undefined,
|
||||
* the property or item will be removed.
|
||||
* @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`
|
||||
*/
|
||||
export function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): Edit[];
|
||||
|
||||
/**
|
||||
* Applies edits to a input string.
|
||||
*/
|
||||
export function applyEdits(text: string, edits: Edit[]): string;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* A text range in the document
|
||||
*/
|
||||
export interface Range {
|
||||
/**
|
||||
* The start offset of the range.
|
||||
*/
|
||||
offset: number;
|
||||
/**
|
||||
* The length of the range. Must not be negative.
|
||||
*/
|
||||
length: number;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
(MIT License)
|
||||
|
||||
Copyright 2018, Microsoft
|
||||
186
node_modules/jsonc-parser/lib/esm/impl/edit.js
generated
vendored
Executable file
186
node_modules/jsonc-parser/lib/esm/impl/edit.js
generated
vendored
Executable file
|
|
@ -0,0 +1,186 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { format, isEOL } from './format';
|
||||
import { parseTree, findNodeAtLocation } from './parser';
|
||||
export function removeProperty(text, path, options) {
|
||||
return setProperty(text, path, void 0, options);
|
||||
}
|
||||
export function setProperty(text, originalPath, value, options) {
|
||||
var _a;
|
||||
var path = originalPath.slice();
|
||||
var errors = [];
|
||||
var root = parseTree(text, errors);
|
||||
var parent = void 0;
|
||||
var lastSegment = void 0;
|
||||
while (path.length > 0) {
|
||||
lastSegment = path.pop();
|
||||
parent = findNodeAtLocation(root, path);
|
||||
if (parent === void 0 && value !== void 0) {
|
||||
if (typeof lastSegment === 'string') {
|
||||
value = (_a = {}, _a[lastSegment] = value, _a);
|
||||
}
|
||||
else {
|
||||
value = [value];
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!parent) {
|
||||
// empty document
|
||||
if (value === void 0) { // delete
|
||||
throw new Error('Can not delete in empty document');
|
||||
}
|
||||
return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);
|
||||
}
|
||||
else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
|
||||
var existing = findNodeAtLocation(parent, [lastSegment]);
|
||||
if (existing !== void 0) {
|
||||
if (value === void 0) { // delete
|
||||
if (!existing.parent) {
|
||||
throw new Error('Malformed AST');
|
||||
}
|
||||
var propertyIndex = parent.children.indexOf(existing.parent);
|
||||
var removeBegin = void 0;
|
||||
var removeEnd = existing.parent.offset + existing.parent.length;
|
||||
if (propertyIndex > 0) {
|
||||
// remove the comma of the previous node
|
||||
var previous = parent.children[propertyIndex - 1];
|
||||
removeBegin = previous.offset + previous.length;
|
||||
}
|
||||
else {
|
||||
removeBegin = parent.offset + 1;
|
||||
if (parent.children.length > 1) {
|
||||
// remove the comma of the next node
|
||||
var next = parent.children[1];
|
||||
removeEnd = next.offset;
|
||||
}
|
||||
}
|
||||
return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, options);
|
||||
}
|
||||
else {
|
||||
// set value of existing property
|
||||
return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value === void 0) { // delete
|
||||
return []; // property does not exist, nothing to do
|
||||
}
|
||||
var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value);
|
||||
var index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length;
|
||||
var edit = void 0;
|
||||
if (index > 0) {
|
||||
var previous = parent.children[index - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
||||
}
|
||||
else if (parent.children.length === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
||||
}
|
||||
else {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
}
|
||||
else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
|
||||
var insertIndex = lastSegment;
|
||||
if (insertIndex === -1) {
|
||||
// Insert
|
||||
var newProperty = "" + JSON.stringify(value);
|
||||
var edit = void 0;
|
||||
if (parent.children.length === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
||||
}
|
||||
else {
|
||||
var previous = parent.children[parent.children.length - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
else if (value === void 0 && parent.children.length >= 0) {
|
||||
// Removal
|
||||
var removalIndex = lastSegment;
|
||||
var toRemove = parent.children[removalIndex];
|
||||
var edit = void 0;
|
||||
if (parent.children.length === 1) {
|
||||
// only item
|
||||
edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
|
||||
}
|
||||
else if (parent.children.length - 1 === removalIndex) {
|
||||
// last item
|
||||
var previous = parent.children[removalIndex - 1];
|
||||
var offset = previous.offset + previous.length;
|
||||
var parentEndOffset = parent.offset + parent.length;
|
||||
edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' };
|
||||
}
|
||||
else {
|
||||
edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
else if (value !== void 0) {
|
||||
var edit = void 0;
|
||||
var newProperty = "" + JSON.stringify(value);
|
||||
if (!options.isArrayInsertion && parent.children.length > lastSegment) {
|
||||
var toModify = parent.children[lastSegment];
|
||||
edit = { offset: toModify.offset, length: toModify.length, content: newProperty };
|
||||
}
|
||||
else if (parent.children.length === 0 || lastSegment === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + ',' };
|
||||
}
|
||||
else {
|
||||
var index = lastSegment > parent.children.length ? parent.children.length : lastSegment;
|
||||
var previous = parent.children[index - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
else {
|
||||
throw new Error("Can not " + (value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')) + " Array index " + insertIndex + " as length is not sufficient");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type);
|
||||
}
|
||||
}
|
||||
function withFormatting(text, edit, options) {
|
||||
if (!options.formattingOptions) {
|
||||
return [edit];
|
||||
}
|
||||
// apply the edit
|
||||
var newText = applyEdit(text, edit);
|
||||
// format the new text
|
||||
var begin = edit.offset;
|
||||
var end = edit.offset + edit.content.length;
|
||||
if (edit.length === 0 || edit.content.length === 0) { // insert or remove
|
||||
while (begin > 0 && !isEOL(newText, begin - 1)) {
|
||||
begin--;
|
||||
}
|
||||
while (end < newText.length && !isEOL(newText, end)) {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
var edits = format(newText, { offset: begin, length: end - begin }, options.formattingOptions);
|
||||
// apply the formatting edits and track the begin and end offsets of the changes
|
||||
for (var i = edits.length - 1; i >= 0; i--) {
|
||||
var edit_1 = edits[i];
|
||||
newText = applyEdit(newText, edit_1);
|
||||
begin = Math.min(begin, edit_1.offset);
|
||||
end = Math.max(end, edit_1.offset + edit_1.length);
|
||||
end += edit_1.content.length - edit_1.length;
|
||||
}
|
||||
// create a single edit with all changes
|
||||
var editLength = text.length - (newText.length - end) - begin;
|
||||
return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
|
||||
}
|
||||
export function applyEdit(text, edit) {
|
||||
return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
|
||||
}
|
||||
export function isWS(text, offset) {
|
||||
return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
205
node_modules/jsonc-parser/lib/esm/impl/format.js
generated
vendored
Executable file
205
node_modules/jsonc-parser/lib/esm/impl/format.js
generated
vendored
Executable file
|
|
@ -0,0 +1,205 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { createScanner } from './scanner';
|
||||
export function format(documentText, range, options) {
|
||||
var initialIndentLevel;
|
||||
var formatText;
|
||||
var formatTextStart;
|
||||
var rangeStart;
|
||||
var rangeEnd;
|
||||
if (range) {
|
||||
rangeStart = range.offset;
|
||||
rangeEnd = rangeStart + range.length;
|
||||
formatTextStart = rangeStart;
|
||||
while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
|
||||
formatTextStart--;
|
||||
}
|
||||
var endOffset = rangeEnd;
|
||||
while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
|
||||
endOffset++;
|
||||
}
|
||||
formatText = documentText.substring(formatTextStart, endOffset);
|
||||
initialIndentLevel = computeIndentLevel(formatText, options);
|
||||
}
|
||||
else {
|
||||
formatText = documentText;
|
||||
initialIndentLevel = 0;
|
||||
formatTextStart = 0;
|
||||
rangeStart = 0;
|
||||
rangeEnd = documentText.length;
|
||||
}
|
||||
var eol = getEOL(options, documentText);
|
||||
var lineBreak = false;
|
||||
var indentLevel = 0;
|
||||
var indentValue;
|
||||
if (options.insertSpaces) {
|
||||
indentValue = repeat(' ', options.tabSize || 4);
|
||||
}
|
||||
else {
|
||||
indentValue = '\t';
|
||||
}
|
||||
var scanner = createScanner(formatText, false);
|
||||
var hasError = false;
|
||||
function newLineAndIndent() {
|
||||
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 */);
|
||||
token = scanner.scan();
|
||||
}
|
||||
hasError = token === 16 /* Unknown */ || scanner.getTokenError() !== 0 /* None */;
|
||||
return token;
|
||||
}
|
||||
var editOperations = [];
|
||||
function addEdit(text, startOffset, endOffset) {
|
||||
if (!hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text) {
|
||||
editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
|
||||
}
|
||||
}
|
||||
var firstToken = scanNext();
|
||||
if (firstToken !== 17 /* EOF */) {
|
||||
var firstTokenStart = scanner.getTokenOffset() + formatTextStart;
|
||||
var initialIndent = repeat(indentValue, initialIndentLevel);
|
||||
addEdit(initialIndent, formatTextStart, firstTokenStart);
|
||||
}
|
||||
while (firstToken !== 17 /* EOF */) {
|
||||
var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
|
||||
var secondToken = scanNext();
|
||||
var replaceContent = '';
|
||||
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
|
||||
var commentTokenStart = scanner.getTokenOffset() + formatTextStart;
|
||||
addEdit(' ', firstTokenEnd, commentTokenStart);
|
||||
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
|
||||
needsLineBreak = secondToken === 12 /* LineCommentTrivia */;
|
||||
replaceContent = needsLineBreak ? newLineAndIndent() : '';
|
||||
secondToken = scanNext();
|
||||
}
|
||||
if (secondToken === 2 /* CloseBraceToken */) {
|
||||
if (firstToken !== 1 /* OpenBraceToken */) {
|
||||
indentLevel--;
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
}
|
||||
else if (secondToken === 4 /* CloseBracketToken */) {
|
||||
if (firstToken !== 3 /* OpenBracketToken */) {
|
||||
indentLevel--;
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (firstToken) {
|
||||
case 3 /* OpenBracketToken */:
|
||||
case 1 /* OpenBraceToken */:
|
||||
indentLevel++;
|
||||
replaceContent = newLineAndIndent();
|
||||
break;
|
||||
case 5 /* CommaToken */:
|
||||
case 12 /* LineCommentTrivia */:
|
||||
replaceContent = newLineAndIndent();
|
||||
break;
|
||||
case 13 /* BlockCommentTrivia */:
|
||||
if (lineBreak) {
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
else if (!needsLineBreak) {
|
||||
// symbol following comment on the same line: keep on same line, separate with ' '
|
||||
replaceContent = ' ';
|
||||
}
|
||||
break;
|
||||
case 6 /* ColonToken */:
|
||||
if (!needsLineBreak) {
|
||||
replaceContent = ' ';
|
||||
}
|
||||
break;
|
||||
case 10 /* StringLiteral */:
|
||||
if (secondToken === 6 /* ColonToken */) {
|
||||
if (!needsLineBreak) {
|
||||
replaceContent = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
// 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) {
|
||||
replaceContent = ' ';
|
||||
}
|
||||
}
|
||||
else if (secondToken !== 5 /* CommaToken */ && secondToken !== 17 /* EOF */) {
|
||||
hasError = true;
|
||||
}
|
||||
break;
|
||||
case 16 /* Unknown */:
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
if (lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) {
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
}
|
||||
if (secondToken === 17 /* EOF */) {
|
||||
replaceContent = options.insertFinalNewline ? eol : '';
|
||||
}
|
||||
var secondTokenStart = scanner.getTokenOffset() + formatTextStart;
|
||||
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
|
||||
firstToken = secondToken;
|
||||
}
|
||||
return editOperations;
|
||||
}
|
||||
function repeat(s, count) {
|
||||
var result = '';
|
||||
for (var i = 0; i < count; i++) {
|
||||
result += s;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function computeIndentLevel(content, options) {
|
||||
var i = 0;
|
||||
var nChars = 0;
|
||||
var tabSize = options.tabSize || 4;
|
||||
while (i < content.length) {
|
||||
var ch = content.charAt(i);
|
||||
if (ch === ' ') {
|
||||
nChars++;
|
||||
}
|
||||
else if (ch === '\t') {
|
||||
nChars += tabSize;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return Math.floor(nChars / tabSize);
|
||||
}
|
||||
function getEOL(options, text) {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
var ch = text.charAt(i);
|
||||
if (ch === '\r') {
|
||||
if (i + 1 < text.length && text.charAt(i + 1) === '\n') {
|
||||
return '\r\n';
|
||||
}
|
||||
return '\r';
|
||||
}
|
||||
else if (ch === '\n') {
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
return (options && options.eol) || '\n';
|
||||
}
|
||||
export function isEOL(text, offset) {
|
||||
return '\r\n'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
621
node_modules/jsonc-parser/lib/esm/impl/parser.js
generated
vendored
Executable file
621
node_modules/jsonc-parser/lib/esm/impl/parser.js
generated
vendored
Executable file
|
|
@ -0,0 +1,621 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { createScanner } from './scanner';
|
||||
var ParseOptions;
|
||||
(function (ParseOptions) {
|
||||
ParseOptions.DEFAULT = {
|
||||
allowTrailingComma: false
|
||||
};
|
||||
})(ParseOptions || (ParseOptions = {}));
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
export function getLocation(text, position) {
|
||||
var segments = []; // strings or numbers
|
||||
var earlyReturnException = new Object();
|
||||
var previousNode = undefined;
|
||||
var previousNodeInst = {
|
||||
value: {},
|
||||
offset: 0,
|
||||
length: 0,
|
||||
type: 'object',
|
||||
parent: undefined
|
||||
};
|
||||
var isAtPropertyKey = false;
|
||||
function setPreviousNode(value, offset, length, type) {
|
||||
previousNodeInst.value = value;
|
||||
previousNodeInst.offset = offset;
|
||||
previousNodeInst.length = length;
|
||||
previousNodeInst.type = type;
|
||||
previousNodeInst.colonOffset = undefined;
|
||||
previousNode = previousNodeInst;
|
||||
}
|
||||
try {
|
||||
visit(text, {
|
||||
onObjectBegin: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
isAtPropertyKey = position > offset;
|
||||
segments.push(''); // push a placeholder (will be replaced)
|
||||
},
|
||||
onObjectProperty: function (name, offset, length) {
|
||||
if (position < offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
setPreviousNode(name, offset, length, 'property');
|
||||
segments[segments.length - 1] = name;
|
||||
if (position <= offset + length) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
},
|
||||
onObjectEnd: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
segments.pop();
|
||||
},
|
||||
onArrayBegin: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
segments.push(0);
|
||||
},
|
||||
onArrayEnd: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
segments.pop();
|
||||
},
|
||||
onLiteralValue: function (value, offset, length) {
|
||||
if (position < offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
setPreviousNode(value, offset, length, getNodeType(value));
|
||||
if (position <= offset + length) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
},
|
||||
onSeparator: function (sep, offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
if (sep === ':' && previousNode && previousNode.type === 'property') {
|
||||
previousNode.colonOffset = offset;
|
||||
isAtPropertyKey = false;
|
||||
previousNode = undefined;
|
||||
}
|
||||
else if (sep === ',') {
|
||||
var last = segments[segments.length - 1];
|
||||
if (typeof last === 'number') {
|
||||
segments[segments.length - 1] = last + 1;
|
||||
}
|
||||
else {
|
||||
isAtPropertyKey = true;
|
||||
segments[segments.length - 1] = '';
|
||||
}
|
||||
previousNode = undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
if (e !== earlyReturnException) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return {
|
||||
path: segments,
|
||||
previousNode: previousNode,
|
||||
isAtPropertyKey: isAtPropertyKey,
|
||||
matches: function (pattern) {
|
||||
var k = 0;
|
||||
for (var i = 0; k < pattern.length && i < segments.length; i++) {
|
||||
if (pattern[k] === segments[i] || pattern[k] === '*') {
|
||||
k++;
|
||||
}
|
||||
else if (pattern[k] !== '**') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return k === pattern.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
export function parse(text, errors, options) {
|
||||
if (errors === void 0) { errors = []; }
|
||||
if (options === void 0) { options = ParseOptions.DEFAULT; }
|
||||
var currentProperty = null;
|
||||
var currentParent = [];
|
||||
var previousParents = [];
|
||||
function onValue(value) {
|
||||
if (Array.isArray(currentParent)) {
|
||||
currentParent.push(value);
|
||||
}
|
||||
else if (currentProperty !== null) {
|
||||
currentParent[currentProperty] = value;
|
||||
}
|
||||
}
|
||||
var visitor = {
|
||||
onObjectBegin: function () {
|
||||
var object = {};
|
||||
onValue(object);
|
||||
previousParents.push(currentParent);
|
||||
currentParent = object;
|
||||
currentProperty = null;
|
||||
},
|
||||
onObjectProperty: function (name) {
|
||||
currentProperty = name;
|
||||
},
|
||||
onObjectEnd: function () {
|
||||
currentParent = previousParents.pop();
|
||||
},
|
||||
onArrayBegin: function () {
|
||||
var array = [];
|
||||
onValue(array);
|
||||
previousParents.push(currentParent);
|
||||
currentParent = array;
|
||||
currentProperty = null;
|
||||
},
|
||||
onArrayEnd: function () {
|
||||
currentParent = previousParents.pop();
|
||||
},
|
||||
onLiteralValue: onValue,
|
||||
onError: function (error, offset, length) {
|
||||
errors.push({ error: error, offset: offset, length: length });
|
||||
}
|
||||
};
|
||||
visit(text, visitor, options);
|
||||
return currentParent[0];
|
||||
}
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
export function parseTree(text, errors, options) {
|
||||
if (errors === void 0) { errors = []; }
|
||||
if (options === void 0) { options = ParseOptions.DEFAULT; }
|
||||
var currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root
|
||||
function ensurePropertyComplete(endOffset) {
|
||||
if (currentParent.type === 'property') {
|
||||
currentParent.length = endOffset - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
}
|
||||
}
|
||||
function onValue(valueNode) {
|
||||
currentParent.children.push(valueNode);
|
||||
return valueNode;
|
||||
}
|
||||
var visitor = {
|
||||
onObjectBegin: function (offset) {
|
||||
currentParent = onValue({ type: 'object', offset: offset, length: -1, parent: currentParent, children: [] });
|
||||
},
|
||||
onObjectProperty: function (name, offset, length) {
|
||||
currentParent = onValue({ type: 'property', offset: offset, length: -1, parent: currentParent, children: [] });
|
||||
currentParent.children.push({ type: 'string', value: name, offset: offset, length: length, parent: currentParent });
|
||||
},
|
||||
onObjectEnd: function (offset, length) {
|
||||
ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete
|
||||
currentParent.length = offset + length - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
ensurePropertyComplete(offset + length);
|
||||
},
|
||||
onArrayBegin: function (offset, length) {
|
||||
currentParent = onValue({ type: 'array', offset: offset, length: -1, parent: currentParent, children: [] });
|
||||
},
|
||||
onArrayEnd: function (offset, length) {
|
||||
currentParent.length = offset + length - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
ensurePropertyComplete(offset + length);
|
||||
},
|
||||
onLiteralValue: function (value, offset, length) {
|
||||
onValue({ type: getNodeType(value), offset: offset, length: length, parent: currentParent, value: value });
|
||||
ensurePropertyComplete(offset + length);
|
||||
},
|
||||
onSeparator: function (sep, offset, length) {
|
||||
if (currentParent.type === 'property') {
|
||||
if (sep === ':') {
|
||||
currentParent.colonOffset = offset;
|
||||
}
|
||||
else if (sep === ',') {
|
||||
ensurePropertyComplete(offset);
|
||||
}
|
||||
}
|
||||
},
|
||||
onError: function (error, offset, length) {
|
||||
errors.push({ error: error, offset: offset, length: length });
|
||||
}
|
||||
};
|
||||
visit(text, visitor, options);
|
||||
var result = currentParent.children[0];
|
||||
if (result) {
|
||||
delete result.parent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
export function findNodeAtLocation(root, path) {
|
||||
if (!root) {
|
||||
return undefined;
|
||||
}
|
||||
var node = root;
|
||||
for (var _i = 0, path_1 = path; _i < path_1.length; _i++) {
|
||||
var segment = path_1[_i];
|
||||
if (typeof segment === 'string') {
|
||||
if (node.type !== 'object' || !Array.isArray(node.children)) {
|
||||
return undefined;
|
||||
}
|
||||
var found = false;
|
||||
for (var _a = 0, _b = node.children; _a < _b.length; _a++) {
|
||||
var propertyNode = _b[_a];
|
||||
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment) {
|
||||
node = propertyNode.children[1];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var index = segment;
|
||||
if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
|
||||
return undefined;
|
||||
}
|
||||
node = node.children[index];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
export function getNodePath(node) {
|
||||
if (!node.parent || !node.parent.children) {
|
||||
return [];
|
||||
}
|
||||
var path = getNodePath(node.parent);
|
||||
if (node.parent.type === 'property') {
|
||||
var key = node.parent.children[0].value;
|
||||
path.push(key);
|
||||
}
|
||||
else if (node.parent.type === 'array') {
|
||||
var index = node.parent.children.indexOf(node);
|
||||
if (index !== -1) {
|
||||
path.push(index);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
export function getNodeValue(node) {
|
||||
switch (node.type) {
|
||||
case 'array':
|
||||
return node.children.map(getNodeValue);
|
||||
case 'object':
|
||||
var obj = Object.create(null);
|
||||
for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
|
||||
var prop = _a[_i];
|
||||
var valueNode = prop.children[1];
|
||||
if (valueNode) {
|
||||
obj[prop.children[0].value] = getNodeValue(valueNode);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
case 'null':
|
||||
case 'string':
|
||||
case 'number':
|
||||
case 'boolean':
|
||||
return node.value;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
export function contains(node, offset, includeRightBound) {
|
||||
if (includeRightBound === void 0) { includeRightBound = false; }
|
||||
return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));
|
||||
}
|
||||
/**
|
||||
* Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
export function findNodeAtOffset(node, offset, includeRightBound) {
|
||||
if (includeRightBound === void 0) { includeRightBound = false; }
|
||||
if (contains(node, offset, includeRightBound)) {
|
||||
var children = node.children;
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length && children[i].offset <= offset; i++) {
|
||||
var item = findNodeAtOffset(children[i], offset, includeRightBound);
|
||||
if (item) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
export function visit(text, visitor, options) {
|
||||
if (options === void 0) { options = ParseOptions.DEFAULT; }
|
||||
var _scanner = createScanner(text, false);
|
||||
function toNoArgVisit(visitFunction) {
|
||||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : 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);
|
||||
var disallowComments = options && options.disallowComments;
|
||||
var allowTrailingComma = options && options.allowTrailingComma;
|
||||
function scanNext() {
|
||||
while (true) {
|
||||
var token = _scanner.scan();
|
||||
switch (_scanner.getTokenError()) {
|
||||
case 4 /* InvalidUnicode */:
|
||||
handleError(14 /* InvalidUnicode */);
|
||||
break;
|
||||
case 5 /* InvalidEscapeCharacter */:
|
||||
handleError(15 /* InvalidEscapeCharacter */);
|
||||
break;
|
||||
case 3 /* UnexpectedEndOfNumber */:
|
||||
handleError(13 /* UnexpectedEndOfNumber */);
|
||||
break;
|
||||
case 1 /* UnexpectedEndOfComment */:
|
||||
if (!disallowComments) {
|
||||
handleError(11 /* UnexpectedEndOfComment */);
|
||||
}
|
||||
break;
|
||||
case 2 /* UnexpectedEndOfString */:
|
||||
handleError(12 /* UnexpectedEndOfString */);
|
||||
break;
|
||||
case 6 /* InvalidCharacter */:
|
||||
handleError(16 /* InvalidCharacter */);
|
||||
break;
|
||||
}
|
||||
switch (token) {
|
||||
case 12 /* LineCommentTrivia */:
|
||||
case 13 /* BlockCommentTrivia */:
|
||||
if (disallowComments) {
|
||||
handleError(10 /* InvalidCommentToken */);
|
||||
}
|
||||
else {
|
||||
onComment();
|
||||
}
|
||||
break;
|
||||
case 16 /* Unknown */:
|
||||
handleError(1 /* InvalidSymbol */);
|
||||
break;
|
||||
case 15 /* Trivia */:
|
||||
case 14 /* LineBreakTrivia */:
|
||||
break;
|
||||
default:
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
function handleError(error, skipUntilAfter, skipUntil) {
|
||||
if (skipUntilAfter === void 0) { skipUntilAfter = []; }
|
||||
if (skipUntil === void 0) { skipUntil = []; }
|
||||
onError(error);
|
||||
if (skipUntilAfter.length + skipUntil.length > 0) {
|
||||
var token = _scanner.getToken();
|
||||
while (token !== 17 /* EOF */) {
|
||||
if (skipUntilAfter.indexOf(token) !== -1) {
|
||||
scanNext();
|
||||
break;
|
||||
}
|
||||
else if (skipUntil.indexOf(token) !== -1) {
|
||||
break;
|
||||
}
|
||||
token = scanNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
function parseString(isValue) {
|
||||
var value = _scanner.getTokenValue();
|
||||
if (isValue) {
|
||||
onLiteralValue(value);
|
||||
}
|
||||
else {
|
||||
onObjectProperty(value);
|
||||
}
|
||||
scanNext();
|
||||
return true;
|
||||
}
|
||||
function parseLiteral() {
|
||||
switch (_scanner.getToken()) {
|
||||
case 11 /* NumericLiteral */:
|
||||
var tokenValue = _scanner.getTokenValue();
|
||||
var value = Number(tokenValue);
|
||||
if (isNaN(value)) {
|
||||
handleError(2 /* InvalidNumberFormat */);
|
||||
value = 0;
|
||||
}
|
||||
onLiteralValue(value);
|
||||
break;
|
||||
case 7 /* NullKeyword */:
|
||||
onLiteralValue(null);
|
||||
break;
|
||||
case 8 /* TrueKeyword */:
|
||||
onLiteralValue(true);
|
||||
break;
|
||||
case 9 /* FalseKeyword */:
|
||||
onLiteralValue(false);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
scanNext();
|
||||
return true;
|
||||
}
|
||||
function parseProperty() {
|
||||
if (_scanner.getToken() !== 10 /* StringLiteral */) {
|
||||
handleError(3 /* PropertyNameExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
return false;
|
||||
}
|
||||
parseString(false);
|
||||
if (_scanner.getToken() === 6 /* ColonToken */) {
|
||||
onSeparator(':');
|
||||
scanNext(); // consume colon
|
||||
if (!parseValue()) {
|
||||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
handleError(5 /* ColonExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function parseObject() {
|
||||
onObjectBegin();
|
||||
scanNext(); // consume open brace
|
||||
var needsComma = false;
|
||||
while (_scanner.getToken() !== 2 /* CloseBraceToken */ && _scanner.getToken() !== 17 /* EOF */) {
|
||||
if (_scanner.getToken() === 5 /* CommaToken */) {
|
||||
if (!needsComma) {
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
}
|
||||
onSeparator(',');
|
||||
scanNext(); // consume comma
|
||||
if (_scanner.getToken() === 2 /* CloseBraceToken */ && allowTrailingComma) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (needsComma) {
|
||||
handleError(6 /* CommaExpected */, [], []);
|
||||
}
|
||||
if (!parseProperty()) {
|
||||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
needsComma = true;
|
||||
}
|
||||
onObjectEnd();
|
||||
if (_scanner.getToken() !== 2 /* CloseBraceToken */) {
|
||||
handleError(7 /* CloseBraceExpected */, [2 /* CloseBraceToken */], []);
|
||||
}
|
||||
else {
|
||||
scanNext(); // consume close brace
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function parseArray() {
|
||||
onArrayBegin();
|
||||
scanNext(); // consume open bracket
|
||||
var needsComma = false;
|
||||
while (_scanner.getToken() !== 4 /* CloseBracketToken */ && _scanner.getToken() !== 17 /* EOF */) {
|
||||
if (_scanner.getToken() === 5 /* CommaToken */) {
|
||||
if (!needsComma) {
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
}
|
||||
onSeparator(',');
|
||||
scanNext(); // consume comma
|
||||
if (_scanner.getToken() === 4 /* CloseBracketToken */ && allowTrailingComma) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (needsComma) {
|
||||
handleError(6 /* CommaExpected */, [], []);
|
||||
}
|
||||
if (!parseValue()) {
|
||||
handleError(4 /* ValueExpected */, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
needsComma = true;
|
||||
}
|
||||
onArrayEnd();
|
||||
if (_scanner.getToken() !== 4 /* CloseBracketToken */) {
|
||||
handleError(8 /* CloseBracketExpected */, [4 /* CloseBracketToken */], []);
|
||||
}
|
||||
else {
|
||||
scanNext(); // consume close bracket
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function parseValue() {
|
||||
switch (_scanner.getToken()) {
|
||||
case 3 /* OpenBracketToken */:
|
||||
return parseArray();
|
||||
case 1 /* OpenBraceToken */:
|
||||
return parseObject();
|
||||
case 10 /* StringLiteral */:
|
||||
return parseString(true);
|
||||
default:
|
||||
return parseLiteral();
|
||||
}
|
||||
}
|
||||
scanNext();
|
||||
if (_scanner.getToken() === 17 /* EOF */) {
|
||||
if (options.allowEmptyContent) {
|
||||
return true;
|
||||
}
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
return false;
|
||||
}
|
||||
if (!parseValue()) {
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
return false;
|
||||
}
|
||||
if (_scanner.getToken() !== 17 /* EOF */) {
|
||||
handleError(9 /* EndOfFileExpected */, [], []);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
export function stripComments(text, replaceCh) {
|
||||
var _scanner = createScanner(text), parts = [], kind, offset = 0, pos;
|
||||
do {
|
||||
pos = _scanner.getPosition();
|
||||
kind = _scanner.scan();
|
||||
switch (kind) {
|
||||
case 12 /* LineCommentTrivia */:
|
||||
case 13 /* BlockCommentTrivia */:
|
||||
case 17 /* EOF */:
|
||||
if (offset !== pos) {
|
||||
parts.push(text.substring(offset, pos));
|
||||
}
|
||||
if (replaceCh !== undefined) {
|
||||
parts.push(_scanner.getTokenValue().replace(/[^\r\n]/g, replaceCh));
|
||||
}
|
||||
offset = _scanner.getPosition();
|
||||
break;
|
||||
}
|
||||
} while (kind !== 17 /* EOF */);
|
||||
return parts.join('');
|
||||
}
|
||||
export function getNodeType(value) {
|
||||
switch (typeof value) {
|
||||
case 'boolean': return 'boolean';
|
||||
case 'number': return 'number';
|
||||
case 'string': return 'string';
|
||||
case 'object': {
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
else if (Array.isArray(value)) {
|
||||
return 'array';
|
||||
}
|
||||
return 'object';
|
||||
}
|
||||
default: return 'null';
|
||||
}
|
||||
}
|
||||
363
node_modules/jsonc-parser/lib/esm/impl/scanner.js
generated
vendored
Executable file
363
node_modules/jsonc-parser/lib/esm/impl/scanner.js
generated
vendored
Executable file
|
|
@ -0,0 +1,363 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export function createScanner(text, ignoreTrivia) {
|
||||
if (ignoreTrivia === void 0) { ignoreTrivia = false; }
|
||||
var len = text.length;
|
||||
var pos = 0, value = '', tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */;
|
||||
function scanHexDigits(count, exact) {
|
||||
var digits = 0;
|
||||
var value = 0;
|
||||
while (digits < count || !exact) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
|
||||
value = value * 16 + ch - 48 /* _0 */;
|
||||
}
|
||||
else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
|
||||
value = value * 16 + ch - 65 /* A */ + 10;
|
||||
}
|
||||
else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
|
||||
value = value * 16 + ch - 97 /* a */ + 10;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
digits++;
|
||||
}
|
||||
if (digits < count) {
|
||||
value = -1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function setPosition(newPosition) {
|
||||
pos = newPosition;
|
||||
value = '';
|
||||
tokenOffset = 0;
|
||||
token = 16 /* Unknown */;
|
||||
scanError = 0 /* None */;
|
||||
}
|
||||
function scanNumber() {
|
||||
var start = pos;
|
||||
if (text.charCodeAt(pos) === 48 /* _0 */) {
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) {
|
||||
pos++;
|
||||
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scanError = 3 /* UnexpectedEndOfNumber */;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
}
|
||||
var end = pos;
|
||||
if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) {
|
||||
pos++;
|
||||
if (pos < text.length && text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) {
|
||||
pos++;
|
||||
}
|
||||
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
end = pos;
|
||||
}
|
||||
else {
|
||||
scanError = 3 /* UnexpectedEndOfNumber */;
|
||||
}
|
||||
}
|
||||
return text.substring(start, end);
|
||||
}
|
||||
function scanString() {
|
||||
var result = '', start = pos;
|
||||
while (true) {
|
||||
if (pos >= len) {
|
||||
result += text.substring(start, pos);
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch === 34 /* doubleQuote */) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
if (ch === 92 /* backslash */) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
if (pos >= len) {
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
var ch2 = text.charCodeAt(pos++);
|
||||
switch (ch2) {
|
||||
case 34 /* doubleQuote */:
|
||||
result += '\"';
|
||||
break;
|
||||
case 92 /* backslash */:
|
||||
result += '\\';
|
||||
break;
|
||||
case 47 /* slash */:
|
||||
result += '/';
|
||||
break;
|
||||
case 98 /* b */:
|
||||
result += '\b';
|
||||
break;
|
||||
case 102 /* f */:
|
||||
result += '\f';
|
||||
break;
|
||||
case 110 /* n */:
|
||||
result += '\n';
|
||||
break;
|
||||
case 114 /* r */:
|
||||
result += '\r';
|
||||
break;
|
||||
case 116 /* t */:
|
||||
result += '\t';
|
||||
break;
|
||||
case 117 /* u */:
|
||||
var ch3 = scanHexDigits(4, true);
|
||||
if (ch3 >= 0) {
|
||||
result += String.fromCharCode(ch3);
|
||||
}
|
||||
else {
|
||||
scanError = 4 /* InvalidUnicode */;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
scanError = 5 /* InvalidEscapeCharacter */;
|
||||
}
|
||||
start = pos;
|
||||
continue;
|
||||
}
|
||||
if (ch >= 0 && ch <= 0x1f) {
|
||||
if (isLineBreak(ch)) {
|
||||
result += text.substring(start, pos);
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
scanError = 6 /* InvalidCharacter */;
|
||||
// mark as error but continue with string
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function scanNext() {
|
||||
value = '';
|
||||
scanError = 0 /* None */;
|
||||
tokenOffset = pos;
|
||||
lineStartOffset = lineNumber;
|
||||
prevTokenLineStartOffset = tokenLineStartOffset;
|
||||
if (pos >= len) {
|
||||
// at the end
|
||||
tokenOffset = len;
|
||||
return token = 17 /* EOF */;
|
||||
}
|
||||
var code = text.charCodeAt(pos);
|
||||
// trivia: whitespace
|
||||
if (isWhiteSpace(code)) {
|
||||
do {
|
||||
pos++;
|
||||
value += String.fromCharCode(code);
|
||||
code = text.charCodeAt(pos);
|
||||
} while (isWhiteSpace(code));
|
||||
return token = 15 /* Trivia */;
|
||||
}
|
||||
// trivia: newlines
|
||||
if (isLineBreak(code)) {
|
||||
pos++;
|
||||
value += String.fromCharCode(code);
|
||||
if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
||||
pos++;
|
||||
value += '\n';
|
||||
}
|
||||
lineNumber++;
|
||||
tokenLineStartOffset = pos;
|
||||
return token = 14 /* LineBreakTrivia */;
|
||||
}
|
||||
switch (code) {
|
||||
// tokens: []{}:,
|
||||
case 123 /* openBrace */:
|
||||
pos++;
|
||||
return token = 1 /* OpenBraceToken */;
|
||||
case 125 /* closeBrace */:
|
||||
pos++;
|
||||
return token = 2 /* CloseBraceToken */;
|
||||
case 91 /* openBracket */:
|
||||
pos++;
|
||||
return token = 3 /* OpenBracketToken */;
|
||||
case 93 /* closeBracket */:
|
||||
pos++;
|
||||
return token = 4 /* CloseBracketToken */;
|
||||
case 58 /* colon */:
|
||||
pos++;
|
||||
return token = 6 /* ColonToken */;
|
||||
case 44 /* comma */:
|
||||
pos++;
|
||||
return token = 5 /* CommaToken */;
|
||||
// strings
|
||||
case 34 /* doubleQuote */:
|
||||
pos++;
|
||||
value = scanString();
|
||||
return token = 10 /* StringLiteral */;
|
||||
// comments
|
||||
case 47 /* slash */:
|
||||
var start = pos - 1;
|
||||
// Single-line comment
|
||||
if (text.charCodeAt(pos + 1) === 47 /* slash */) {
|
||||
pos += 2;
|
||||
while (pos < len) {
|
||||
if (isLineBreak(text.charCodeAt(pos))) {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
value = text.substring(start, pos);
|
||||
return token = 12 /* LineCommentTrivia */;
|
||||
}
|
||||
// Multi-line comment
|
||||
if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
|
||||
pos += 2;
|
||||
var safeLength = len - 1; // For lookahead.
|
||||
var commentClosed = false;
|
||||
while (pos < safeLength) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
|
||||
pos += 2;
|
||||
commentClosed = true;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
if (isLineBreak(ch)) {
|
||||
if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
||||
pos++;
|
||||
}
|
||||
lineNumber++;
|
||||
tokenLineStartOffset = pos;
|
||||
}
|
||||
}
|
||||
if (!commentClosed) {
|
||||
pos++;
|
||||
scanError = 1 /* UnexpectedEndOfComment */;
|
||||
}
|
||||
value = text.substring(start, pos);
|
||||
return token = 13 /* BlockCommentTrivia */;
|
||||
}
|
||||
// just a single slash
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
return token = 16 /* Unknown */;
|
||||
// numbers
|
||||
case 45 /* minus */:
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
// found a minus, followed by a number so
|
||||
// we fall through to proceed with scanning
|
||||
// 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 */:
|
||||
value += scanNumber();
|
||||
return token = 11 /* NumericLiteral */;
|
||||
// literals and unknown symbols
|
||||
default:
|
||||
// is a literal? Read the full word.
|
||||
while (pos < len && isUnknownContentCharacter(code)) {
|
||||
pos++;
|
||||
code = text.charCodeAt(pos);
|
||||
}
|
||||
if (tokenOffset !== pos) {
|
||||
value = text.substring(tokenOffset, pos);
|
||||
// keywords: true, false, null
|
||||
switch (value) {
|
||||
case 'true': return token = 8 /* TrueKeyword */;
|
||||
case 'false': return token = 9 /* FalseKeyword */;
|
||||
case 'null': return token = 7 /* NullKeyword */;
|
||||
}
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
// some
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
}
|
||||
function isUnknownContentCharacter(code) {
|
||||
if (isWhiteSpace(code) || isLineBreak(code)) {
|
||||
return false;
|
||||
}
|
||||
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 */:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function scanNextNonTrivia() {
|
||||
var result;
|
||||
do {
|
||||
result = scanNext();
|
||||
} while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */);
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
setPosition: setPosition,
|
||||
getPosition: function () { return pos; },
|
||||
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
||||
getToken: function () { return token; },
|
||||
getTokenValue: function () { return value; },
|
||||
getTokenOffset: function () { return tokenOffset; },
|
||||
getTokenLength: function () { return pos - tokenOffset; },
|
||||
getTokenStartLine: function () { return lineStartOffset; },
|
||||
getTokenStartCharacter: function () { return tokenOffset - prevTokenLineStartOffset; },
|
||||
getTokenError: function () { return scanError; },
|
||||
};
|
||||
}
|
||||
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 */;
|
||||
}
|
||||
function isLineBreak(ch) {
|
||||
return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */;
|
||||
}
|
||||
function isDigit(ch) {
|
||||
return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
|
||||
}
|
||||
316
node_modules/jsonc-parser/lib/esm/main.d.ts
generated
vendored
Executable file
316
node_modules/jsonc-parser/lib/esm/main.d.ts
generated
vendored
Executable file
|
|
@ -0,0 +1,316 @@
|
|||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export declare const createScanner: (text: string, ignoreTrivia?: boolean) => JSONScanner;
|
||||
export declare const enum ScanError {
|
||||
None = 0,
|
||||
UnexpectedEndOfComment = 1,
|
||||
UnexpectedEndOfString = 2,
|
||||
UnexpectedEndOfNumber = 3,
|
||||
InvalidUnicode = 4,
|
||||
InvalidEscapeCharacter = 5,
|
||||
InvalidCharacter = 6
|
||||
}
|
||||
export declare const enum SyntaxKind {
|
||||
OpenBraceToken = 1,
|
||||
CloseBraceToken = 2,
|
||||
OpenBracketToken = 3,
|
||||
CloseBracketToken = 4,
|
||||
CommaToken = 5,
|
||||
ColonToken = 6,
|
||||
NullKeyword = 7,
|
||||
TrueKeyword = 8,
|
||||
FalseKeyword = 9,
|
||||
StringLiteral = 10,
|
||||
NumericLiteral = 11,
|
||||
LineCommentTrivia = 12,
|
||||
BlockCommentTrivia = 13,
|
||||
LineBreakTrivia = 14,
|
||||
Trivia = 15,
|
||||
Unknown = 16,
|
||||
EOF = 17
|
||||
}
|
||||
/**
|
||||
* The scanner object, representing a JSON scanner at a position in the input string.
|
||||
*/
|
||||
export interface JSONScanner {
|
||||
/**
|
||||
* Sets the scan position to a new offset. A call to 'scan' is needed to get the first token.
|
||||
*/
|
||||
setPosition(pos: number): void;
|
||||
/**
|
||||
* Read the next token. Returns the token code.
|
||||
*/
|
||||
scan(): SyntaxKind;
|
||||
/**
|
||||
* Returns the current scan position, which is after the last read token.
|
||||
*/
|
||||
getPosition(): number;
|
||||
/**
|
||||
* Returns the last read token.
|
||||
*/
|
||||
getToken(): SyntaxKind;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
getTokenOffset(): number;
|
||||
/**
|
||||
* The length of the last read token.
|
||||
*/
|
||||
getTokenLength(): number;
|
||||
/**
|
||||
* The zero-based start line number of the last read token.
|
||||
*/
|
||||
getTokenStartLine(): number;
|
||||
/**
|
||||
* The zero-based start character (column) of the last read token.
|
||||
*/
|
||||
getTokenStartCharacter(): number;
|
||||
/**
|
||||
* An error code of the last scan.
|
||||
*/
|
||||
getTokenError(): ScanError;
|
||||
}
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
export declare const getLocation: (text: string, position: number) => Location;
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore, always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
export declare const parse: (text: string, errors?: ParseError[], options?: ParseOptions) => any;
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
export declare const parseTree: (text: string, errors?: ParseError[], options?: ParseOptions) => Node | undefined;
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
export declare const findNodeAtLocation: (root: Node, path: JSONPath) => Node | undefined;
|
||||
/**
|
||||
* Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
export declare const findNodeAtOffset: (root: Node, offset: number, includeRightBound?: boolean) => Node | undefined;
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
export declare const getNodePath: (node: Node) => JSONPath;
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
export declare const getNodeValue: (node: Node) => any;
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
export declare const visit: (text: string, visitor: JSONVisitor, options?: ParseOptions) => any;
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
export declare const stripComments: (text: string, replaceCh?: string) => string;
|
||||
export interface ParseError {
|
||||
error: ParseErrorCode;
|
||||
offset: number;
|
||||
length: number;
|
||||
}
|
||||
export declare const enum ParseErrorCode {
|
||||
InvalidSymbol = 1,
|
||||
InvalidNumberFormat = 2,
|
||||
PropertyNameExpected = 3,
|
||||
ValueExpected = 4,
|
||||
ColonExpected = 5,
|
||||
CommaExpected = 6,
|
||||
CloseBraceExpected = 7,
|
||||
CloseBracketExpected = 8,
|
||||
EndOfFileExpected = 9,
|
||||
InvalidCommentToken = 10,
|
||||
UnexpectedEndOfComment = 11,
|
||||
UnexpectedEndOfString = 12,
|
||||
UnexpectedEndOfNumber = 13,
|
||||
InvalidUnicode = 14,
|
||||
InvalidEscapeCharacter = 15,
|
||||
InvalidCharacter = 16
|
||||
}
|
||||
export declare function printParseErrorCode(code: ParseErrorCode): "InvalidSymbol" | "InvalidNumberFormat" | "PropertyNameExpected" | "ValueExpected" | "ColonExpected" | "CommaExpected" | "CloseBraceExpected" | "CloseBracketExpected" | "EndOfFileExpected" | "InvalidCommentToken" | "UnexpectedEndOfComment" | "UnexpectedEndOfString" | "UnexpectedEndOfNumber" | "InvalidUnicode" | "InvalidEscapeCharacter" | "InvalidCharacter" | "<unknown ParseErrorCode>";
|
||||
export declare type NodeType = 'object' | 'array' | 'property' | 'string' | 'number' | 'boolean' | 'null';
|
||||
export interface Node {
|
||||
readonly type: NodeType;
|
||||
readonly value?: any;
|
||||
readonly offset: number;
|
||||
readonly length: number;
|
||||
readonly colonOffset?: number;
|
||||
readonly parent?: Node;
|
||||
readonly children?: Node[];
|
||||
}
|
||||
export declare type Segment = string | number;
|
||||
export declare type JSONPath = Segment[];
|
||||
export interface Location {
|
||||
/**
|
||||
* The previous property key or literal value (string, number, boolean or null) or undefined.
|
||||
*/
|
||||
previousNode?: Node;
|
||||
/**
|
||||
* The path describing the location in the JSON document. The path consists of a sequence of strings
|
||||
* representing an object property or numbers for array indices.
|
||||
*/
|
||||
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 sequence of segments of any property name or index, or no segment.
|
||||
*/
|
||||
matches: (patterns: JSONPath) => boolean;
|
||||
/**
|
||||
* If set, the location's offset is at a property key.
|
||||
*/
|
||||
isAtPropertyKey: boolean;
|
||||
}
|
||||
export interface ParseOptions {
|
||||
disallowComments?: boolean;
|
||||
allowTrailingComma?: boolean;
|
||||
allowEmptyContent?: boolean;
|
||||
}
|
||||
export interface JSONVisitor {
|
||||
/**
|
||||
* Invoked when an open brace is encountered and an object is started. The offset and length represent the location of the open brace.
|
||||
*/
|
||||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a property is encountered. The offset and length represent the location of the property name.
|
||||
*/
|
||||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace.
|
||||
*/
|
||||
onObjectEnd?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when an open bracket is encountered. The offset and length represent the location of the open bracket.
|
||||
*/
|
||||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket.
|
||||
*/
|
||||
onArrayEnd?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a literal value is encountered. The offset and length represent the location of the literal value.
|
||||
*/
|
||||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator.
|
||||
*/
|
||||
onSeparator?: (character: string, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* When comments are allowed, invoked when a line or block comment is encountered. The offset and length represent the location of the comment.
|
||||
*/
|
||||
onComment?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked on an error.
|
||||
*/
|
||||
onError?: (error: ParseErrorCode, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
/**
|
||||
* A text range in the document
|
||||
*/
|
||||
export interface Range {
|
||||
/**
|
||||
* The start offset of the range.
|
||||
*/
|
||||
offset: number;
|
||||
/**
|
||||
* The length of the range. Must not be negative.
|
||||
*/
|
||||
length: number;
|
||||
}
|
||||
export interface FormattingOptions {
|
||||
/**
|
||||
* If indentation is based on spaces (`insertSpaces` = true), the number of spaces that make an indent.
|
||||
*/
|
||||
tabSize?: number;
|
||||
/**
|
||||
* Is indentation based on spaces?
|
||||
*/
|
||||
insertSpaces?: boolean;
|
||||
/**
|
||||
* The default 'end of line' character. If not set, '\n' is used as default.
|
||||
*/
|
||||
eol?: string;
|
||||
/**
|
||||
* If set, will add a new line at the end of the document.
|
||||
*/
|
||||
insertFinalNewline?: boolean;
|
||||
}
|
||||
/**
|
||||
* Computes the edits needed to format a JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param range The range to format or `undefined` to format the full content
|
||||
* @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`.
|
||||
*/
|
||||
export declare function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[];
|
||||
/**
|
||||
* Options used when computing the modification edits
|
||||
*/
|
||||
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 {@property isArrayInsertion} is `true`, then
|
||||
* {@function 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;
|
||||
}
|
||||
/**
|
||||
* Computes the edits needed to modify a value in the JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param path The path of the value to change. The path represents either to the document root, a property or an array item.
|
||||
* If the path points to an non-existing property or item, it will be created.
|
||||
* @param value The new value for the specified property or item. If the value is undefined,
|
||||
* the property or item will be removed.
|
||||
* @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`.
|
||||
*/
|
||||
export declare function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): Edit[];
|
||||
/**
|
||||
* Applies edits to a input string.
|
||||
*/
|
||||
export declare function applyEdits(text: string, edits: Edit[]): string;
|
||||
116
node_modules/jsonc-parser/lib/esm/main.js
generated
vendored
Executable file
116
node_modules/jsonc-parser/lib/esm/main.js
generated
vendored
Executable file
|
|
@ -0,0 +1,116 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import * as formatter from './impl/format';
|
||||
import * as edit from './impl/edit';
|
||||
import * as scanner from './impl/scanner';
|
||||
import * as parser from './impl/parser';
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export var createScanner = scanner.createScanner;
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
export var getLocation = parser.getLocation;
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore, always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
export var parse = parser.parse;
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
export var parseTree = parser.parseTree;
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
export var findNodeAtLocation = parser.findNodeAtLocation;
|
||||
/**
|
||||
* Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
export var findNodeAtOffset = parser.findNodeAtOffset;
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
export var getNodePath = parser.getNodePath;
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
export var getNodeValue = parser.getNodeValue;
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
export var visit = parser.visit;
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
export var stripComments = parser.stripComments;
|
||||
export function printParseErrorCode(code) {
|
||||
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';
|
||||
}
|
||||
return '<unknown ParseErrorCode>';
|
||||
}
|
||||
/**
|
||||
* Computes the edits needed to format a JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param range The range to format or `undefined` to format the full content
|
||||
* @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`.
|
||||
*/
|
||||
export function format(documentText, range, options) {
|
||||
return formatter.format(documentText, range, options);
|
||||
}
|
||||
/**
|
||||
* Computes the edits needed to modify a value in the JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param path The path of the value to change. The path represents either to the document root, a property or an array item.
|
||||
* If the path points to an non-existing property or item, it will be created.
|
||||
* @param value The new value for the specified property or item. If the value is undefined,
|
||||
* the property or item will be removed.
|
||||
* @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`.
|
||||
*/
|
||||
export function modify(text, path, value, options) {
|
||||
return edit.setProperty(text, path, value, options);
|
||||
}
|
||||
/**
|
||||
* Applies edits to a input string.
|
||||
*/
|
||||
export function applyEdits(text, edits) {
|
||||
for (var i = edits.length - 1; i >= 0; i--) {
|
||||
text = edit.applyEdit(text, edits[i]);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
202
node_modules/jsonc-parser/lib/umd/impl/edit.js
generated
vendored
Executable file
202
node_modules/jsonc-parser/lib/umd/impl/edit.js
generated
vendored
Executable file
|
|
@ -0,0 +1,202 @@
|
|||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports", "./format", "./parser"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isWS = exports.applyEdit = exports.setProperty = exports.removeProperty = void 0;
|
||||
var format_1 = require("./format");
|
||||
var parser_1 = require("./parser");
|
||||
function removeProperty(text, path, options) {
|
||||
return setProperty(text, path, void 0, options);
|
||||
}
|
||||
exports.removeProperty = removeProperty;
|
||||
function setProperty(text, originalPath, value, options) {
|
||||
var _a;
|
||||
var path = originalPath.slice();
|
||||
var errors = [];
|
||||
var root = parser_1.parseTree(text, errors);
|
||||
var parent = void 0;
|
||||
var lastSegment = void 0;
|
||||
while (path.length > 0) {
|
||||
lastSegment = path.pop();
|
||||
parent = parser_1.findNodeAtLocation(root, path);
|
||||
if (parent === void 0 && value !== void 0) {
|
||||
if (typeof lastSegment === 'string') {
|
||||
value = (_a = {}, _a[lastSegment] = value, _a);
|
||||
}
|
||||
else {
|
||||
value = [value];
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!parent) {
|
||||
// empty document
|
||||
if (value === void 0) { // delete
|
||||
throw new Error('Can not delete in empty document');
|
||||
}
|
||||
return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);
|
||||
}
|
||||
else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
|
||||
var existing = parser_1.findNodeAtLocation(parent, [lastSegment]);
|
||||
if (existing !== void 0) {
|
||||
if (value === void 0) { // delete
|
||||
if (!existing.parent) {
|
||||
throw new Error('Malformed AST');
|
||||
}
|
||||
var propertyIndex = parent.children.indexOf(existing.parent);
|
||||
var removeBegin = void 0;
|
||||
var removeEnd = existing.parent.offset + existing.parent.length;
|
||||
if (propertyIndex > 0) {
|
||||
// remove the comma of the previous node
|
||||
var previous = parent.children[propertyIndex - 1];
|
||||
removeBegin = previous.offset + previous.length;
|
||||
}
|
||||
else {
|
||||
removeBegin = parent.offset + 1;
|
||||
if (parent.children.length > 1) {
|
||||
// remove the comma of the next node
|
||||
var next = parent.children[1];
|
||||
removeEnd = next.offset;
|
||||
}
|
||||
}
|
||||
return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, options);
|
||||
}
|
||||
else {
|
||||
// set value of existing property
|
||||
return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value === void 0) { // delete
|
||||
return []; // property does not exist, nothing to do
|
||||
}
|
||||
var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value);
|
||||
var index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length;
|
||||
var edit = void 0;
|
||||
if (index > 0) {
|
||||
var previous = parent.children[index - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
||||
}
|
||||
else if (parent.children.length === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
||||
}
|
||||
else {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
}
|
||||
else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
|
||||
var insertIndex = lastSegment;
|
||||
if (insertIndex === -1) {
|
||||
// Insert
|
||||
var newProperty = "" + JSON.stringify(value);
|
||||
var edit = void 0;
|
||||
if (parent.children.length === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
||||
}
|
||||
else {
|
||||
var previous = parent.children[parent.children.length - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
else if (value === void 0 && parent.children.length >= 0) {
|
||||
// Removal
|
||||
var removalIndex = lastSegment;
|
||||
var toRemove = parent.children[removalIndex];
|
||||
var edit = void 0;
|
||||
if (parent.children.length === 1) {
|
||||
// only item
|
||||
edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
|
||||
}
|
||||
else if (parent.children.length - 1 === removalIndex) {
|
||||
// last item
|
||||
var previous = parent.children[removalIndex - 1];
|
||||
var offset = previous.offset + previous.length;
|
||||
var parentEndOffset = parent.offset + parent.length;
|
||||
edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' };
|
||||
}
|
||||
else {
|
||||
edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
else if (value !== void 0) {
|
||||
var edit = void 0;
|
||||
var newProperty = "" + JSON.stringify(value);
|
||||
if (!options.isArrayInsertion && parent.children.length > lastSegment) {
|
||||
var toModify = parent.children[lastSegment];
|
||||
edit = { offset: toModify.offset, length: toModify.length, content: newProperty };
|
||||
}
|
||||
else if (parent.children.length === 0 || lastSegment === 0) {
|
||||
edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + ',' };
|
||||
}
|
||||
else {
|
||||
var index = lastSegment > parent.children.length ? parent.children.length : lastSegment;
|
||||
var previous = parent.children[index - 1];
|
||||
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
||||
}
|
||||
return withFormatting(text, edit, options);
|
||||
}
|
||||
else {
|
||||
throw new Error("Can not " + (value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')) + " Array index " + insertIndex + " as length is not sufficient");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type);
|
||||
}
|
||||
}
|
||||
exports.setProperty = setProperty;
|
||||
function withFormatting(text, edit, options) {
|
||||
if (!options.formattingOptions) {
|
||||
return [edit];
|
||||
}
|
||||
// apply the edit
|
||||
var newText = applyEdit(text, edit);
|
||||
// format the new text
|
||||
var begin = edit.offset;
|
||||
var end = edit.offset + edit.content.length;
|
||||
if (edit.length === 0 || edit.content.length === 0) { // insert or remove
|
||||
while (begin > 0 && !format_1.isEOL(newText, begin - 1)) {
|
||||
begin--;
|
||||
}
|
||||
while (end < newText.length && !format_1.isEOL(newText, end)) {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
var edits = format_1.format(newText, { offset: begin, length: end - begin }, options.formattingOptions);
|
||||
// apply the formatting edits and track the begin and end offsets of the changes
|
||||
for (var i = edits.length - 1; i >= 0; i--) {
|
||||
var edit_1 = edits[i];
|
||||
newText = applyEdit(newText, edit_1);
|
||||
begin = Math.min(begin, edit_1.offset);
|
||||
end = Math.max(end, edit_1.offset + edit_1.length);
|
||||
end += edit_1.content.length - edit_1.length;
|
||||
}
|
||||
// create a single edit with all changes
|
||||
var editLength = text.length - (newText.length - end) - begin;
|
||||
return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
|
||||
}
|
||||
function applyEdit(text, edit) {
|
||||
return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
|
||||
}
|
||||
exports.applyEdit = applyEdit;
|
||||
function isWS(text, offset) {
|
||||
return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
exports.isWS = isWS;
|
||||
});
|
||||
219
node_modules/jsonc-parser/lib/umd/impl/format.js
generated
vendored
Executable file
219
node_modules/jsonc-parser/lib/umd/impl/format.js
generated
vendored
Executable file
|
|
@ -0,0 +1,219 @@
|
|||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports", "./scanner"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isEOL = exports.format = void 0;
|
||||
var scanner_1 = require("./scanner");
|
||||
function format(documentText, range, options) {
|
||||
var initialIndentLevel;
|
||||
var formatText;
|
||||
var formatTextStart;
|
||||
var rangeStart;
|
||||
var rangeEnd;
|
||||
if (range) {
|
||||
rangeStart = range.offset;
|
||||
rangeEnd = rangeStart + range.length;
|
||||
formatTextStart = rangeStart;
|
||||
while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
|
||||
formatTextStart--;
|
||||
}
|
||||
var endOffset = rangeEnd;
|
||||
while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
|
||||
endOffset++;
|
||||
}
|
||||
formatText = documentText.substring(formatTextStart, endOffset);
|
||||
initialIndentLevel = computeIndentLevel(formatText, options);
|
||||
}
|
||||
else {
|
||||
formatText = documentText;
|
||||
initialIndentLevel = 0;
|
||||
formatTextStart = 0;
|
||||
rangeStart = 0;
|
||||
rangeEnd = documentText.length;
|
||||
}
|
||||
var eol = getEOL(options, documentText);
|
||||
var lineBreak = false;
|
||||
var indentLevel = 0;
|
||||
var indentValue;
|
||||
if (options.insertSpaces) {
|
||||
indentValue = repeat(' ', options.tabSize || 4);
|
||||
}
|
||||
else {
|
||||
indentValue = '\t';
|
||||
}
|
||||
var scanner = scanner_1.createScanner(formatText, false);
|
||||
var hasError = false;
|
||||
function newLineAndIndent() {
|
||||
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 */);
|
||||
token = scanner.scan();
|
||||
}
|
||||
hasError = token === 16 /* Unknown */ || scanner.getTokenError() !== 0 /* None */;
|
||||
return token;
|
||||
}
|
||||
var editOperations = [];
|
||||
function addEdit(text, startOffset, endOffset) {
|
||||
if (!hasError && (!range || (startOffset < rangeEnd && endOffset > rangeStart)) && documentText.substring(startOffset, endOffset) !== text) {
|
||||
editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
|
||||
}
|
||||
}
|
||||
var firstToken = scanNext();
|
||||
if (firstToken !== 17 /* EOF */) {
|
||||
var firstTokenStart = scanner.getTokenOffset() + formatTextStart;
|
||||
var initialIndent = repeat(indentValue, initialIndentLevel);
|
||||
addEdit(initialIndent, formatTextStart, firstTokenStart);
|
||||
}
|
||||
while (firstToken !== 17 /* EOF */) {
|
||||
var firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
|
||||
var secondToken = scanNext();
|
||||
var replaceContent = '';
|
||||
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
|
||||
var commentTokenStart = scanner.getTokenOffset() + formatTextStart;
|
||||
addEdit(' ', firstTokenEnd, commentTokenStart);
|
||||
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
|
||||
needsLineBreak = secondToken === 12 /* LineCommentTrivia */;
|
||||
replaceContent = needsLineBreak ? newLineAndIndent() : '';
|
||||
secondToken = scanNext();
|
||||
}
|
||||
if (secondToken === 2 /* CloseBraceToken */) {
|
||||
if (firstToken !== 1 /* OpenBraceToken */) {
|
||||
indentLevel--;
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
}
|
||||
else if (secondToken === 4 /* CloseBracketToken */) {
|
||||
if (firstToken !== 3 /* OpenBracketToken */) {
|
||||
indentLevel--;
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (firstToken) {
|
||||
case 3 /* OpenBracketToken */:
|
||||
case 1 /* OpenBraceToken */:
|
||||
indentLevel++;
|
||||
replaceContent = newLineAndIndent();
|
||||
break;
|
||||
case 5 /* CommaToken */:
|
||||
case 12 /* LineCommentTrivia */:
|
||||
replaceContent = newLineAndIndent();
|
||||
break;
|
||||
case 13 /* BlockCommentTrivia */:
|
||||
if (lineBreak) {
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
else if (!needsLineBreak) {
|
||||
// symbol following comment on the same line: keep on same line, separate with ' '
|
||||
replaceContent = ' ';
|
||||
}
|
||||
break;
|
||||
case 6 /* ColonToken */:
|
||||
if (!needsLineBreak) {
|
||||
replaceContent = ' ';
|
||||
}
|
||||
break;
|
||||
case 10 /* StringLiteral */:
|
||||
if (secondToken === 6 /* ColonToken */) {
|
||||
if (!needsLineBreak) {
|
||||
replaceContent = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
// 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) {
|
||||
replaceContent = ' ';
|
||||
}
|
||||
}
|
||||
else if (secondToken !== 5 /* CommaToken */ && secondToken !== 17 /* EOF */) {
|
||||
hasError = true;
|
||||
}
|
||||
break;
|
||||
case 16 /* Unknown */:
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
if (lineBreak && (secondToken === 12 /* LineCommentTrivia */ || secondToken === 13 /* BlockCommentTrivia */)) {
|
||||
replaceContent = newLineAndIndent();
|
||||
}
|
||||
}
|
||||
if (secondToken === 17 /* EOF */) {
|
||||
replaceContent = options.insertFinalNewline ? eol : '';
|
||||
}
|
||||
var secondTokenStart = scanner.getTokenOffset() + formatTextStart;
|
||||
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
|
||||
firstToken = secondToken;
|
||||
}
|
||||
return editOperations;
|
||||
}
|
||||
exports.format = format;
|
||||
function repeat(s, count) {
|
||||
var result = '';
|
||||
for (var i = 0; i < count; i++) {
|
||||
result += s;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function computeIndentLevel(content, options) {
|
||||
var i = 0;
|
||||
var nChars = 0;
|
||||
var tabSize = options.tabSize || 4;
|
||||
while (i < content.length) {
|
||||
var ch = content.charAt(i);
|
||||
if (ch === ' ') {
|
||||
nChars++;
|
||||
}
|
||||
else if (ch === '\t') {
|
||||
nChars += tabSize;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return Math.floor(nChars / tabSize);
|
||||
}
|
||||
function getEOL(options, text) {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
var ch = text.charAt(i);
|
||||
if (ch === '\r') {
|
||||
if (i + 1 < text.length && text.charAt(i + 1) === '\n') {
|
||||
return '\r\n';
|
||||
}
|
||||
return '\r';
|
||||
}
|
||||
else if (ch === '\n') {
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
return (options && options.eol) || '\n';
|
||||
}
|
||||
function isEOL(text, offset) {
|
||||
return '\r\n'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
exports.isEOL = isEOL;
|
||||
});
|
||||
644
node_modules/jsonc-parser/lib/umd/impl/parser.js
generated
vendored
Executable file
644
node_modules/jsonc-parser/lib/umd/impl/parser.js
generated
vendored
Executable file
|
|
@ -0,0 +1,644 @@
|
|||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports", "./scanner"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getNodeType = exports.stripComments = exports.visit = exports.findNodeAtOffset = exports.contains = exports.getNodeValue = exports.getNodePath = exports.findNodeAtLocation = exports.parseTree = exports.parse = exports.getLocation = void 0;
|
||||
var scanner_1 = require("./scanner");
|
||||
var ParseOptions;
|
||||
(function (ParseOptions) {
|
||||
ParseOptions.DEFAULT = {
|
||||
allowTrailingComma: false
|
||||
};
|
||||
})(ParseOptions || (ParseOptions = {}));
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
function getLocation(text, position) {
|
||||
var segments = []; // strings or numbers
|
||||
var earlyReturnException = new Object();
|
||||
var previousNode = undefined;
|
||||
var previousNodeInst = {
|
||||
value: {},
|
||||
offset: 0,
|
||||
length: 0,
|
||||
type: 'object',
|
||||
parent: undefined
|
||||
};
|
||||
var isAtPropertyKey = false;
|
||||
function setPreviousNode(value, offset, length, type) {
|
||||
previousNodeInst.value = value;
|
||||
previousNodeInst.offset = offset;
|
||||
previousNodeInst.length = length;
|
||||
previousNodeInst.type = type;
|
||||
previousNodeInst.colonOffset = undefined;
|
||||
previousNode = previousNodeInst;
|
||||
}
|
||||
try {
|
||||
visit(text, {
|
||||
onObjectBegin: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
isAtPropertyKey = position > offset;
|
||||
segments.push(''); // push a placeholder (will be replaced)
|
||||
},
|
||||
onObjectProperty: function (name, offset, length) {
|
||||
if (position < offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
setPreviousNode(name, offset, length, 'property');
|
||||
segments[segments.length - 1] = name;
|
||||
if (position <= offset + length) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
},
|
||||
onObjectEnd: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
segments.pop();
|
||||
},
|
||||
onArrayBegin: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
segments.push(0);
|
||||
},
|
||||
onArrayEnd: function (offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
previousNode = undefined;
|
||||
segments.pop();
|
||||
},
|
||||
onLiteralValue: function (value, offset, length) {
|
||||
if (position < offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
setPreviousNode(value, offset, length, getNodeType(value));
|
||||
if (position <= offset + length) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
},
|
||||
onSeparator: function (sep, offset, length) {
|
||||
if (position <= offset) {
|
||||
throw earlyReturnException;
|
||||
}
|
||||
if (sep === ':' && previousNode && previousNode.type === 'property') {
|
||||
previousNode.colonOffset = offset;
|
||||
isAtPropertyKey = false;
|
||||
previousNode = undefined;
|
||||
}
|
||||
else if (sep === ',') {
|
||||
var last = segments[segments.length - 1];
|
||||
if (typeof last === 'number') {
|
||||
segments[segments.length - 1] = last + 1;
|
||||
}
|
||||
else {
|
||||
isAtPropertyKey = true;
|
||||
segments[segments.length - 1] = '';
|
||||
}
|
||||
previousNode = undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
if (e !== earlyReturnException) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return {
|
||||
path: segments,
|
||||
previousNode: previousNode,
|
||||
isAtPropertyKey: isAtPropertyKey,
|
||||
matches: function (pattern) {
|
||||
var k = 0;
|
||||
for (var i = 0; k < pattern.length && i < segments.length; i++) {
|
||||
if (pattern[k] === segments[i] || pattern[k] === '*') {
|
||||
k++;
|
||||
}
|
||||
else if (pattern[k] !== '**') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return k === pattern.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.getLocation = getLocation;
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
function parse(text, errors, options) {
|
||||
if (errors === void 0) { errors = []; }
|
||||
if (options === void 0) { options = ParseOptions.DEFAULT; }
|
||||
var currentProperty = null;
|
||||
var currentParent = [];
|
||||
var previousParents = [];
|
||||
function onValue(value) {
|
||||
if (Array.isArray(currentParent)) {
|
||||
currentParent.push(value);
|
||||
}
|
||||
else if (currentProperty !== null) {
|
||||
currentParent[currentProperty] = value;
|
||||
}
|
||||
}
|
||||
var visitor = {
|
||||
onObjectBegin: function () {
|
||||
var object = {};
|
||||
onValue(object);
|
||||
previousParents.push(currentParent);
|
||||
currentParent = object;
|
||||
currentProperty = null;
|
||||
},
|
||||
onObjectProperty: function (name) {
|
||||
currentProperty = name;
|
||||
},
|
||||
onObjectEnd: function () {
|
||||
currentParent = previousParents.pop();
|
||||
},
|
||||
onArrayBegin: function () {
|
||||
var array = [];
|
||||
onValue(array);
|
||||
previousParents.push(currentParent);
|
||||
currentParent = array;
|
||||
currentProperty = null;
|
||||
},
|
||||
onArrayEnd: function () {
|
||||
currentParent = previousParents.pop();
|
||||
},
|
||||
onLiteralValue: onValue,
|
||||
onError: function (error, offset, length) {
|
||||
errors.push({ error: error, offset: offset, length: length });
|
||||
}
|
||||
};
|
||||
visit(text, visitor, options);
|
||||
return currentParent[0];
|
||||
}
|
||||
exports.parse = parse;
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
function parseTree(text, errors, options) {
|
||||
if (errors === void 0) { errors = []; }
|
||||
if (options === void 0) { options = ParseOptions.DEFAULT; }
|
||||
var currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root
|
||||
function ensurePropertyComplete(endOffset) {
|
||||
if (currentParent.type === 'property') {
|
||||
currentParent.length = endOffset - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
}
|
||||
}
|
||||
function onValue(valueNode) {
|
||||
currentParent.children.push(valueNode);
|
||||
return valueNode;
|
||||
}
|
||||
var visitor = {
|
||||
onObjectBegin: function (offset) {
|
||||
currentParent = onValue({ type: 'object', offset: offset, length: -1, parent: currentParent, children: [] });
|
||||
},
|
||||
onObjectProperty: function (name, offset, length) {
|
||||
currentParent = onValue({ type: 'property', offset: offset, length: -1, parent: currentParent, children: [] });
|
||||
currentParent.children.push({ type: 'string', value: name, offset: offset, length: length, parent: currentParent });
|
||||
},
|
||||
onObjectEnd: function (offset, length) {
|
||||
ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete
|
||||
currentParent.length = offset + length - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
ensurePropertyComplete(offset + length);
|
||||
},
|
||||
onArrayBegin: function (offset, length) {
|
||||
currentParent = onValue({ type: 'array', offset: offset, length: -1, parent: currentParent, children: [] });
|
||||
},
|
||||
onArrayEnd: function (offset, length) {
|
||||
currentParent.length = offset + length - currentParent.offset;
|
||||
currentParent = currentParent.parent;
|
||||
ensurePropertyComplete(offset + length);
|
||||
},
|
||||
onLiteralValue: function (value, offset, length) {
|
||||
onValue({ type: getNodeType(value), offset: offset, length: length, parent: currentParent, value: value });
|
||||
ensurePropertyComplete(offset + length);
|
||||
},
|
||||
onSeparator: function (sep, offset, length) {
|
||||
if (currentParent.type === 'property') {
|
||||
if (sep === ':') {
|
||||
currentParent.colonOffset = offset;
|
||||
}
|
||||
else if (sep === ',') {
|
||||
ensurePropertyComplete(offset);
|
||||
}
|
||||
}
|
||||
},
|
||||
onError: function (error, offset, length) {
|
||||
errors.push({ error: error, offset: offset, length: length });
|
||||
}
|
||||
};
|
||||
visit(text, visitor, options);
|
||||
var result = currentParent.children[0];
|
||||
if (result) {
|
||||
delete result.parent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.parseTree = parseTree;
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
function findNodeAtLocation(root, path) {
|
||||
if (!root) {
|
||||
return undefined;
|
||||
}
|
||||
var node = root;
|
||||
for (var _i = 0, path_1 = path; _i < path_1.length; _i++) {
|
||||
var segment = path_1[_i];
|
||||
if (typeof segment === 'string') {
|
||||
if (node.type !== 'object' || !Array.isArray(node.children)) {
|
||||
return undefined;
|
||||
}
|
||||
var found = false;
|
||||
for (var _a = 0, _b = node.children; _a < _b.length; _a++) {
|
||||
var propertyNode = _b[_a];
|
||||
if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment) {
|
||||
node = propertyNode.children[1];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var index = segment;
|
||||
if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {
|
||||
return undefined;
|
||||
}
|
||||
node = node.children[index];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
exports.findNodeAtLocation = findNodeAtLocation;
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
function getNodePath(node) {
|
||||
if (!node.parent || !node.parent.children) {
|
||||
return [];
|
||||
}
|
||||
var path = getNodePath(node.parent);
|
||||
if (node.parent.type === 'property') {
|
||||
var key = node.parent.children[0].value;
|
||||
path.push(key);
|
||||
}
|
||||
else if (node.parent.type === 'array') {
|
||||
var index = node.parent.children.indexOf(node);
|
||||
if (index !== -1) {
|
||||
path.push(index);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
exports.getNodePath = getNodePath;
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
function getNodeValue(node) {
|
||||
switch (node.type) {
|
||||
case 'array':
|
||||
return node.children.map(getNodeValue);
|
||||
case 'object':
|
||||
var obj = Object.create(null);
|
||||
for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
|
||||
var prop = _a[_i];
|
||||
var valueNode = prop.children[1];
|
||||
if (valueNode) {
|
||||
obj[prop.children[0].value] = getNodeValue(valueNode);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
case 'null':
|
||||
case 'string':
|
||||
case 'number':
|
||||
case 'boolean':
|
||||
return node.value;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
exports.getNodeValue = getNodeValue;
|
||||
function contains(node, offset, includeRightBound) {
|
||||
if (includeRightBound === void 0) { includeRightBound = false; }
|
||||
return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));
|
||||
}
|
||||
exports.contains = contains;
|
||||
/**
|
||||
* Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
function findNodeAtOffset(node, offset, includeRightBound) {
|
||||
if (includeRightBound === void 0) { includeRightBound = false; }
|
||||
if (contains(node, offset, includeRightBound)) {
|
||||
var children = node.children;
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length && children[i].offset <= offset; i++) {
|
||||
var item = findNodeAtOffset(children[i], offset, includeRightBound);
|
||||
if (item) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
exports.findNodeAtOffset = findNodeAtOffset;
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
function visit(text, visitor, options) {
|
||||
if (options === void 0) { options = ParseOptions.DEFAULT; }
|
||||
var _scanner = scanner_1.createScanner(text, false);
|
||||
function toNoArgVisit(visitFunction) {
|
||||
return visitFunction ? function () { return visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()); } : 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);
|
||||
var disallowComments = options && options.disallowComments;
|
||||
var allowTrailingComma = options && options.allowTrailingComma;
|
||||
function scanNext() {
|
||||
while (true) {
|
||||
var token = _scanner.scan();
|
||||
switch (_scanner.getTokenError()) {
|
||||
case 4 /* InvalidUnicode */:
|
||||
handleError(14 /* InvalidUnicode */);
|
||||
break;
|
||||
case 5 /* InvalidEscapeCharacter */:
|
||||
handleError(15 /* InvalidEscapeCharacter */);
|
||||
break;
|
||||
case 3 /* UnexpectedEndOfNumber */:
|
||||
handleError(13 /* UnexpectedEndOfNumber */);
|
||||
break;
|
||||
case 1 /* UnexpectedEndOfComment */:
|
||||
if (!disallowComments) {
|
||||
handleError(11 /* UnexpectedEndOfComment */);
|
||||
}
|
||||
break;
|
||||
case 2 /* UnexpectedEndOfString */:
|
||||
handleError(12 /* UnexpectedEndOfString */);
|
||||
break;
|
||||
case 6 /* InvalidCharacter */:
|
||||
handleError(16 /* InvalidCharacter */);
|
||||
break;
|
||||
}
|
||||
switch (token) {
|
||||
case 12 /* LineCommentTrivia */:
|
||||
case 13 /* BlockCommentTrivia */:
|
||||
if (disallowComments) {
|
||||
handleError(10 /* InvalidCommentToken */);
|
||||
}
|
||||
else {
|
||||
onComment();
|
||||
}
|
||||
break;
|
||||
case 16 /* Unknown */:
|
||||
handleError(1 /* InvalidSymbol */);
|
||||
break;
|
||||
case 15 /* Trivia */:
|
||||
case 14 /* LineBreakTrivia */:
|
||||
break;
|
||||
default:
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
function handleError(error, skipUntilAfter, skipUntil) {
|
||||
if (skipUntilAfter === void 0) { skipUntilAfter = []; }
|
||||
if (skipUntil === void 0) { skipUntil = []; }
|
||||
onError(error);
|
||||
if (skipUntilAfter.length + skipUntil.length > 0) {
|
||||
var token = _scanner.getToken();
|
||||
while (token !== 17 /* EOF */) {
|
||||
if (skipUntilAfter.indexOf(token) !== -1) {
|
||||
scanNext();
|
||||
break;
|
||||
}
|
||||
else if (skipUntil.indexOf(token) !== -1) {
|
||||
break;
|
||||
}
|
||||
token = scanNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
function parseString(isValue) {
|
||||
var value = _scanner.getTokenValue();
|
||||
if (isValue) {
|
||||
onLiteralValue(value);
|
||||
}
|
||||
else {
|
||||
onObjectProperty(value);
|
||||
}
|
||||
scanNext();
|
||||
return true;
|
||||
}
|
||||
function parseLiteral() {
|
||||
switch (_scanner.getToken()) {
|
||||
case 11 /* NumericLiteral */:
|
||||
var tokenValue = _scanner.getTokenValue();
|
||||
var value = Number(tokenValue);
|
||||
if (isNaN(value)) {
|
||||
handleError(2 /* InvalidNumberFormat */);
|
||||
value = 0;
|
||||
}
|
||||
onLiteralValue(value);
|
||||
break;
|
||||
case 7 /* NullKeyword */:
|
||||
onLiteralValue(null);
|
||||
break;
|
||||
case 8 /* TrueKeyword */:
|
||||
onLiteralValue(true);
|
||||
break;
|
||||
case 9 /* FalseKeyword */:
|
||||
onLiteralValue(false);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
scanNext();
|
||||
return true;
|
||||
}
|
||||
function parseProperty() {
|
||||
if (_scanner.getToken() !== 10 /* StringLiteral */) {
|
||||
handleError(3 /* PropertyNameExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
return false;
|
||||
}
|
||||
parseString(false);
|
||||
if (_scanner.getToken() === 6 /* ColonToken */) {
|
||||
onSeparator(':');
|
||||
scanNext(); // consume colon
|
||||
if (!parseValue()) {
|
||||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
handleError(5 /* ColonExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function parseObject() {
|
||||
onObjectBegin();
|
||||
scanNext(); // consume open brace
|
||||
var needsComma = false;
|
||||
while (_scanner.getToken() !== 2 /* CloseBraceToken */ && _scanner.getToken() !== 17 /* EOF */) {
|
||||
if (_scanner.getToken() === 5 /* CommaToken */) {
|
||||
if (!needsComma) {
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
}
|
||||
onSeparator(',');
|
||||
scanNext(); // consume comma
|
||||
if (_scanner.getToken() === 2 /* CloseBraceToken */ && allowTrailingComma) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (needsComma) {
|
||||
handleError(6 /* CommaExpected */, [], []);
|
||||
}
|
||||
if (!parseProperty()) {
|
||||
handleError(4 /* ValueExpected */, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
needsComma = true;
|
||||
}
|
||||
onObjectEnd();
|
||||
if (_scanner.getToken() !== 2 /* CloseBraceToken */) {
|
||||
handleError(7 /* CloseBraceExpected */, [2 /* CloseBraceToken */], []);
|
||||
}
|
||||
else {
|
||||
scanNext(); // consume close brace
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function parseArray() {
|
||||
onArrayBegin();
|
||||
scanNext(); // consume open bracket
|
||||
var needsComma = false;
|
||||
while (_scanner.getToken() !== 4 /* CloseBracketToken */ && _scanner.getToken() !== 17 /* EOF */) {
|
||||
if (_scanner.getToken() === 5 /* CommaToken */) {
|
||||
if (!needsComma) {
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
}
|
||||
onSeparator(',');
|
||||
scanNext(); // consume comma
|
||||
if (_scanner.getToken() === 4 /* CloseBracketToken */ && allowTrailingComma) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (needsComma) {
|
||||
handleError(6 /* CommaExpected */, [], []);
|
||||
}
|
||||
if (!parseValue()) {
|
||||
handleError(4 /* ValueExpected */, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]);
|
||||
}
|
||||
needsComma = true;
|
||||
}
|
||||
onArrayEnd();
|
||||
if (_scanner.getToken() !== 4 /* CloseBracketToken */) {
|
||||
handleError(8 /* CloseBracketExpected */, [4 /* CloseBracketToken */], []);
|
||||
}
|
||||
else {
|
||||
scanNext(); // consume close bracket
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function parseValue() {
|
||||
switch (_scanner.getToken()) {
|
||||
case 3 /* OpenBracketToken */:
|
||||
return parseArray();
|
||||
case 1 /* OpenBraceToken */:
|
||||
return parseObject();
|
||||
case 10 /* StringLiteral */:
|
||||
return parseString(true);
|
||||
default:
|
||||
return parseLiteral();
|
||||
}
|
||||
}
|
||||
scanNext();
|
||||
if (_scanner.getToken() === 17 /* EOF */) {
|
||||
if (options.allowEmptyContent) {
|
||||
return true;
|
||||
}
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
return false;
|
||||
}
|
||||
if (!parseValue()) {
|
||||
handleError(4 /* ValueExpected */, [], []);
|
||||
return false;
|
||||
}
|
||||
if (_scanner.getToken() !== 17 /* EOF */) {
|
||||
handleError(9 /* EndOfFileExpected */, [], []);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.visit = visit;
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
function stripComments(text, replaceCh) {
|
||||
var _scanner = scanner_1.createScanner(text), parts = [], kind, offset = 0, pos;
|
||||
do {
|
||||
pos = _scanner.getPosition();
|
||||
kind = _scanner.scan();
|
||||
switch (kind) {
|
||||
case 12 /* LineCommentTrivia */:
|
||||
case 13 /* BlockCommentTrivia */:
|
||||
case 17 /* EOF */:
|
||||
if (offset !== pos) {
|
||||
parts.push(text.substring(offset, pos));
|
||||
}
|
||||
if (replaceCh !== undefined) {
|
||||
parts.push(_scanner.getTokenValue().replace(/[^\r\n]/g, replaceCh));
|
||||
}
|
||||
offset = _scanner.getPosition();
|
||||
break;
|
||||
}
|
||||
} while (kind !== 17 /* EOF */);
|
||||
return parts.join('');
|
||||
}
|
||||
exports.stripComments = stripComments;
|
||||
function getNodeType(value) {
|
||||
switch (typeof value) {
|
||||
case 'boolean': return 'boolean';
|
||||
case 'number': return 'number';
|
||||
case 'string': return 'string';
|
||||
case 'object': {
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
else if (Array.isArray(value)) {
|
||||
return 'array';
|
||||
}
|
||||
return 'object';
|
||||
}
|
||||
default: return 'null';
|
||||
}
|
||||
}
|
||||
exports.getNodeType = getNodeType;
|
||||
});
|
||||
376
node_modules/jsonc-parser/lib/umd/impl/scanner.js
generated
vendored
Executable file
376
node_modules/jsonc-parser/lib/umd/impl/scanner.js
generated
vendored
Executable file
|
|
@ -0,0 +1,376 @@
|
|||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createScanner = void 0;
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
function createScanner(text, ignoreTrivia) {
|
||||
if (ignoreTrivia === void 0) { ignoreTrivia = false; }
|
||||
var len = text.length;
|
||||
var pos = 0, value = '', tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */;
|
||||
function scanHexDigits(count, exact) {
|
||||
var digits = 0;
|
||||
var value = 0;
|
||||
while (digits < count || !exact) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
|
||||
value = value * 16 + ch - 48 /* _0 */;
|
||||
}
|
||||
else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
|
||||
value = value * 16 + ch - 65 /* A */ + 10;
|
||||
}
|
||||
else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
|
||||
value = value * 16 + ch - 97 /* a */ + 10;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
digits++;
|
||||
}
|
||||
if (digits < count) {
|
||||
value = -1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function setPosition(newPosition) {
|
||||
pos = newPosition;
|
||||
value = '';
|
||||
tokenOffset = 0;
|
||||
token = 16 /* Unknown */;
|
||||
scanError = 0 /* None */;
|
||||
}
|
||||
function scanNumber() {
|
||||
var start = pos;
|
||||
if (text.charCodeAt(pos) === 48 /* _0 */) {
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) {
|
||||
pos++;
|
||||
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scanError = 3 /* UnexpectedEndOfNumber */;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
}
|
||||
var end = pos;
|
||||
if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) {
|
||||
pos++;
|
||||
if (pos < text.length && text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) {
|
||||
pos++;
|
||||
}
|
||||
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
}
|
||||
end = pos;
|
||||
}
|
||||
else {
|
||||
scanError = 3 /* UnexpectedEndOfNumber */;
|
||||
}
|
||||
}
|
||||
return text.substring(start, end);
|
||||
}
|
||||
function scanString() {
|
||||
var result = '', start = pos;
|
||||
while (true) {
|
||||
if (pos >= len) {
|
||||
result += text.substring(start, pos);
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch === 34 /* doubleQuote */) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
if (ch === 92 /* backslash */) {
|
||||
result += text.substring(start, pos);
|
||||
pos++;
|
||||
if (pos >= len) {
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
var ch2 = text.charCodeAt(pos++);
|
||||
switch (ch2) {
|
||||
case 34 /* doubleQuote */:
|
||||
result += '\"';
|
||||
break;
|
||||
case 92 /* backslash */:
|
||||
result += '\\';
|
||||
break;
|
||||
case 47 /* slash */:
|
||||
result += '/';
|
||||
break;
|
||||
case 98 /* b */:
|
||||
result += '\b';
|
||||
break;
|
||||
case 102 /* f */:
|
||||
result += '\f';
|
||||
break;
|
||||
case 110 /* n */:
|
||||
result += '\n';
|
||||
break;
|
||||
case 114 /* r */:
|
||||
result += '\r';
|
||||
break;
|
||||
case 116 /* t */:
|
||||
result += '\t';
|
||||
break;
|
||||
case 117 /* u */:
|
||||
var ch3 = scanHexDigits(4, true);
|
||||
if (ch3 >= 0) {
|
||||
result += String.fromCharCode(ch3);
|
||||
}
|
||||
else {
|
||||
scanError = 4 /* InvalidUnicode */;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
scanError = 5 /* InvalidEscapeCharacter */;
|
||||
}
|
||||
start = pos;
|
||||
continue;
|
||||
}
|
||||
if (ch >= 0 && ch <= 0x1f) {
|
||||
if (isLineBreak(ch)) {
|
||||
result += text.substring(start, pos);
|
||||
scanError = 2 /* UnexpectedEndOfString */;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
scanError = 6 /* InvalidCharacter */;
|
||||
// mark as error but continue with string
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function scanNext() {
|
||||
value = '';
|
||||
scanError = 0 /* None */;
|
||||
tokenOffset = pos;
|
||||
lineStartOffset = lineNumber;
|
||||
prevTokenLineStartOffset = tokenLineStartOffset;
|
||||
if (pos >= len) {
|
||||
// at the end
|
||||
tokenOffset = len;
|
||||
return token = 17 /* EOF */;
|
||||
}
|
||||
var code = text.charCodeAt(pos);
|
||||
// trivia: whitespace
|
||||
if (isWhiteSpace(code)) {
|
||||
do {
|
||||
pos++;
|
||||
value += String.fromCharCode(code);
|
||||
code = text.charCodeAt(pos);
|
||||
} while (isWhiteSpace(code));
|
||||
return token = 15 /* Trivia */;
|
||||
}
|
||||
// trivia: newlines
|
||||
if (isLineBreak(code)) {
|
||||
pos++;
|
||||
value += String.fromCharCode(code);
|
||||
if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
||||
pos++;
|
||||
value += '\n';
|
||||
}
|
||||
lineNumber++;
|
||||
tokenLineStartOffset = pos;
|
||||
return token = 14 /* LineBreakTrivia */;
|
||||
}
|
||||
switch (code) {
|
||||
// tokens: []{}:,
|
||||
case 123 /* openBrace */:
|
||||
pos++;
|
||||
return token = 1 /* OpenBraceToken */;
|
||||
case 125 /* closeBrace */:
|
||||
pos++;
|
||||
return token = 2 /* CloseBraceToken */;
|
||||
case 91 /* openBracket */:
|
||||
pos++;
|
||||
return token = 3 /* OpenBracketToken */;
|
||||
case 93 /* closeBracket */:
|
||||
pos++;
|
||||
return token = 4 /* CloseBracketToken */;
|
||||
case 58 /* colon */:
|
||||
pos++;
|
||||
return token = 6 /* ColonToken */;
|
||||
case 44 /* comma */:
|
||||
pos++;
|
||||
return token = 5 /* CommaToken */;
|
||||
// strings
|
||||
case 34 /* doubleQuote */:
|
||||
pos++;
|
||||
value = scanString();
|
||||
return token = 10 /* StringLiteral */;
|
||||
// comments
|
||||
case 47 /* slash */:
|
||||
var start = pos - 1;
|
||||
// Single-line comment
|
||||
if (text.charCodeAt(pos + 1) === 47 /* slash */) {
|
||||
pos += 2;
|
||||
while (pos < len) {
|
||||
if (isLineBreak(text.charCodeAt(pos))) {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
value = text.substring(start, pos);
|
||||
return token = 12 /* LineCommentTrivia */;
|
||||
}
|
||||
// Multi-line comment
|
||||
if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
|
||||
pos += 2;
|
||||
var safeLength = len - 1; // For lookahead.
|
||||
var commentClosed = false;
|
||||
while (pos < safeLength) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
|
||||
pos += 2;
|
||||
commentClosed = true;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
if (isLineBreak(ch)) {
|
||||
if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
||||
pos++;
|
||||
}
|
||||
lineNumber++;
|
||||
tokenLineStartOffset = pos;
|
||||
}
|
||||
}
|
||||
if (!commentClosed) {
|
||||
pos++;
|
||||
scanError = 1 /* UnexpectedEndOfComment */;
|
||||
}
|
||||
value = text.substring(start, pos);
|
||||
return token = 13 /* BlockCommentTrivia */;
|
||||
}
|
||||
// just a single slash
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
return token = 16 /* Unknown */;
|
||||
// numbers
|
||||
case 45 /* minus */:
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
// found a minus, followed by a number so
|
||||
// we fall through to proceed with scanning
|
||||
// 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 */:
|
||||
value += scanNumber();
|
||||
return token = 11 /* NumericLiteral */;
|
||||
// literals and unknown symbols
|
||||
default:
|
||||
// is a literal? Read the full word.
|
||||
while (pos < len && isUnknownContentCharacter(code)) {
|
||||
pos++;
|
||||
code = text.charCodeAt(pos);
|
||||
}
|
||||
if (tokenOffset !== pos) {
|
||||
value = text.substring(tokenOffset, pos);
|
||||
// keywords: true, false, null
|
||||
switch (value) {
|
||||
case 'true': return token = 8 /* TrueKeyword */;
|
||||
case 'false': return token = 9 /* FalseKeyword */;
|
||||
case 'null': return token = 7 /* NullKeyword */;
|
||||
}
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
// some
|
||||
value += String.fromCharCode(code);
|
||||
pos++;
|
||||
return token = 16 /* Unknown */;
|
||||
}
|
||||
}
|
||||
function isUnknownContentCharacter(code) {
|
||||
if (isWhiteSpace(code) || isLineBreak(code)) {
|
||||
return false;
|
||||
}
|
||||
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 */:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function scanNextNonTrivia() {
|
||||
var result;
|
||||
do {
|
||||
result = scanNext();
|
||||
} while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */);
|
||||
return result;
|
||||
}
|
||||
return {
|
||||
setPosition: setPosition,
|
||||
getPosition: function () { return pos; },
|
||||
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
||||
getToken: function () { return token; },
|
||||
getTokenValue: function () { return value; },
|
||||
getTokenOffset: function () { return tokenOffset; },
|
||||
getTokenLength: function () { return pos - tokenOffset; },
|
||||
getTokenStartLine: function () { return lineStartOffset; },
|
||||
getTokenStartCharacter: function () { return tokenOffset - prevTokenLineStartOffset; },
|
||||
getTokenError: function () { return scanError; },
|
||||
};
|
||||
}
|
||||
exports.createScanner = createScanner;
|
||||
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 */;
|
||||
}
|
||||
function isLineBreak(ch) {
|
||||
return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */;
|
||||
}
|
||||
function isDigit(ch) {
|
||||
return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
|
||||
}
|
||||
});
|
||||
316
node_modules/jsonc-parser/lib/umd/main.d.ts
generated
vendored
Executable file
316
node_modules/jsonc-parser/lib/umd/main.d.ts
generated
vendored
Executable file
|
|
@ -0,0 +1,316 @@
|
|||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
export declare const createScanner: (text: string, ignoreTrivia?: boolean) => JSONScanner;
|
||||
export declare const enum ScanError {
|
||||
None = 0,
|
||||
UnexpectedEndOfComment = 1,
|
||||
UnexpectedEndOfString = 2,
|
||||
UnexpectedEndOfNumber = 3,
|
||||
InvalidUnicode = 4,
|
||||
InvalidEscapeCharacter = 5,
|
||||
InvalidCharacter = 6
|
||||
}
|
||||
export declare const enum SyntaxKind {
|
||||
OpenBraceToken = 1,
|
||||
CloseBraceToken = 2,
|
||||
OpenBracketToken = 3,
|
||||
CloseBracketToken = 4,
|
||||
CommaToken = 5,
|
||||
ColonToken = 6,
|
||||
NullKeyword = 7,
|
||||
TrueKeyword = 8,
|
||||
FalseKeyword = 9,
|
||||
StringLiteral = 10,
|
||||
NumericLiteral = 11,
|
||||
LineCommentTrivia = 12,
|
||||
BlockCommentTrivia = 13,
|
||||
LineBreakTrivia = 14,
|
||||
Trivia = 15,
|
||||
Unknown = 16,
|
||||
EOF = 17
|
||||
}
|
||||
/**
|
||||
* The scanner object, representing a JSON scanner at a position in the input string.
|
||||
*/
|
||||
export interface JSONScanner {
|
||||
/**
|
||||
* Sets the scan position to a new offset. A call to 'scan' is needed to get the first token.
|
||||
*/
|
||||
setPosition(pos: number): void;
|
||||
/**
|
||||
* Read the next token. Returns the token code.
|
||||
*/
|
||||
scan(): SyntaxKind;
|
||||
/**
|
||||
* Returns the current scan position, which is after the last read token.
|
||||
*/
|
||||
getPosition(): number;
|
||||
/**
|
||||
* Returns the last read token.
|
||||
*/
|
||||
getToken(): SyntaxKind;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
getTokenOffset(): number;
|
||||
/**
|
||||
* The length of the last read token.
|
||||
*/
|
||||
getTokenLength(): number;
|
||||
/**
|
||||
* The zero-based start line number of the last read token.
|
||||
*/
|
||||
getTokenStartLine(): number;
|
||||
/**
|
||||
* The zero-based start character (column) of the last read token.
|
||||
*/
|
||||
getTokenStartCharacter(): number;
|
||||
/**
|
||||
* An error code of the last scan.
|
||||
*/
|
||||
getTokenError(): ScanError;
|
||||
}
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
export declare const getLocation: (text: string, position: number) => Location;
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore, always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
export declare const parse: (text: string, errors?: ParseError[], options?: ParseOptions) => any;
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
export declare const parseTree: (text: string, errors?: ParseError[], options?: ParseOptions) => Node | undefined;
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
export declare const findNodeAtLocation: (root: Node, path: JSONPath) => Node | undefined;
|
||||
/**
|
||||
* Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
export declare const findNodeAtOffset: (root: Node, offset: number, includeRightBound?: boolean) => Node | undefined;
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
export declare const getNodePath: (node: Node) => JSONPath;
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
export declare const getNodeValue: (node: Node) => any;
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
export declare const visit: (text: string, visitor: JSONVisitor, options?: ParseOptions) => any;
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
export declare const stripComments: (text: string, replaceCh?: string) => string;
|
||||
export interface ParseError {
|
||||
error: ParseErrorCode;
|
||||
offset: number;
|
||||
length: number;
|
||||
}
|
||||
export declare const enum ParseErrorCode {
|
||||
InvalidSymbol = 1,
|
||||
InvalidNumberFormat = 2,
|
||||
PropertyNameExpected = 3,
|
||||
ValueExpected = 4,
|
||||
ColonExpected = 5,
|
||||
CommaExpected = 6,
|
||||
CloseBraceExpected = 7,
|
||||
CloseBracketExpected = 8,
|
||||
EndOfFileExpected = 9,
|
||||
InvalidCommentToken = 10,
|
||||
UnexpectedEndOfComment = 11,
|
||||
UnexpectedEndOfString = 12,
|
||||
UnexpectedEndOfNumber = 13,
|
||||
InvalidUnicode = 14,
|
||||
InvalidEscapeCharacter = 15,
|
||||
InvalidCharacter = 16
|
||||
}
|
||||
export declare function printParseErrorCode(code: ParseErrorCode): "InvalidSymbol" | "InvalidNumberFormat" | "PropertyNameExpected" | "ValueExpected" | "ColonExpected" | "CommaExpected" | "CloseBraceExpected" | "CloseBracketExpected" | "EndOfFileExpected" | "InvalidCommentToken" | "UnexpectedEndOfComment" | "UnexpectedEndOfString" | "UnexpectedEndOfNumber" | "InvalidUnicode" | "InvalidEscapeCharacter" | "InvalidCharacter" | "<unknown ParseErrorCode>";
|
||||
export declare type NodeType = 'object' | 'array' | 'property' | 'string' | 'number' | 'boolean' | 'null';
|
||||
export interface Node {
|
||||
readonly type: NodeType;
|
||||
readonly value?: any;
|
||||
readonly offset: number;
|
||||
readonly length: number;
|
||||
readonly colonOffset?: number;
|
||||
readonly parent?: Node;
|
||||
readonly children?: Node[];
|
||||
}
|
||||
export declare type Segment = string | number;
|
||||
export declare type JSONPath = Segment[];
|
||||
export interface Location {
|
||||
/**
|
||||
* The previous property key or literal value (string, number, boolean or null) or undefined.
|
||||
*/
|
||||
previousNode?: Node;
|
||||
/**
|
||||
* The path describing the location in the JSON document. The path consists of a sequence of strings
|
||||
* representing an object property or numbers for array indices.
|
||||
*/
|
||||
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 sequence of segments of any property name or index, or no segment.
|
||||
*/
|
||||
matches: (patterns: JSONPath) => boolean;
|
||||
/**
|
||||
* If set, the location's offset is at a property key.
|
||||
*/
|
||||
isAtPropertyKey: boolean;
|
||||
}
|
||||
export interface ParseOptions {
|
||||
disallowComments?: boolean;
|
||||
allowTrailingComma?: boolean;
|
||||
allowEmptyContent?: boolean;
|
||||
}
|
||||
export interface JSONVisitor {
|
||||
/**
|
||||
* Invoked when an open brace is encountered and an object is started. The offset and length represent the location of the open brace.
|
||||
*/
|
||||
onObjectBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a property is encountered. The offset and length represent the location of the property name.
|
||||
*/
|
||||
onObjectProperty?: (property: string, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace.
|
||||
*/
|
||||
onObjectEnd?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when an open bracket is encountered. The offset and length represent the location of the open bracket.
|
||||
*/
|
||||
onArrayBegin?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket.
|
||||
*/
|
||||
onArrayEnd?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a literal value is encountered. The offset and length represent the location of the literal value.
|
||||
*/
|
||||
onLiteralValue?: (value: any, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator.
|
||||
*/
|
||||
onSeparator?: (character: string, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* When comments are allowed, invoked when a line or block comment is encountered. The offset and length represent the location of the comment.
|
||||
*/
|
||||
onComment?: (offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
/**
|
||||
* Invoked on an error.
|
||||
*/
|
||||
onError?: (error: ParseErrorCode, offset: number, length: number, startLine: number, startCharacter: number) => void;
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
/**
|
||||
* A text range in the document
|
||||
*/
|
||||
export interface Range {
|
||||
/**
|
||||
* The start offset of the range.
|
||||
*/
|
||||
offset: number;
|
||||
/**
|
||||
* The length of the range. Must not be negative.
|
||||
*/
|
||||
length: number;
|
||||
}
|
||||
export interface FormattingOptions {
|
||||
/**
|
||||
* If indentation is based on spaces (`insertSpaces` = true), the number of spaces that make an indent.
|
||||
*/
|
||||
tabSize?: number;
|
||||
/**
|
||||
* Is indentation based on spaces?
|
||||
*/
|
||||
insertSpaces?: boolean;
|
||||
/**
|
||||
* The default 'end of line' character. If not set, '\n' is used as default.
|
||||
*/
|
||||
eol?: string;
|
||||
/**
|
||||
* If set, will add a new line at the end of the document.
|
||||
*/
|
||||
insertFinalNewline?: boolean;
|
||||
}
|
||||
/**
|
||||
* Computes the edits needed to format a JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param range The range to format or `undefined` to format the full content
|
||||
* @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`.
|
||||
*/
|
||||
export declare function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[];
|
||||
/**
|
||||
* Options used when computing the modification edits
|
||||
*/
|
||||
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 {@property isArrayInsertion} is `true`, then
|
||||
* {@function 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;
|
||||
}
|
||||
/**
|
||||
* Computes the edits needed to modify a value in the JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param path The path of the value to change. The path represents either to the document root, a property or an array item.
|
||||
* If the path points to an non-existing property or item, it will be created.
|
||||
* @param value The new value for the specified property or item. If the value is undefined,
|
||||
* the property or item will be removed.
|
||||
* @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`.
|
||||
*/
|
||||
export declare function modify(text: string, path: JSONPath, value: any, options: ModificationOptions): Edit[];
|
||||
/**
|
||||
* Applies edits to a input string.
|
||||
*/
|
||||
export declare function applyEdits(text: string, edits: Edit[]): string;
|
||||
132
node_modules/jsonc-parser/lib/umd/main.js
generated
vendored
Executable file
132
node_modules/jsonc-parser/lib/umd/main.js
generated
vendored
Executable file
|
|
@ -0,0 +1,132 @@
|
|||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports", "./impl/format", "./impl/edit", "./impl/scanner", "./impl/parser"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.applyEdits = exports.modify = exports.format = exports.printParseErrorCode = exports.stripComments = exports.visit = exports.getNodeValue = exports.getNodePath = exports.findNodeAtOffset = exports.findNodeAtLocation = exports.parseTree = exports.parse = exports.getLocation = exports.createScanner = void 0;
|
||||
var formatter = require("./impl/format");
|
||||
var edit = require("./impl/edit");
|
||||
var scanner = require("./impl/scanner");
|
||||
var parser = require("./impl/parser");
|
||||
/**
|
||||
* Creates a JSON scanner on the given text.
|
||||
* If ignoreTrivia is set, whitespaces or comments are ignored.
|
||||
*/
|
||||
exports.createScanner = scanner.createScanner;
|
||||
/**
|
||||
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
|
||||
*/
|
||||
exports.getLocation = parser.getLocation;
|
||||
/**
|
||||
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
* Therefore, always check the errors list to find out if the input was valid.
|
||||
*/
|
||||
exports.parse = parser.parse;
|
||||
/**
|
||||
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
|
||||
*/
|
||||
exports.parseTree = parser.parseTree;
|
||||
/**
|
||||
* Finds the node at the given path in a JSON DOM.
|
||||
*/
|
||||
exports.findNodeAtLocation = parser.findNodeAtLocation;
|
||||
/**
|
||||
* Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
|
||||
*/
|
||||
exports.findNodeAtOffset = parser.findNodeAtOffset;
|
||||
/**
|
||||
* Gets the JSON path of the given JSON DOM node
|
||||
*/
|
||||
exports.getNodePath = parser.getNodePath;
|
||||
/**
|
||||
* Evaluates the JavaScript object of the given JSON DOM node
|
||||
*/
|
||||
exports.getNodeValue = parser.getNodeValue;
|
||||
/**
|
||||
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
|
||||
*/
|
||||
exports.visit = parser.visit;
|
||||
/**
|
||||
* Takes JSON with JavaScript-style comments and remove
|
||||
* them. Optionally replaces every none-newline character
|
||||
* of comments with a replaceCharacter
|
||||
*/
|
||||
exports.stripComments = parser.stripComments;
|
||||
function printParseErrorCode(code) {
|
||||
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';
|
||||
}
|
||||
return '<unknown ParseErrorCode>';
|
||||
}
|
||||
exports.printParseErrorCode = printParseErrorCode;
|
||||
/**
|
||||
* Computes the edits needed to format a JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param range The range to format or `undefined` to format the full content
|
||||
* @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`.
|
||||
*/
|
||||
function format(documentText, range, options) {
|
||||
return formatter.format(documentText, range, options);
|
||||
}
|
||||
exports.format = format;
|
||||
/**
|
||||
* Computes the edits needed to modify a value in the JSON document.
|
||||
*
|
||||
* @param documentText The input text
|
||||
* @param path The path of the value to change. The path represents either to the document root, a property or an array item.
|
||||
* If the path points to an non-existing property or item, it will be created.
|
||||
* @param value The new value for the specified property or item. If the value is undefined,
|
||||
* the property or item will be removed.
|
||||
* @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`.
|
||||
*/
|
||||
function modify(text, path, value, options) {
|
||||
return edit.setProperty(text, path, value, options);
|
||||
}
|
||||
exports.modify = modify;
|
||||
/**
|
||||
* Applies edits to a input string.
|
||||
*/
|
||||
function applyEdits(text, edits) {
|
||||
for (var i = edits.length - 1; i >= 0; i--) {
|
||||
text = edit.applyEdit(text, edits[i]);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
exports.applyEdits = applyEdits;
|
||||
});
|
||||
69
node_modules/jsonc-parser/package.json
generated
vendored
Executable file
69
node_modules/jsonc-parser/package.json
generated
vendored
Executable file
|
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"_from": "jsonc-parser@3.0.0",
|
||||
"_id": "jsonc-parser@3.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
|
||||
"_location": "/jsonc-parser",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "jsonc-parser@3.0.0",
|
||||
"name": "jsonc-parser",
|
||||
"escapedName": "jsonc-parser",
|
||||
"rawSpec": "3.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@angular/cli",
|
||||
"/@schematics/angular"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
|
||||
"_shasum": "abdd785701c7e7eaca8a9ec8cf070ca51a745a22",
|
||||
"_spec": "jsonc-parser@3.0.0",
|
||||
"_where": "/home/jack/Documents/JDA/m14/projecte_janmaroto/node_modules/@angular/cli",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/microsoft/node-jsonc-parser/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Scanner and parser for JSON with comments.",
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^10.12.12",
|
||||
"@typescript-eslint/eslint-plugin": "^4.7.0",
|
||||
"@typescript-eslint/parser": "^4.7.0",
|
||||
"eslint": "^7.13.0",
|
||||
"mocha": "^8.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.0.5"
|
||||
},
|
||||
"homepage": "https://github.com/microsoft/node-jsonc-parser#readme",
|
||||
"license": "MIT",
|
||||
"main": "./lib/umd/main.js",
|
||||
"module": "./lib/esm/main.js",
|
||||
"name": "jsonc-parser",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/microsoft/node-jsonc-parser.git"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf lib",
|
||||
"compile": "tsc -p ./src && npm run lint",
|
||||
"compile-esm": "tsc -p ./src/tsconfig.esm.json",
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"postpublish": "node ./build/post-publish.js",
|
||||
"postversion": "git push && git push --tags",
|
||||
"prepublishOnly": "npm run clean && npm run compile-esm && npm run test && npm run remove-sourcemap-refs",
|
||||
"preversion": "npm test",
|
||||
"remove-sourcemap-refs": "node ./build/remove-sourcemap-refs.js",
|
||||
"test": "npm run compile && mocha ./lib/umd/test",
|
||||
"watch": "tsc -w -p ./src"
|
||||
},
|
||||
"typings": "./lib/umd/main",
|
||||
"version": "3.0.0"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue