@sap-ux/fiori-annotation-api 0.11.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/annotation-provider.d.ts +1 -1
- package/dist/annotation-provider.d.ts.map +1 -1
- package/dist/annotation-provider.js +30 -36
- package/dist/annotation-provider.js.map +1 -1
- package/dist/avt/annotations.js +53 -56
- package/dist/avt/annotations.js.map +1 -1
- package/dist/avt/expressions.js +3 -7
- package/dist/avt/expressions.js.map +1 -1
- package/dist/avt/find.d.ts +2 -2
- package/dist/avt/find.d.ts.map +1 -1
- package/dist/avt/find.js +16 -20
- package/dist/avt/find.js.map +1 -1
- package/dist/avt/index.d.ts +8 -8
- package/dist/avt/index.d.ts.map +1 -1
- package/dist/avt/index.js +7 -31
- package/dist/avt/index.js.map +1 -1
- package/dist/avt/metadata.js +1 -4
- package/dist/avt/metadata.js.map +1 -1
- package/dist/avt/pointer.d.ts +1 -1
- package/dist/avt/pointer.d.ts.map +1 -1
- package/dist/avt/pointer.js +12 -15
- package/dist/avt/pointer.js.map +1 -1
- package/dist/avt/to-internal.d.ts +1 -1
- package/dist/avt/to-internal.d.ts.map +1 -1
- package/dist/avt/to-internal.js +53 -65
- package/dist/avt/to-internal.js.map +1 -1
- package/dist/avt/types.js +1 -2
- package/dist/avt/utils.d.ts +2 -2
- package/dist/avt/utils.d.ts.map +1 -1
- package/dist/avt/utils.js +11 -20
- package/dist/avt/utils.js.map +1 -1
- package/dist/cds/adapter.d.ts +5 -5
- package/dist/cds/adapter.d.ts.map +1 -1
- package/dist/cds/adapter.js +184 -187
- package/dist/cds/adapter.js.map +1 -1
- package/dist/cds/cds-compiler-tokens.js +11 -21
- package/dist/cds/cds-compiler-tokens.js.map +1 -1
- package/dist/cds/change.d.ts +1 -1
- package/dist/cds/change.d.ts.map +1 -1
- package/dist/cds/change.js +63 -79
- package/dist/cds/change.js.map +1 -1
- package/dist/cds/comments.d.ts +1 -1
- package/dist/cds/comments.d.ts.map +1 -1
- package/dist/cds/comments.js +4 -7
- package/dist/cds/comments.js.map +1 -1
- package/dist/cds/deletion.d.ts +1 -1
- package/dist/cds/deletion.d.ts.map +1 -1
- package/dist/cds/deletion.js +74 -61
- package/dist/cds/deletion.js.map +1 -1
- package/dist/cds/document.d.ts +4 -4
- package/dist/cds/document.d.ts.map +1 -1
- package/dist/cds/document.js +20 -27
- package/dist/cds/document.js.map +1 -1
- package/dist/cds/indent.d.ts +2 -2
- package/dist/cds/indent.d.ts.map +1 -1
- package/dist/cds/indent.js +16 -20
- package/dist/cds/indent.js.map +1 -1
- package/dist/cds/index.d.ts +2 -2
- package/dist/cds/index.d.ts.map +1 -1
- package/dist/cds/index.js +4 -22
- package/dist/cds/index.js.map +1 -1
- package/dist/cds/pointer.d.ts +1 -1
- package/dist/cds/pointer.d.ts.map +1 -1
- package/dist/cds/pointer.js +38 -42
- package/dist/cds/pointer.js.map +1 -1
- package/dist/cds/preprocessor.d.ts +3 -3
- package/dist/cds/preprocessor.d.ts.map +1 -1
- package/dist/cds/preprocessor.js +91 -95
- package/dist/cds/preprocessor.js.map +1 -1
- package/dist/cds/references.d.ts +2 -2
- package/dist/cds/references.d.ts.map +1 -1
- package/dist/cds/references.js +49 -55
- package/dist/cds/references.js.map +1 -1
- package/dist/cds/service.d.ts +1 -1
- package/dist/cds/service.d.ts.map +1 -1
- package/dist/cds/service.js +6 -8
- package/dist/cds/service.js.map +1 -1
- package/dist/cds/utils.d.ts +2 -2
- package/dist/cds/utils.d.ts.map +1 -1
- package/dist/cds/utils.js +20 -24
- package/dist/cds/utils.js.map +1 -1
- package/dist/cds/writer.d.ts +6 -6
- package/dist/cds/writer.d.ts.map +1 -1
- package/dist/cds/writer.js +199 -202
- package/dist/cds/writer.js.map +1 -1
- package/dist/change-converter.d.ts +1 -1
- package/dist/change-converter.d.ts.map +1 -1
- package/dist/change-converter.js +124 -128
- package/dist/change-converter.js.map +1 -1
- package/dist/error.js +3 -7
- package/dist/error.js.map +1 -1
- package/dist/external-services.d.ts +1 -1
- package/dist/external-services.d.ts.map +1 -1
- package/dist/external-services.js +10 -13
- package/dist/external-services.js.map +1 -1
- package/dist/fiori-service.d.ts +4 -4
- package/dist/fiori-service.d.ts.map +1 -1
- package/dist/fiori-service.js +41 -45
- package/dist/fiori-service.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -31
- package/dist/index.js.map +1 -1
- package/dist/logger.js +2 -5
- package/dist/logger.js.map +1 -1
- package/dist/protected.d.ts +2 -2
- package/dist/protected.d.ts.map +1 -1
- package/dist/protected.js +2 -8
- package/dist/protected.js.map +1 -1
- package/dist/sap/builders.d.ts +1 -1
- package/dist/sap/builders.d.ts.map +1 -1
- package/dist/sap/builders.js +22 -30
- package/dist/sap/builders.js.map +1 -1
- package/dist/sap/collector.d.ts +1 -1
- package/dist/sap/collector.d.ts.map +1 -1
- package/dist/sap/collector.js +50 -53
- package/dist/sap/collector.js.map +1 -1
- package/dist/sap/converter.d.ts +1 -1
- package/dist/sap/converter.d.ts.map +1 -1
- package/dist/sap/converter.js +37 -42
- package/dist/sap/converter.js.map +1 -1
- package/dist/sap/index.d.ts +1 -1
- package/dist/sap/index.d.ts.map +1 -1
- package/dist/sap/index.js +1 -6
- package/dist/sap/index.js.map +1 -1
- package/dist/sap/types.js +5 -8
- package/dist/sap/types.js.map +1 -1
- package/dist/types/adapter.d.ts +3 -3
- package/dist/types/adapter.d.ts.map +1 -1
- package/dist/types/adapter.js +1 -2
- package/dist/types/change.js +11 -14
- package/dist/types/change.js.map +1 -1
- package/dist/types/index.d.ts +6 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -32
- package/dist/types/index.js.map +1 -1
- package/dist/types/internal-change.d.ts +1 -1
- package/dist/types/internal-change.d.ts.map +1 -1
- package/dist/types/internal-change.js +13 -16
- package/dist/types/internal-change.js.map +1 -1
- package/dist/types/project-info.js +1 -2
- package/dist/types/service.d.ts +1 -1
- package/dist/types/service.d.ts.map +1 -1
- package/dist/types/service.js +1 -2
- package/dist/types/text-file.js +1 -2
- package/dist/utils/constants.js +20 -22
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/indent.js +1 -4
- package/dist/utils/indent.js.map +1 -1
- package/dist/utils/index.d.ts +7 -7
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +7 -17
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/metadata.js +1 -4
- package/dist/utils/metadata.js.map +1 -1
- package/dist/utils/path.js +5 -8
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/pointer.d.ts +1 -1
- package/dist/utils/pointer.d.ts.map +1 -1
- package/dist/utils/pointer.js +1 -4
- package/dist/utils/pointer.js.map +1 -1
- package/dist/utils/range.js +1 -4
- package/dist/utils/range.js.map +1 -1
- package/dist/utils/reference.d.ts +1 -1
- package/dist/utils/reference.d.ts.map +1 -1
- package/dist/utils/reference.js +1 -4
- package/dist/utils/reference.js.map +1 -1
- package/dist/vocabularies.js +1 -4
- package/dist/vocabularies.js.map +1 -1
- package/dist/xml/adapter.d.ts +2 -2
- package/dist/xml/adapter.d.ts.map +1 -1
- package/dist/xml/adapter.js +92 -96
- package/dist/xml/adapter.js.map +1 -1
- package/dist/xml/changes.d.ts +1 -1
- package/dist/xml/changes.d.ts.map +1 -1
- package/dist/xml/changes.js +11 -15
- package/dist/xml/changes.js.map +1 -1
- package/dist/xml/comments.js +3 -6
- package/dist/xml/comments.js.map +1 -1
- package/dist/xml/document.d.ts +1 -1
- package/dist/xml/document.d.ts.map +1 -1
- package/dist/xml/document.js +1 -2
- package/dist/xml/index.d.ts +2 -2
- package/dist/xml/index.d.ts.map +1 -1
- package/dist/xml/index.js +4 -9
- package/dist/xml/index.js.map +1 -1
- package/dist/xml/pointer.js +1 -4
- package/dist/xml/pointer.js.map +1 -1
- package/dist/xml/references.js +15 -18
- package/dist/xml/references.js.map +1 -1
- package/dist/xml/service.d.ts +1 -1
- package/dist/xml/service.d.ts.map +1 -1
- package/dist/xml/service.js +4 -7
- package/dist/xml/service.js.map +1 -1
- package/dist/xml/writer.d.ts +2 -2
- package/dist/xml/writer.d.ts.map +1 -1
- package/dist/xml/writer.js +100 -104
- package/dist/xml/writer.js.map +1 -1
- package/package.json +13 -11
package/dist/xml/writer.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const changes_1 = require("./changes");
|
|
11
|
-
const pointer_1 = require("./pointer");
|
|
12
|
-
const printOptions = { ...odata_annotation_core_types_1.printOptions, useSnippetSyntax: false };
|
|
1
|
+
import { getIndentLevel, indentWithTabs, indentWithSpaces, isBefore, rangeContained } from '@sap-ux/odata-annotation-core';
|
|
2
|
+
import { copyPosition, copyRange } from '@sap-ux/cds-annotation-parser';
|
|
3
|
+
import { createElementNode, Position, printOptions as defaultPrintOptions, TextEdit, Range, EDMX_NAMESPACE_ALIAS, EDM_NAMESPACE_ALIAS } from '@sap-ux/odata-annotation-core-types';
|
|
4
|
+
import { printCsdlNodeToXmlString, transformRange, escapeAttribute, EDMX_V4_NAMESPACE, EDM_V4_NAMESPACE } from '@sap-ux/xml-odata-annotation-converter';
|
|
5
|
+
import { DEFAULT_NS } from '@xml-tools/ast';
|
|
6
|
+
import { compareByRange } from '../utils/index.js';
|
|
7
|
+
import { DELETE_ELEMENT, REPLACE_ELEMENT_CONTENT } from './changes.js';
|
|
8
|
+
import { getNodeFromPointer } from './pointer.js';
|
|
9
|
+
const printOptions = { ...defaultPrintOptions, useSnippetSyntax: false };
|
|
13
10
|
/**
|
|
14
11
|
* Translates changes objects to XML text edits.
|
|
15
12
|
*/
|
|
16
|
-
class XMLWriter {
|
|
13
|
+
export class XMLWriter {
|
|
17
14
|
document;
|
|
18
15
|
comments;
|
|
19
16
|
textDocument;
|
|
@@ -50,7 +47,7 @@ class XMLWriter {
|
|
|
50
47
|
for (const pointer of Object.keys(batches)) {
|
|
51
48
|
edits.push(...this.getTextEditsForPointer(pointer, batches[pointer], changes));
|
|
52
49
|
}
|
|
53
|
-
edits.sort(
|
|
50
|
+
edits.sort(compareByRange);
|
|
54
51
|
return edits;
|
|
55
52
|
}
|
|
56
53
|
getContent(element) {
|
|
@@ -63,7 +60,7 @@ class XMLWriter {
|
|
|
63
60
|
}
|
|
64
61
|
getTextEditsForPointer(pointer, byType, changes) {
|
|
65
62
|
const edits = [];
|
|
66
|
-
const element =
|
|
63
|
+
const element = getNodeFromPointer(this.document, pointer);
|
|
67
64
|
const childIndentLevel = getIndentFromElement(element);
|
|
68
65
|
const inserts = (byType.get('insert-element') ?? []);
|
|
69
66
|
const insertEdits = convertInsertElementToTextEdits(this.comments, element, inserts, childIndentLevel);
|
|
@@ -74,7 +71,7 @@ class XMLWriter {
|
|
|
74
71
|
case 'XMLElement': {
|
|
75
72
|
const elementChanges = {
|
|
76
73
|
replacements: (byType.get('replace-element') ?? []),
|
|
77
|
-
contentReplacements: (byType.get(
|
|
74
|
+
contentReplacements: (byType.get(REPLACE_ELEMENT_CONTENT) ?? []),
|
|
78
75
|
elementDeletions: (byType.get('delete-element') ?? []),
|
|
79
76
|
attributeInserts: (byType.get('insert-attribute') ?? []),
|
|
80
77
|
moveInCollection: (byType.get('move-collection-value') ?? [])
|
|
@@ -138,53 +135,52 @@ class XMLWriter {
|
|
|
138
135
|
}
|
|
139
136
|
text.push(this.textDocument.getText(range));
|
|
140
137
|
if (changes.some((change) => {
|
|
141
|
-
if (change.type !==
|
|
138
|
+
if (change.type !== DELETE_ELEMENT) {
|
|
142
139
|
return false;
|
|
143
140
|
}
|
|
144
|
-
const element =
|
|
145
|
-
const changeRange = element?.type === 'XMLElement' &&
|
|
146
|
-
return changeRange &&
|
|
141
|
+
const element = getNodeFromPointer(this.document, change.pointer);
|
|
142
|
+
const changeRange = element?.type === 'XMLElement' && transformRange(element.position);
|
|
143
|
+
return changeRange && rangeContained(changeRange, range);
|
|
147
144
|
})) {
|
|
148
145
|
continue;
|
|
149
146
|
}
|
|
150
|
-
textEdits.push(
|
|
147
|
+
textEdits.push(TextEdit.del(range));
|
|
151
148
|
}
|
|
152
149
|
return { textEdits, text };
|
|
153
150
|
}
|
|
154
151
|
}
|
|
155
|
-
exports.XMLWriter = XMLWriter;
|
|
156
152
|
function handleXmlAttributeChanges(attributeChanges, element) {
|
|
157
153
|
const edits = [];
|
|
158
154
|
const { attributeDeletions, attributeNameUpdates, attributeValueUpdates } = attributeChanges;
|
|
159
155
|
if (attributeDeletions.length > 0) {
|
|
160
|
-
const attributeRange =
|
|
156
|
+
const attributeRange = transformRange(element.position);
|
|
161
157
|
if (attributeRange) {
|
|
162
158
|
// There must be a space character before attribute and we should remove it with attribute.
|
|
163
159
|
attributeRange.start.character--;
|
|
164
|
-
edits.push(
|
|
160
|
+
edits.push(TextEdit.del(attributeRange));
|
|
165
161
|
}
|
|
166
162
|
}
|
|
167
163
|
else {
|
|
168
164
|
// if attribute is deleted, then we can ignore updates
|
|
169
|
-
const nameRange =
|
|
165
|
+
const nameRange = transformRange(element.syntax.key);
|
|
170
166
|
if (nameRange && attributeNameUpdates.length > 0) {
|
|
171
167
|
const newName = attributeNameUpdates[attributeNameUpdates.length - 1].newName;
|
|
172
|
-
edits.push(
|
|
168
|
+
edits.push(TextEdit.replace(nameRange, newName));
|
|
173
169
|
}
|
|
174
|
-
const valueRange =
|
|
170
|
+
const valueRange = transformRange(element.syntax.value);
|
|
175
171
|
if (valueRange && attributeValueUpdates.length > 0) {
|
|
176
172
|
const newValue = attributeValueUpdates[attributeValueUpdates.length - 1].newValue;
|
|
177
173
|
// shift from start quote
|
|
178
174
|
valueRange.start.character++;
|
|
179
175
|
// shift from end quote
|
|
180
176
|
valueRange.end.character--;
|
|
181
|
-
edits.push(
|
|
177
|
+
edits.push(TextEdit.replace(valueRange, newValue));
|
|
182
178
|
}
|
|
183
179
|
}
|
|
184
180
|
return edits;
|
|
185
181
|
}
|
|
186
182
|
function handleXmlElementAttributeInserts(element, attributeInserts) {
|
|
187
|
-
const openTagRange =
|
|
183
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
188
184
|
if (!openTagRange) {
|
|
189
185
|
return [];
|
|
190
186
|
}
|
|
@@ -207,11 +203,11 @@ function handleXmlElementAttributeInserts(element, attributeInserts) {
|
|
|
207
203
|
}
|
|
208
204
|
for (const attributeInsert of inserts) {
|
|
209
205
|
// insert before open tag
|
|
210
|
-
attributes.push(`${attributeInsert.name}="${
|
|
206
|
+
attributes.push(`${attributeInsert.name}="${escapeAttribute(attributeInsert.value)}"`);
|
|
211
207
|
}
|
|
212
208
|
if (attributes.length > 0) {
|
|
213
209
|
const text = ` ${attributes.join(' ')}`;
|
|
214
|
-
edits.push(
|
|
210
|
+
edits.push(TextEdit.insert(position, text));
|
|
215
211
|
}
|
|
216
212
|
}
|
|
217
213
|
return edits;
|
|
@@ -251,50 +247,50 @@ function adjustFragmentIndentation(text, requiredIndent) {
|
|
|
251
247
|
}
|
|
252
248
|
function handleXmlElementMoveChange(element, childIndentLevel, text, insertPosition) {
|
|
253
249
|
const edits = [];
|
|
254
|
-
const openTagRange =
|
|
250
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
255
251
|
const textWithNewIndentation = adjustFragmentIndentation(text.join(''), childIndentLevel);
|
|
256
252
|
if (element.syntax.isSelfClosing && openTagRange) {
|
|
257
253
|
const indent = ' '.repeat(childIndentLevel - 1);
|
|
258
|
-
edits.push(
|
|
254
|
+
edits.push(TextEdit.replace(Range.create(openTagRange.end.line, openTagRange.end.character - 2, openTagRange.end.line, openTagRange.end.character), `>${textWithNewIndentation}\n${indent}</${element.name}>`));
|
|
259
255
|
}
|
|
260
256
|
else {
|
|
261
|
-
edits.push(
|
|
257
|
+
edits.push(TextEdit.insert(insertPosition, textWithNewIndentation));
|
|
262
258
|
}
|
|
263
259
|
return edits;
|
|
264
260
|
}
|
|
265
261
|
function handleXmlElementContentReplacements(element, contentReplacements, childIndentLevel) {
|
|
266
262
|
const edits = [];
|
|
267
|
-
const openTagRange =
|
|
268
|
-
const closeTagRange =
|
|
263
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
264
|
+
const closeTagRange = transformRange(element.syntax.closeBody);
|
|
269
265
|
const lastChange = contentReplacements.slice(-1)[0];
|
|
270
266
|
const namespaceMap = getNamespaceMap(element);
|
|
271
267
|
const text = replaceElementContentToText(lastChange, childIndentLevel - 1, namespaceMap);
|
|
272
268
|
if (element.syntax.isSelfClosing && openTagRange) {
|
|
273
|
-
edits.push(
|
|
269
|
+
edits.push(TextEdit.replace(Range.create(openTagRange.end.line, openTagRange.end.character - 2, openTagRange.end.line, openTagRange.end.character), `>${text}</${element.name}>`));
|
|
274
270
|
}
|
|
275
271
|
else if (openTagRange && closeTagRange) {
|
|
276
|
-
edits.push(
|
|
272
|
+
edits.push(TextEdit.replace(Range.create(openTagRange.end, closeTagRange.start), text));
|
|
277
273
|
}
|
|
278
274
|
return edits;
|
|
279
275
|
}
|
|
280
276
|
function handleXmlElementReplacements(element, replacements, childIndentLevel) {
|
|
281
277
|
const edits = [];
|
|
282
|
-
const openTagRange =
|
|
283
|
-
const closeTagRange =
|
|
278
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
279
|
+
const closeTagRange = transformRange(element.syntax.closeBody);
|
|
284
280
|
const lastChange = replacements.slice(-1)[0];
|
|
285
281
|
const namespaceMap = getNamespaceMap(element);
|
|
286
282
|
const text = replaceElementToText(lastChange, childIndentLevel - 1, namespaceMap);
|
|
287
283
|
if (element.syntax.isSelfClosing && openTagRange) {
|
|
288
|
-
edits.push(
|
|
284
|
+
edits.push(TextEdit.replace(openTagRange, text));
|
|
289
285
|
}
|
|
290
286
|
else if (openTagRange && closeTagRange) {
|
|
291
|
-
edits.push(
|
|
287
|
+
edits.push(TextEdit.replace(Range.create(openTagRange.start, closeTagRange.end), text));
|
|
292
288
|
}
|
|
293
289
|
return edits;
|
|
294
290
|
}
|
|
295
291
|
function handleXmlElementDeletions(parent, pointer, content, element) {
|
|
296
292
|
const edits = [];
|
|
297
|
-
const openTagRange =
|
|
293
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
298
294
|
if (parent.type === 'XMLElement') {
|
|
299
295
|
const index = Number.parseInt(pointer.split('/').slice(-1)[0], 10);
|
|
300
296
|
const { previousContentIndex, startContentIndex } = findContentIndices(index, index, content);
|
|
@@ -302,22 +298,22 @@ function handleXmlElementDeletions(parent, pointer, content, element) {
|
|
|
302
298
|
if (anchor) {
|
|
303
299
|
const previousElement = content[previousContentIndex];
|
|
304
300
|
const nextElement = content.find((item, i) => item.type === 'element' && i > startContentIndex);
|
|
305
|
-
const parentCloseTagRange =
|
|
301
|
+
const parentCloseTagRange = transformRange(parent.syntax.closeBody);
|
|
306
302
|
if (!nextElement && !previousElement && parentCloseTagRange) {
|
|
307
303
|
updatePosition(anchor.end, parentCloseTagRange.start);
|
|
308
304
|
}
|
|
309
|
-
edits.push(
|
|
305
|
+
edits.push(TextEdit.del(anchor));
|
|
310
306
|
}
|
|
311
307
|
}
|
|
312
308
|
else if (element.syntax.isSelfClosing && openTagRange) {
|
|
313
309
|
// empty root element
|
|
314
|
-
edits.push(
|
|
310
|
+
edits.push(TextEdit.del(openTagRange));
|
|
315
311
|
}
|
|
316
312
|
else {
|
|
317
313
|
// root element with content
|
|
318
|
-
const closeTagRange =
|
|
314
|
+
const closeTagRange = transformRange(element.syntax.closeBody);
|
|
319
315
|
if (openTagRange && closeTagRange) {
|
|
320
|
-
edits.push(
|
|
316
|
+
edits.push(TextEdit.del(Range.create(openTagRange.start, closeTagRange.end)));
|
|
321
317
|
}
|
|
322
318
|
}
|
|
323
319
|
return edits;
|
|
@@ -326,17 +322,17 @@ function convertUpdateElementNameToTextEdits(elementNameUpdates, element) {
|
|
|
326
322
|
const edits = [];
|
|
327
323
|
if (elementNameUpdates.length > 0 && element?.type === 'XMLElement') {
|
|
328
324
|
const newName = elementNameUpdates[elementNameUpdates.length - 1].newName;
|
|
329
|
-
const openTagRange =
|
|
330
|
-
const closeTagRange =
|
|
325
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
326
|
+
const closeTagRange = transformRange(element.syntax.closeBody);
|
|
331
327
|
if (openTagRange) {
|
|
332
328
|
const nameLength = element.name?.length ?? 0;
|
|
333
329
|
openTagRange.start.character++; // <
|
|
334
330
|
openTagRange.end.character = openTagRange.start.character + nameLength;
|
|
335
|
-
edits.push(
|
|
331
|
+
edits.push(TextEdit.replace(openTagRange, newName));
|
|
336
332
|
if (closeTagRange) {
|
|
337
333
|
closeTagRange.start.character += 2; // </
|
|
338
334
|
closeTagRange.end.character--; // >
|
|
339
|
-
edits.push(
|
|
335
|
+
edits.push(TextEdit.replace(closeTagRange, newName));
|
|
340
336
|
}
|
|
341
337
|
}
|
|
342
338
|
}
|
|
@@ -363,18 +359,18 @@ function getAttributeInsertPosition(element, openTagRange, index) {
|
|
|
363
359
|
if (index === undefined) {
|
|
364
360
|
// /> or >
|
|
365
361
|
const characterOffset = element.syntax.isSelfClosing === true ? 2 : 1;
|
|
366
|
-
return
|
|
362
|
+
return Position.create(openTagRange.end.line, openTagRange.end.character - characterOffset);
|
|
367
363
|
}
|
|
368
364
|
const attribute = element.attributes[index];
|
|
369
365
|
if (!attribute) {
|
|
370
366
|
return undefined;
|
|
371
367
|
}
|
|
372
|
-
const range =
|
|
368
|
+
const range = transformRange(attribute.position);
|
|
373
369
|
if (!range) {
|
|
374
370
|
return undefined;
|
|
375
371
|
}
|
|
376
372
|
// There must be a space character before attribute and the insert position should be before it
|
|
377
|
-
return
|
|
373
|
+
return Position.create(range.start.line, range.start.character - 1);
|
|
378
374
|
}
|
|
379
375
|
function convertInsertElementToTextEdits(comments, element, changes, childIndentLevel) {
|
|
380
376
|
if (!(element === undefined || element.type === 'XMLElement')) {
|
|
@@ -387,11 +383,11 @@ function convertInsertElementToTextEdits(comments, element, changes, childIndent
|
|
|
387
383
|
const change = changes.slice(-1)[0];
|
|
388
384
|
const namespaceMap = getNamespaceMapForNewRootNode(change.element);
|
|
389
385
|
const newElements = insertElementToText([change], childIndentLevel, namespaceMap);
|
|
390
|
-
return [
|
|
386
|
+
return [TextEdit.insert(Position.create(0, 0), newElements)];
|
|
391
387
|
}
|
|
392
388
|
else {
|
|
393
389
|
const namespaceMap = getNamespaceMap(element);
|
|
394
|
-
const openTagRange =
|
|
390
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
395
391
|
if (element.syntax.isSelfClosing && openTagRange) {
|
|
396
392
|
const newElements = insertElementToText(changes, childIndentLevel, namespaceMap);
|
|
397
393
|
const fragments = ['>', '\n', newElements];
|
|
@@ -400,7 +396,7 @@ function convertInsertElementToTextEdits(comments, element, changes, childIndent
|
|
|
400
396
|
const indent = ' '.repeat(indentLevel);
|
|
401
397
|
fragments.push(`${indent}</${element.name}>`);
|
|
402
398
|
return [
|
|
403
|
-
|
|
399
|
+
TextEdit.replace(Range.create(openTagRange.end.line, openTagRange.end.character - 2, openTagRange.end.line, openTagRange.end.character), fragments.join(''))
|
|
404
400
|
];
|
|
405
401
|
}
|
|
406
402
|
else {
|
|
@@ -419,8 +415,8 @@ function buildInsertFragments(element, anchor, newElements, childIndentLevel) {
|
|
|
419
415
|
fragments.push(newElements);
|
|
420
416
|
if (anchor.requiresNewLine) {
|
|
421
417
|
const childIndent = printOptions.useTabs
|
|
422
|
-
?
|
|
423
|
-
:
|
|
418
|
+
? indentWithTabs(childIndentLevel)
|
|
419
|
+
: indentWithSpaces(printOptions.tabWidth, childIndentLevel);
|
|
424
420
|
fragments.push(childIndent);
|
|
425
421
|
}
|
|
426
422
|
return fragments;
|
|
@@ -440,13 +436,13 @@ function insertIntoElementWithContent(comments, element, changes, childIndentLev
|
|
|
440
436
|
const newElements = insertElementToText(changeSet, childIndentLevel, namespaceMap) + '\n';
|
|
441
437
|
const fragments = buildInsertFragments(element, anchor, newElements, childIndentLevel);
|
|
442
438
|
if (!anchor.requiresNewLine) {
|
|
443
|
-
edits.push(
|
|
439
|
+
edits.push(TextEdit.insert(anchor.position, fragments.join('')));
|
|
444
440
|
continue;
|
|
445
441
|
}
|
|
446
442
|
if (anchor.redundantWhitespace) {
|
|
447
|
-
edits.push(
|
|
443
|
+
edits.push(TextEdit.del(anchor.redundantWhitespace));
|
|
448
444
|
}
|
|
449
|
-
edits.push(
|
|
445
|
+
edits.push(TextEdit.insert(anchor.position, fragments.join('')));
|
|
450
446
|
}
|
|
451
447
|
return edits;
|
|
452
448
|
}
|
|
@@ -466,20 +462,20 @@ function indexInserts(changes) {
|
|
|
466
462
|
}
|
|
467
463
|
function insertElementToText(inserts, childIndentLevel, namespaceMap) {
|
|
468
464
|
return inserts
|
|
469
|
-
.map((change) =>
|
|
465
|
+
.map((change) => printCsdlNodeToXmlString(createElementNode(change.element), printOptions, {
|
|
470
466
|
namespaces: namespaceMap,
|
|
471
467
|
cursorIndentLevel: childIndentLevel
|
|
472
468
|
}))
|
|
473
469
|
.join('\n');
|
|
474
470
|
}
|
|
475
471
|
function replaceElementToText(change, childIndentLevel, namespaceMap) {
|
|
476
|
-
return
|
|
472
|
+
return printCsdlNodeToXmlString(createElementNode(change.newElement), printOptions, {
|
|
477
473
|
namespaces: namespaceMap,
|
|
478
474
|
cursorIndentLevel: childIndentLevel
|
|
479
475
|
}).trim();
|
|
480
476
|
}
|
|
481
477
|
function replaceElementContentToText(change, childIndentLevel, namespaceMap) {
|
|
482
|
-
return
|
|
478
|
+
return printCsdlNodeToXmlString(change.newValue, printOptions, {
|
|
483
479
|
namespaces: namespaceMap,
|
|
484
480
|
cursorIndentLevel: childIndentLevel
|
|
485
481
|
}).trim();
|
|
@@ -499,16 +495,16 @@ function findInsertPosition(comments, element, index = -1) {
|
|
|
499
495
|
// If we are not on the same line as the starting anchor,
|
|
500
496
|
// then it means there should be only whitespace until the start of the line
|
|
501
497
|
// and we can insert the snippet there
|
|
502
|
-
const position = requiresNewLine ? anchorPosition :
|
|
503
|
-
const redundantWhitespace = requiresNewLine ?
|
|
498
|
+
const position = requiresNewLine ? anchorPosition : Position.create(anchorPosition.line, 0);
|
|
499
|
+
const redundantWhitespace = requiresNewLine ? Range.create(startAnchorRange.end, anchorPosition) : undefined;
|
|
504
500
|
return { type: 'child', position, requiresNewLine, redundantWhitespace };
|
|
505
501
|
}
|
|
506
|
-
const closeTagRange =
|
|
502
|
+
const closeTagRange = transformRange(element.syntax.closeBody);
|
|
507
503
|
const startAnchorRange = findStartAnchorRange(element, element.subElements.length);
|
|
508
504
|
if (closeTagRange && startAnchorRange) {
|
|
509
505
|
const anchorPosition = closeTagRange.start;
|
|
510
506
|
const requiresNewLine = anchorPosition.line === startAnchorRange.end.line;
|
|
511
|
-
const position = requiresNewLine ? anchorPosition :
|
|
507
|
+
const position = requiresNewLine ? anchorPosition : Position.create(anchorPosition.line, 0);
|
|
512
508
|
return { type: 'parent', position, requiresNewLine: false };
|
|
513
509
|
}
|
|
514
510
|
return { type: 'none' };
|
|
@@ -524,7 +520,7 @@ function findInsertPosition(comments, element, index = -1) {
|
|
|
524
520
|
function findStartAnchorRange(parent, index) {
|
|
525
521
|
const previousElement = parent.subElements[index - 1];
|
|
526
522
|
if (index === 0) {
|
|
527
|
-
return
|
|
523
|
+
return transformRange(parent.syntax.openBody);
|
|
528
524
|
}
|
|
529
525
|
if (previousElement) {
|
|
530
526
|
return sourcePositionToRange(previousElement.position);
|
|
@@ -549,13 +545,13 @@ function findComment(comments, range) {
|
|
|
549
545
|
return undefined;
|
|
550
546
|
}
|
|
551
547
|
function sourcePositionToRange(position) {
|
|
552
|
-
return
|
|
548
|
+
return Range.create(position.startLine - 1, position.startColumn - 1, position.endLine - 1, position.endColumn);
|
|
553
549
|
}
|
|
554
550
|
function getIndentFromElement(element) {
|
|
555
551
|
if (element?.type === 'XMLElement') {
|
|
556
|
-
const openTagRange =
|
|
552
|
+
const openTagRange = transformRange(element.syntax.openBody);
|
|
557
553
|
if (openTagRange) {
|
|
558
|
-
return
|
|
554
|
+
return getIndentLevel(openTagRange.start.character, printOptions.tabWidth) + 1;
|
|
559
555
|
}
|
|
560
556
|
}
|
|
561
557
|
return 0;
|
|
@@ -577,7 +573,7 @@ function createElementRanges(document, pointers) {
|
|
|
577
573
|
return acc;
|
|
578
574
|
}, new Map());
|
|
579
575
|
for (const [containerPath, indices] of groups) {
|
|
580
|
-
const parent =
|
|
576
|
+
const parent = getNodeFromPointer(document, containerPath);
|
|
581
577
|
if (parent?.type === 'XMLElement') {
|
|
582
578
|
indices.sort((index1, index2) => index1 - index2);
|
|
583
579
|
for (let i = 1, start = indices[0], end = indices[0]; i <= indices.length; i++) {
|
|
@@ -601,7 +597,7 @@ function createElementRanges(document, pointers) {
|
|
|
601
597
|
return ranges;
|
|
602
598
|
}
|
|
603
599
|
function getElementContent(element, comments) {
|
|
604
|
-
const range =
|
|
600
|
+
const range = transformRange(element.position);
|
|
605
601
|
if (!range) {
|
|
606
602
|
return [];
|
|
607
603
|
}
|
|
@@ -614,7 +610,7 @@ function getElementContent(element, comments) {
|
|
|
614
610
|
content.push(item);
|
|
615
611
|
continue;
|
|
616
612
|
}
|
|
617
|
-
const range =
|
|
613
|
+
const range = transformRange(item.position);
|
|
618
614
|
if (!range) {
|
|
619
615
|
continue;
|
|
620
616
|
}
|
|
@@ -622,7 +618,7 @@ function getElementContent(element, comments) {
|
|
|
622
618
|
type: 'element',
|
|
623
619
|
element: item,
|
|
624
620
|
elementRange: range,
|
|
625
|
-
range:
|
|
621
|
+
range: copyRange(range)
|
|
626
622
|
};
|
|
627
623
|
const previousItem = content[content.length - 1];
|
|
628
624
|
const previousLine = element.range.start.line - 1;
|
|
@@ -643,28 +639,28 @@ function getElementContent(element, comments) {
|
|
|
643
639
|
return content;
|
|
644
640
|
}
|
|
645
641
|
function isCommentInContent(range, comment, element) {
|
|
646
|
-
return (
|
|
642
|
+
return (rangeContained(range, comment.range) &&
|
|
647
643
|
!element.subElements.some((item) => {
|
|
648
|
-
const subElementRange =
|
|
644
|
+
const subElementRange = transformRange(item.position);
|
|
649
645
|
if (!subElementRange) {
|
|
650
646
|
return false;
|
|
651
647
|
}
|
|
652
|
-
return
|
|
648
|
+
return rangeContained(subElementRange, comment.range);
|
|
653
649
|
}));
|
|
654
650
|
}
|
|
655
651
|
function compareRange(a, b) {
|
|
656
|
-
const aRange = a.range ??
|
|
657
|
-
const bRange = b.range ??
|
|
652
|
+
const aRange = a.range ?? transformRange(a.syntax?.closeBody ?? a.syntax?.openBody);
|
|
653
|
+
const bRange = b.range ?? transformRange(b.syntax?.closeBody ?? b.syntax?.openBody);
|
|
658
654
|
if (!aRange) {
|
|
659
655
|
return 1;
|
|
660
656
|
}
|
|
661
657
|
if (!bRange) {
|
|
662
658
|
return -1;
|
|
663
659
|
}
|
|
664
|
-
if (
|
|
660
|
+
if (isBefore(aRange.start, bRange.start)) {
|
|
665
661
|
return -1;
|
|
666
662
|
}
|
|
667
|
-
else if (
|
|
663
|
+
else if (isBefore(bRange.start, aRange.start)) {
|
|
668
664
|
return 1;
|
|
669
665
|
}
|
|
670
666
|
return 0;
|
|
@@ -701,22 +697,22 @@ function getRangeForMove(content, parent, start, end) {
|
|
|
701
697
|
let startPosition = getStartAnchor(content, parent, previousContentIndex, startContentIndex)?.start;
|
|
702
698
|
let endPosition = endElement?.range?.end;
|
|
703
699
|
if (startPosition) {
|
|
704
|
-
startPosition =
|
|
700
|
+
startPosition = copyPosition(startPosition);
|
|
705
701
|
}
|
|
706
702
|
if (endPosition) {
|
|
707
|
-
endPosition =
|
|
703
|
+
endPosition = copyPosition(endPosition);
|
|
708
704
|
}
|
|
709
705
|
if (!startPosition || !endElement) {
|
|
710
706
|
return undefined;
|
|
711
707
|
}
|
|
712
|
-
return
|
|
708
|
+
return Range.create(startPosition, endPosition);
|
|
713
709
|
}
|
|
714
710
|
function getStartAnchor(content, parent, previous, index) {
|
|
715
711
|
const previousElement = content[previous];
|
|
716
|
-
let startPosition = index === 0 ?
|
|
712
|
+
let startPosition = index === 0 ? transformRange(parent.syntax.openBody)?.end : previousElement?.range?.end;
|
|
717
713
|
const item = content[index];
|
|
718
714
|
if (startPosition) {
|
|
719
|
-
startPosition =
|
|
715
|
+
startPosition = copyPosition(startPosition);
|
|
720
716
|
}
|
|
721
717
|
if (!startPosition || !item) {
|
|
722
718
|
return undefined;
|
|
@@ -726,7 +722,7 @@ function getStartAnchor(content, parent, previous, index) {
|
|
|
726
722
|
// multiple comments between previous item and starting item -> ignore them
|
|
727
723
|
updatePosition(startPosition, previousItem.range.end);
|
|
728
724
|
}
|
|
729
|
-
return
|
|
725
|
+
return Range.create(startPosition, copyPosition(item.range.end));
|
|
730
726
|
}
|
|
731
727
|
function updatePosition(a, b) {
|
|
732
728
|
a.line = b.line;
|
|
@@ -751,7 +747,7 @@ function adjustRangeByComments(comments, range) {
|
|
|
751
747
|
}
|
|
752
748
|
function findInsertPositionForMove(index, element, comments) {
|
|
753
749
|
if (index === 0) {
|
|
754
|
-
const range =
|
|
750
|
+
const range = transformRange(element.syntax.openBody);
|
|
755
751
|
return range?.end;
|
|
756
752
|
}
|
|
757
753
|
else if (index === undefined || index >= element.subElements.length) {
|
|
@@ -760,7 +756,7 @@ function findInsertPositionForMove(index, element, comments) {
|
|
|
760
756
|
return undefined;
|
|
761
757
|
}
|
|
762
758
|
// self closed elements only have "openBody"
|
|
763
|
-
const range =
|
|
759
|
+
const range = transformRange(child.syntax.closeBody ?? child.syntax.openBody);
|
|
764
760
|
adjustRangeByComments(comments, range);
|
|
765
761
|
return range?.end;
|
|
766
762
|
}
|
|
@@ -768,7 +764,7 @@ function findInsertPositionForMove(index, element, comments) {
|
|
|
768
764
|
const child = element.subElements[index - 1];
|
|
769
765
|
// end of the previous element
|
|
770
766
|
// self closed elements only have "openBody"
|
|
771
|
-
const range =
|
|
767
|
+
const range = transformRange(child.syntax.closeBody ?? child.syntax.openBody);
|
|
772
768
|
adjustRangeByComments(comments, range);
|
|
773
769
|
return range?.end;
|
|
774
770
|
}
|
|
@@ -777,15 +773,15 @@ function findInsertPositionForMove(index, element, comments) {
|
|
|
777
773
|
function getNamespaceMap(parent) {
|
|
778
774
|
const map = {};
|
|
779
775
|
for (const alias of Object.keys(parent.namespaces)) {
|
|
780
|
-
if (alias ===
|
|
776
|
+
if (alias === DEFAULT_NS) {
|
|
781
777
|
continue;
|
|
782
778
|
}
|
|
783
779
|
const namespace = parent.namespaces[alias];
|
|
784
|
-
if (namespace ===
|
|
785
|
-
map[
|
|
780
|
+
if (namespace === EDMX_V4_NAMESPACE) {
|
|
781
|
+
map[EDMX_NAMESPACE_ALIAS] = alias;
|
|
786
782
|
}
|
|
787
|
-
else if (namespace ===
|
|
788
|
-
map[
|
|
783
|
+
else if (namespace === EDM_V4_NAMESPACE) {
|
|
784
|
+
map[EDM_NAMESPACE_ALIAS] = alias;
|
|
789
785
|
}
|
|
790
786
|
}
|
|
791
787
|
return map;
|
|
@@ -801,11 +797,11 @@ function getNamespaceMapForNewRootNode(element) {
|
|
|
801
797
|
if (alias === undefined) {
|
|
802
798
|
continue;
|
|
803
799
|
}
|
|
804
|
-
if (namespace ===
|
|
805
|
-
map[
|
|
800
|
+
if (namespace === EDMX_V4_NAMESPACE) {
|
|
801
|
+
map[EDMX_NAMESPACE_ALIAS] = alias;
|
|
806
802
|
}
|
|
807
|
-
else if (namespace ===
|
|
808
|
-
map[
|
|
803
|
+
else if (namespace === EDM_V4_NAMESPACE) {
|
|
804
|
+
map[EDM_NAMESPACE_ALIAS] = alias;
|
|
809
805
|
}
|
|
810
806
|
}
|
|
811
807
|
return map;
|
|
@@ -827,7 +823,7 @@ function combineInsertsWithDeletions(changes, document) {
|
|
|
827
823
|
continue;
|
|
828
824
|
}
|
|
829
825
|
// merge inserts and deletions
|
|
830
|
-
const element =
|
|
826
|
+
const element = getNodeFromPointer(document, change.pointer);
|
|
831
827
|
if (element?.type !== 'XMLElement') {
|
|
832
828
|
continue;
|
|
833
829
|
}
|