1313#include " llvm/Support/raw_ostream.h"
1414#include " swift/Basic/Edit.h"
1515#include " swift/Basic/SourceManager.h"
16+ #include < algorithm>
1617
1718using namespace swift ;
1819
@@ -34,8 +35,42 @@ void SourceEdits::addEdit(SourceManager &SM, CharSourceRange Range,
3435
3536void swift::
3637writeEditsInJson (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 " ;
3974 OS << " {\n " ;
4075 OS << " \" file\" : \" " ;
4176 OS.write_escaped (Edit.Path ) << " \" ,\n " ;
@@ -44,9 +79,9 @@ writeEditsInJson(const SourceEdits &AllEdits, llvm::raw_ostream &OS) {
4479 OS << " \" remove\" : " << Edit.Length << " ,\n " ;
4580 if (!Edit.Text .empty ()) {
4681 OS << " \" text\" : \" " ;
47- OS.write_escaped (Edit.Text ) << " \" , \n " ;
82+ OS.write_escaped (Edit.Text ) << " \"\n " ;
4883 }
49- OS << " }, \n " ;
84+ OS << " }" ;
5085 }
51- OS << " ]\n " ;
86+ OS << " \n ]\n " ;
5287}
0 commit comments