Skip to content

Commit febb019

Browse files
committed
Avoid storing a SourceManager on JSONFixitWriter
Switch to storing the necessary edit information instead.
1 parent 746128c commit febb019

File tree

4 files changed

+51
-29
lines changed

4 files changed

+51
-29
lines changed

include/swift/Basic/Edit.h

+19-5
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,34 @@
1313
#ifndef SWIFT_BASIC_EDIT_H
1414
#define SWIFT_BASIC_EDIT_H
1515

16+
#include "llvm/ADT/ArrayRef.h"
1617
#include "swift/Basic/LLVM.h"
1718
#include "swift/Basic/SourceLoc.h"
1819

1920
namespace swift {
2021
class SourceManager;
2122
class CharSourceRange;
2223

23-
struct SingleEdit {
24-
SourceManager &SM;
25-
CharSourceRange Range;
26-
std::string Text;
24+
/// A set of edits made to a source file.
25+
class SourceEdits final {
26+
public:
27+
struct Edit {
28+
std::string Path;
29+
std::string Text;
30+
unsigned Offset;
31+
unsigned Length;
32+
};
33+
34+
private:
35+
std::vector<Edit> Edits;
36+
37+
public:
38+
ArrayRef<Edit> getEdits() const { return Edits; }
39+
40+
void addEdit(SourceManager &SM, CharSourceRange Range, StringRef Text);
2741
};
2842

29-
void writeEditsInJson(ArrayRef<SingleEdit> Edits, llvm::raw_ostream &OS);
43+
void writeEditsInJson(const SourceEdits &Edits, llvm::raw_ostream &OS);
3044
}
3145

3246
#endif // SWIFT_BASIC_EDIT_H

lib/Basic/Edit.cpp

+26-17
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,37 @@
1414
#include "swift/Basic/Edit.h"
1515
#include "swift/Basic/SourceManager.h"
1616

17+
using namespace swift;
18+
19+
void SourceEdits::addEdit(SourceManager &SM, CharSourceRange Range,
20+
StringRef Text) {
21+
SourceLoc Loc = Range.getStart();
22+
unsigned BufID = SM.findBufferContainingLoc(Loc);
23+
unsigned Offset = SM.getLocOffsetInBuffer(Loc, BufID);
24+
unsigned Length = Range.getByteLength();
25+
StringRef Path = SM.getIdentifierForBuffer(BufID);
26+
27+
// NOTE: We cannot store SourceManager here since this logic is used by a
28+
// DiagnosticConsumer where the SourceManager may not remain valid. This is
29+
// the case when e.g build swift interfaces, we create a fresh
30+
// CompilerInstance for a limited scope, but diagnostics are passed outside of
31+
// it.
32+
Edits.push_back({Path.str(), Text.str(), Offset, Length});
33+
}
34+
1735
void swift::
18-
writeEditsInJson(ArrayRef<SingleEdit> AllEdits, llvm::raw_ostream &OS) {
36+
writeEditsInJson(const SourceEdits &AllEdits, llvm::raw_ostream &OS) {
1937
OS << "[\n";
20-
for (auto &Edit : AllEdits) {
21-
SourceManager &SM = Edit.SM;
22-
CharSourceRange Range = Edit.Range;
23-
StringRef Text = Edit.Text;
24-
SourceLoc Loc = Range.getStart();
25-
unsigned BufID = SM.findBufferContainingLoc(Loc);
26-
unsigned Offset = SM.getLocOffsetInBuffer(Loc, BufID);
27-
unsigned Length = Range.getByteLength();
28-
StringRef Path(SM.getIdentifierForBuffer(BufID));
29-
38+
for (auto &Edit : AllEdits.getEdits()) {
3039
OS << " {\n";
3140
OS << " \"file\": \"";
32-
OS.write_escaped(Path) << "\",\n";
33-
OS << " \"offset\": " << Offset << ",\n";
34-
if (Length != 0)
35-
OS << " \"remove\": " << Length << ",\n";
36-
if (!Text.empty()) {
41+
OS.write_escaped(Edit.Path) << "\",\n";
42+
OS << " \"offset\": " << Edit.Offset << ",\n";
43+
if (Edit.Length != 0)
44+
OS << " \"remove\": " << Edit.Length << ",\n";
45+
if (!Edit.Text.empty()) {
3746
OS << " \"text\": \"";
38-
OS.write_escaped(Text) << "\",\n";
47+
OS.write_escaped(Edit.Text) << "\",\n";
3948
}
4049
OS << " },\n";
4150
}

lib/FrontendTool/FrontendTool.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class JSONFixitWriter
216216
std::string FixitsOutputPath;
217217
std::unique_ptr<llvm::raw_ostream> OSPtr;
218218
bool FixitAll;
219-
std::vector<SingleEdit> AllEdits;
219+
SourceEdits AllEdits;
220220

221221
public:
222222
JSONFixitWriter(std::string fixitsOutputPath,
@@ -229,9 +229,8 @@ class JSONFixitWriter
229229
const DiagnosticInfo &Info) override {
230230
if (!(FixitAll || shouldTakeFixit(Info)))
231231
return;
232-
for (const auto &Fix : Info.FixIts) {
233-
AllEdits.push_back({SM, Fix.getRange(), Fix.getText().str()});
234-
}
232+
for (const auto &Fix : Info.FixIts)
233+
AllEdits.addEdit(SM, Fix.getRange(), Fix.getText());
235234
}
236235

237236
bool finishProcessing() override {
@@ -251,7 +250,7 @@ class JSONFixitWriter
251250
return true;
252251
}
253252

254-
swift::writeEditsInJson(llvm::makeArrayRef(AllEdits), *OS);
253+
swift::writeEditsInJson(AllEdits, *OS);
255254
return false;
256255
}
257256
};

lib/IDE/Utils.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -722,14 +722,14 @@ void swift::ide::SourceEditConsumer::acceptMacroExpansionBuffer(
722722

723723
struct swift::ide::SourceEditJsonConsumer::Implementation {
724724
llvm::raw_ostream &OS;
725-
std::vector<SingleEdit> AllEdits;
725+
SourceEdits AllEdits;
726726
Implementation(llvm::raw_ostream &OS) : OS(OS) {}
727727
~Implementation() {
728728
writeEditsInJson(AllEdits, OS);
729729
}
730730
void accept(SourceManager &SM, CharSourceRange Range,
731731
llvm::StringRef Text) {
732-
AllEdits.push_back({SM, Range, Text.str()});
732+
AllEdits.addEdit(SM, Range, Text);
733733
}
734734
};
735735

0 commit comments

Comments
 (0)