My dotfiles
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 

168 lignes
7.5 KiB

  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. 'use strict';
  6. import { parseTree, findNodeAtLocation } from './main';
  7. import { format, isEOL } from './format';
  8. export function removeProperty(text, path, formattingOptions) {
  9. return setProperty(text, path, void 0, formattingOptions);
  10. }
  11. export function setProperty(text, path, value, formattingOptions, getInsertionIndex) {
  12. var errors = [];
  13. var root = parseTree(text, errors);
  14. var parent = void 0;
  15. var lastSegment = void 0;
  16. while (path.length > 0) {
  17. lastSegment = path.pop();
  18. parent = findNodeAtLocation(root, path);
  19. if (parent === void 0 && value !== void 0) {
  20. if (typeof lastSegment === 'string') {
  21. value = (_a = {}, _a[lastSegment] = value, _a);
  22. }
  23. else {
  24. value = [value];
  25. }
  26. }
  27. else {
  28. break;
  29. }
  30. }
  31. if (!parent) {
  32. // empty document
  33. if (value === void 0) {
  34. throw new Error('Can not delete in empty document');
  35. }
  36. return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions);
  37. }
  38. else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
  39. var existing = findNodeAtLocation(parent, [lastSegment]);
  40. if (existing !== void 0) {
  41. if (value === void 0) {
  42. if (!existing.parent) {
  43. throw new Error('Malformed AST');
  44. }
  45. var propertyIndex = parent.children.indexOf(existing.parent);
  46. var removeBegin = void 0;
  47. var removeEnd = existing.parent.offset + existing.parent.length;
  48. if (propertyIndex > 0) {
  49. // remove the comma of the previous node
  50. var previous = parent.children[propertyIndex - 1];
  51. removeBegin = previous.offset + previous.length;
  52. }
  53. else {
  54. removeBegin = parent.offset + 1;
  55. if (parent.children.length > 1) {
  56. // remove the comma of the next node
  57. var next = parent.children[1];
  58. removeEnd = next.offset;
  59. }
  60. }
  61. return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, formattingOptions);
  62. }
  63. else {
  64. // set value of existing property
  65. return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, formattingOptions);
  66. }
  67. }
  68. else {
  69. if (value === void 0) {
  70. return []; // property does not exist, nothing to do
  71. }
  72. var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value);
  73. var index = getInsertionIndex ? getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length;
  74. var edit = void 0;
  75. if (index > 0) {
  76. var previous = parent.children[index - 1];
  77. edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
  78. }
  79. else if (parent.children.length === 0) {
  80. edit = { offset: parent.offset + 1, length: 0, content: newProperty };
  81. }
  82. else {
  83. edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
  84. }
  85. return withFormatting(text, edit, formattingOptions);
  86. }
  87. }
  88. else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
  89. var insertIndex = lastSegment;
  90. if (insertIndex === -1) {
  91. // Insert
  92. var newProperty = "" + JSON.stringify(value);
  93. var edit = void 0;
  94. if (parent.children.length === 0) {
  95. edit = { offset: parent.offset + 1, length: 0, content: newProperty };
  96. }
  97. else {
  98. var previous = parent.children[parent.children.length - 1];
  99. edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
  100. }
  101. return withFormatting(text, edit, formattingOptions);
  102. }
  103. else {
  104. if (value === void 0 && parent.children.length >= 0) {
  105. //Removal
  106. var removalIndex = lastSegment;
  107. var toRemove = parent.children[removalIndex];
  108. var edit = void 0;
  109. if (parent.children.length === 1) {
  110. // only item
  111. edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
  112. }
  113. else if (parent.children.length - 1 === removalIndex) {
  114. // last item
  115. var previous = parent.children[removalIndex - 1];
  116. var offset = previous.offset + previous.length;
  117. var parentEndOffset = parent.offset + parent.length;
  118. edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' };
  119. }
  120. else {
  121. edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
  122. }
  123. return withFormatting(text, edit, formattingOptions);
  124. }
  125. else {
  126. throw new Error('Array modification not supported yet');
  127. }
  128. }
  129. }
  130. else {
  131. throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type);
  132. }
  133. var _a;
  134. }
  135. function withFormatting(text, edit, formattingOptions) {
  136. // apply the edit
  137. var newText = applyEdit(text, edit);
  138. // format the new text
  139. var begin = edit.offset;
  140. var end = edit.offset + edit.content.length;
  141. if (edit.length === 0 || edit.content.length === 0) {
  142. while (begin > 0 && !isEOL(newText, begin - 1)) {
  143. begin--;
  144. }
  145. while (end < newText.length && !isEOL(newText, end)) {
  146. end++;
  147. }
  148. }
  149. var edits = format(newText, { offset: begin, length: end - begin }, formattingOptions);
  150. // apply the formatting edits and track the begin and end offsets of the changes
  151. for (var i = edits.length - 1; i >= 0; i--) {
  152. var edit_1 = edits[i];
  153. newText = applyEdit(newText, edit_1);
  154. begin = Math.min(begin, edit_1.offset);
  155. end = Math.max(end, edit_1.offset + edit_1.length);
  156. end += edit_1.content.length - edit_1.length;
  157. }
  158. // create a single edit with all changes
  159. var editLength = text.length - (newText.length - end) - begin;
  160. return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
  161. }
  162. export function applyEdit(text, edit) {
  163. return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
  164. }
  165. export function isWS(text, offset) {
  166. return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
  167. }
  168. //# sourceMappingURL=edit.js.map