From 5775d27e32034d2712902011f05c713f95698aba Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 14 Mar 2017 17:08:35 -0700 Subject: [PATCH] respect initial order of changes --- src/harness/unittests/textChanges.ts | 17 +++++++++++++++ src/services/textChanges.ts | 14 +++++++------ .../insertNodeAfterMultipleNodes.js | 21 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js diff --git a/src/harness/unittests/textChanges.ts b/src/harness/unittests/textChanges.ts index 61f6d738e57..8724f7aa392 100644 --- a/src/harness/unittests/textChanges.ts +++ b/src/harness/unittests/textChanges.ts @@ -650,5 +650,22 @@ import { changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a"))); }) } + { + const text = ` +class A { + x; +}`; + runSingleFileTest("insertNodeAfterMultipleNodes", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => { + let newNodes = []; + for (let i = 0; i < 11 /*error doesn't occur with fewer nodes*/; ++i) { + newNodes.push( + createProperty(undefined, undefined, i + "", undefined, undefined, undefined)); + } + const insertAfter = findChild("x", sourceFile); + for (const newNode of newNodes) { + changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: newLineCharacter }); + } + }); + } }); } \ No newline at end of file diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 174f2969a00..bb310657b60 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -407,10 +407,8 @@ namespace ts.textChanges { changesPerFile.forEachValue(path => { const changesInFile = changesPerFile.get(path); const sourceFile = changesInFile[0].sourceFile; - ChangeTracker.normalize(changesInFile); - const fileTextChanges: FileTextChanges = { fileName: sourceFile.fileName, textChanges: [] }; - for (const c of changesInFile) { + for (const c of ChangeTracker.normalize(changesInFile)) { fileTextChanges.textChanges.push({ span: this.computeSpan(c, sourceFile), newText: this.computeNewText(c, sourceFile) @@ -463,11 +461,15 @@ namespace ts.textChanges { private static normalize(changes: Change[]) { // order changes by start position - changes.sort((a, b) => a.range.pos - b.range.pos); + const normalized = changes + .map((c, i) => ({ c, i })) + .sort(({ c: a, i: i1 }, { c: b, i: i2 }) => (a.range.pos - b.range.pos) || i1 - i2) + .map(({ c }) => c); // verify that end position of the change is less than start position of the next change - for (let i = 0; i < changes.length - 2; i++) { - Debug.assert(changes[i].range.end <= changes[i + 1].range.pos); + for (let i = 0; i < normalized.length - 2; i++) { + Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos); } + return normalized; } } diff --git a/tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js b/tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js new file mode 100644 index 00000000000..1c3bbe4d3e2 --- /dev/null +++ b/tests/baselines/reference/textChanges/insertNodeAfterMultipleNodes.js @@ -0,0 +1,21 @@ +===ORIGINAL=== + +class A { + x; +} +===MODIFIED=== + +class A { + x; + 0; + 1; + 2; + 3; + 4; + 5; + 6; + 7; + 8; + 9; + 10; +} \ No newline at end of file