massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-json / node_modules / jsonc-parser / lib / umd / impl / edit.js
1 (function (factory) {
2     if (typeof module === "object" && typeof module.exports === "object") {
3         var v = factory(require, exports);
4         if (v !== undefined) module.exports = v;
5     }
6     else if (typeof define === "function" && define.amd) {
7         define(["require", "exports", "./format", "./parser"], factory);
8     }
9 })(function (require, exports) {
10     /*---------------------------------------------------------------------------------------------
11      *  Copyright (c) Microsoft Corporation. All rights reserved.
12      *  Licensed under the MIT License. See License.txt in the project root for license information.
13      *--------------------------------------------------------------------------------------------*/
14     'use strict';
15     Object.defineProperty(exports, "__esModule", { value: true });
16     exports.isWS = exports.applyEdit = exports.setProperty = exports.removeProperty = void 0;
17     var format_1 = require("./format");
18     var parser_1 = require("./parser");
19     function removeProperty(text, path, options) {
20         return setProperty(text, path, void 0, options);
21     }
22     exports.removeProperty = removeProperty;
23     function setProperty(text, originalPath, value, options) {
24         var _a;
25         var path = originalPath.slice();
26         var errors = [];
27         var root = parser_1.parseTree(text, errors);
28         var parent = void 0;
29         var lastSegment = void 0;
30         while (path.length > 0) {
31             lastSegment = path.pop();
32             parent = parser_1.findNodeAtLocation(root, path);
33             if (parent === void 0 && value !== void 0) {
34                 if (typeof lastSegment === 'string') {
35                     value = (_a = {}, _a[lastSegment] = value, _a);
36                 }
37                 else {
38                     value = [value];
39                 }
40             }
41             else {
42                 break;
43             }
44         }
45         if (!parent) {
46             // empty document
47             if (value === void 0) { // delete
48                 throw new Error('Can not delete in empty document');
49             }
50             return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, options);
51         }
52         else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
53             var existing = parser_1.findNodeAtLocation(parent, [lastSegment]);
54             if (existing !== void 0) {
55                 if (value === void 0) { // delete
56                     if (!existing.parent) {
57                         throw new Error('Malformed AST');
58                     }
59                     var propertyIndex = parent.children.indexOf(existing.parent);
60                     var removeBegin = void 0;
61                     var removeEnd = existing.parent.offset + existing.parent.length;
62                     if (propertyIndex > 0) {
63                         // remove the comma of the previous node
64                         var previous = parent.children[propertyIndex - 1];
65                         removeBegin = previous.offset + previous.length;
66                     }
67                     else {
68                         removeBegin = parent.offset + 1;
69                         if (parent.children.length > 1) {
70                             // remove the comma of the next node
71                             var next = parent.children[1];
72                             removeEnd = next.offset;
73                         }
74                     }
75                     return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, options);
76                 }
77                 else {
78                     // set value of existing property
79                     return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, options);
80                 }
81             }
82             else {
83                 if (value === void 0) { // delete
84                     return []; // property does not exist, nothing to do
85                 }
86                 var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value);
87                 var index = options.getInsertionIndex ? options.getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length;
88                 var edit = void 0;
89                 if (index > 0) {
90                     var previous = parent.children[index - 1];
91                     edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
92                 }
93                 else if (parent.children.length === 0) {
94                     edit = { offset: parent.offset + 1, length: 0, content: newProperty };
95                 }
96                 else {
97                     edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
98                 }
99                 return withFormatting(text, edit, options);
100             }
101         }
102         else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
103             var insertIndex = lastSegment;
104             if (insertIndex === -1) {
105                 // Insert
106                 var newProperty = "" + JSON.stringify(value);
107                 var edit = void 0;
108                 if (parent.children.length === 0) {
109                     edit = { offset: parent.offset + 1, length: 0, content: newProperty };
110                 }
111                 else {
112                     var previous = parent.children[parent.children.length - 1];
113                     edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
114                 }
115                 return withFormatting(text, edit, options);
116             }
117             else if (value === void 0 && parent.children.length >= 0) {
118                 // Removal
119                 var removalIndex = lastSegment;
120                 var toRemove = parent.children[removalIndex];
121                 var edit = void 0;
122                 if (parent.children.length === 1) {
123                     // only item
124                     edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
125                 }
126                 else if (parent.children.length - 1 === removalIndex) {
127                     // last item
128                     var previous = parent.children[removalIndex - 1];
129                     var offset = previous.offset + previous.length;
130                     var parentEndOffset = parent.offset + parent.length;
131                     edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' };
132                 }
133                 else {
134                     edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
135                 }
136                 return withFormatting(text, edit, options);
137             }
138             else if (value !== void 0) {
139                 var edit = void 0;
140                 var newProperty = "" + JSON.stringify(value);
141                 if (!options.isArrayInsertion && parent.children.length > lastSegment) {
142                     var toModify = parent.children[lastSegment];
143                     edit = { offset: toModify.offset, length: toModify.length, content: newProperty };
144                 }
145                 else if (parent.children.length === 0 || lastSegment === 0) {
146                     edit = { offset: parent.offset + 1, length: 0, content: parent.children.length === 0 ? newProperty : newProperty + ',' };
147                 }
148                 else {
149                     var index = lastSegment > parent.children.length ? parent.children.length : lastSegment;
150                     var previous = parent.children[index - 1];
151                     edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
152                 }
153                 return withFormatting(text, edit, options);
154             }
155             else {
156                 throw new Error("Can not " + (value === void 0 ? 'remove' : (options.isArrayInsertion ? 'insert' : 'modify')) + " Array index " + insertIndex + " as length is not sufficient");
157             }
158         }
159         else {
160             throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type);
161         }
162     }
163     exports.setProperty = setProperty;
164     function withFormatting(text, edit, options) {
165         if (!options.formattingOptions) {
166             return [edit];
167         }
168         // apply the edit
169         var newText = applyEdit(text, edit);
170         // format the new text
171         var begin = edit.offset;
172         var end = edit.offset + edit.content.length;
173         if (edit.length === 0 || edit.content.length === 0) { // insert or remove
174             while (begin > 0 && !format_1.isEOL(newText, begin - 1)) {
175                 begin--;
176             }
177             while (end < newText.length && !format_1.isEOL(newText, end)) {
178                 end++;
179             }
180         }
181         var edits = format_1.format(newText, { offset: begin, length: end - begin }, options.formattingOptions);
182         // apply the formatting edits and track the begin and end offsets of the changes
183         for (var i = edits.length - 1; i >= 0; i--) {
184             var edit_1 = edits[i];
185             newText = applyEdit(newText, edit_1);
186             begin = Math.min(begin, edit_1.offset);
187             end = Math.max(end, edit_1.offset + edit_1.length);
188             end += edit_1.content.length - edit_1.length;
189         }
190         // create a single edit with all changes
191         var editLength = text.length - (newText.length - end) - begin;
192         return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
193     }
194     function applyEdit(text, edit) {
195         return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
196     }
197     exports.applyEdit = applyEdit;
198     function isWS(text, offset) {
199         return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
200     }
201     exports.isWS = isWS;
202 });