13
13
#include " llvm/Support/raw_ostream.h"
14
14
#include " swift/Basic/Edit.h"
15
15
#include " swift/Basic/SourceManager.h"
16
+ #include < algorithm>
16
17
17
18
using namespace swift ;
18
19
@@ -34,8 +35,42 @@ void SourceEdits::addEdit(SourceManager &SM, CharSourceRange Range,
34
35
35
36
void swift::
36
37
writeEditsInJson (const SourceEdits &AllEdits, llvm::raw_ostream &OS) {
37
- OS << " [\n " ;
38
- for (auto &Edit : AllEdits.getEdits ()) {
38
+ // Sort the edits so they occur from the last to the first within a given
39
+ // source file. That's the order in which applying non-overlapping edits
40
+ // will succeed.
41
+ std::vector<SourceEdits::Edit> allEdits (AllEdits.getEdits ().begin (),
42
+ AllEdits.getEdits ().end ());
43
+ std::sort (allEdits.begin (), allEdits.end (),
44
+ [&](const SourceEdits::Edit &lhs, const SourceEdits::Edit &rhs) {
45
+ // Sort first based on the path. This keeps the edits for a given
46
+ // file together.
47
+ if (lhs.Path < rhs.Path )
48
+ return true ;
49
+ else if (lhs.Path > rhs.Path )
50
+ return false ;
51
+
52
+ // Then sort based on offset, with larger offsets coming earlier.
53
+ return lhs.Offset > rhs.Offset ;
54
+ });
55
+
56
+ // Remove duplicate edits.
57
+ allEdits.erase (
58
+ std::unique (allEdits.begin (), allEdits.end (),
59
+ [&](const SourceEdits::Edit &lhs, const SourceEdits::Edit &rhs) {
60
+ return lhs.Path == rhs.Path && lhs.Text == rhs.Text &&
61
+ lhs.Offset == rhs.Offset && lhs.Length == rhs.Length ;
62
+ }),
63
+ allEdits.end ());
64
+
65
+ OS << " [" ;
66
+ bool first = true ;
67
+ for (auto &Edit : allEdits) {
68
+ if (first) {
69
+ first = false ;
70
+ } else {
71
+ OS << " ," ;
72
+ }
73
+ OS << " \n " ;
39
74
OS << " {\n " ;
40
75
OS << " \" file\" : \" " ;
41
76
OS.write_escaped (Edit.Path ) << " \" ,\n " ;
@@ -44,9 +79,9 @@ writeEditsInJson(const SourceEdits &AllEdits, llvm::raw_ostream &OS) {
44
79
OS << " \" remove\" : " << Edit.Length << " ,\n " ;
45
80
if (!Edit.Text .empty ()) {
46
81
OS << " \" text\" : \" " ;
47
- OS.write_escaped (Edit.Text ) << " \" , \n " ;
82
+ OS.write_escaped (Edit.Text ) << " \"\n " ;
48
83
}
49
- OS << " }, \n " ;
84
+ OS << " }" ;
50
85
}
51
- OS << " ]\n " ;
86
+ OS << " \n ]\n " ;
52
87
}
0 commit comments