Index: pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart |
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart |
index 66860037644c9979a7c26d9b93880d5ee2c7f362..e95657d4736f7fba8bbc0de1fec4719940657882 100644 |
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart |
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart |
@@ -3,6 +3,7 @@ |
// BSD-style license that can be found in the LICENSE file. |
import 'dart:async'; |
+import 'dart:math' as math; |
import 'package:analyzer/src/generated/source.dart'; |
import 'package:analyzer_plugin/protocol/protocol_common.dart'; |
@@ -77,6 +78,29 @@ class ChangeBuilderImpl implements ChangeBuilder { |
void setSelection(Position position) { |
_change.selection = position; |
} |
+ |
+ /** |
+ * Update the offsets of any positions that occur at or after the given |
+ * [offset] such that the positions are offset by the given [delta]. Positions |
+ * occur in linked edit groups and as the post-change selection. |
+ */ |
+ void _updatePositions(int offset, int delta) { |
+ void _updatePosition(Position position) { |
+ if (position.offset >= offset) { |
+ position.offset = position.offset + delta; |
+ } |
+ } |
+ |
+ for (LinkedEditGroup group in _linkedEditGroups.values) { |
+ for (Position position in group.positions) { |
+ _updatePosition(position); |
+ } |
+ } |
+ Position selection = _change.selection; |
+ if (selection != null) { |
+ _updatePosition(selection); |
+ } |
+ } |
} |
/** |
@@ -219,7 +243,7 @@ class FileEditBuilderImpl implements FileEditBuilder { |
@override |
void addDeletion(SourceRange range) { |
EditBuilderImpl builder = createEditBuilder(range.offset, range.length); |
- fileEdit.add(builder.sourceEdit); |
+ _addEdit(builder); |
} |
@override |
@@ -228,9 +252,7 @@ class FileEditBuilderImpl implements FileEditBuilder { |
try { |
buildEdit(builder); |
} finally { |
- SourceEdit edit = builder.sourceEdit; |
- fileEdit.add(edit); |
- _captureSelection(builder, edit); |
+ _addEdit(builder); |
} |
} |
@@ -248,9 +270,7 @@ class FileEditBuilderImpl implements FileEditBuilder { |
try { |
buildEdit(builder); |
} finally { |
- SourceEdit edit = builder.sourceEdit; |
- fileEdit.add(edit); |
- _captureSelection(builder, edit); |
+ _addEdit(builder); |
} |
} |
@@ -260,9 +280,7 @@ class FileEditBuilderImpl implements FileEditBuilder { |
try { |
builder.write(text); |
} finally { |
- SourceEdit edit = builder.sourceEdit; |
- fileEdit.add(edit); |
- _captureSelection(builder, edit); |
+ _addEdit(builder); |
} |
} |
@@ -272,9 +290,7 @@ class FileEditBuilderImpl implements FileEditBuilder { |
try { |
builder.write(text); |
} finally { |
- SourceEdit edit = builder.sourceEdit; |
- fileEdit.add(edit); |
- _captureSelection(builder, edit); |
+ _addEdit(builder); |
} |
} |
@@ -290,6 +306,18 @@ class FileEditBuilderImpl implements FileEditBuilder { |
} |
/** |
+ * Add the edit from the given [builder] to the edits associates with the |
+ * current file. |
+ */ |
+ void _addEdit(EditBuilderImpl builder) { |
+ SourceEdit edit = builder.sourceEdit; |
+ fileEdit.add(edit); |
+ int delta = _editDelta(edit); |
+ changeBuilder._updatePositions(edit.offset + math.max(0, delta), delta); |
+ _captureSelection(builder, edit); |
+ } |
+ |
+ /** |
* Capture the selection offset if one was set. |
*/ |
void _captureSelection(EditBuilderImpl builder, SourceEdit edit) { |
@@ -312,7 +340,7 @@ class FileEditBuilderImpl implements FileEditBuilder { |
int delta = 0; |
for (SourceEdit edit in fileEdit.edits) { |
if (edit.offset < targetEdit.offset) { |
- delta += edit.replacement.length - edit.length; |
+ delta += _editDelta(edit); |
} |
} |
return delta; |
@@ -328,11 +356,16 @@ class FileEditBuilderImpl implements FileEditBuilder { |
int delta = 0; |
for (SourceEdit edit in fileEdit.edits) { |
if (edit.offset <= offset) { |
- delta += edit.replacement.length - edit.length; |
+ delta += _editDelta(edit); |
} |
} |
return delta; |
} |
+ |
+ /** |
+ * Return the delta introduced by the given `edit`. |
+ */ |
+ int _editDelta(SourceEdit edit) => edit.replacement.length - edit.length; |
} |
/** |