Avoid storing a SourceManager on JSONFixitWriter

Switch to storing the necessary edit information
instead.
This commit is contained in:
Hamish Knight
2023-09-15 18:27:49 +01:00
parent 746128c7aa
commit febb019a86
4 changed files with 52 additions and 30 deletions

View File

@@ -13,6 +13,7 @@
#ifndef SWIFT_BASIC_EDIT_H
#define SWIFT_BASIC_EDIT_H
#include "llvm/ADT/ArrayRef.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SourceLoc.h"
@@ -20,13 +21,26 @@ namespace swift {
class SourceManager;
class CharSourceRange;
struct SingleEdit {
SourceManager &SM;
CharSourceRange Range;
std::string Text;
/// A set of edits made to a source file.
class SourceEdits final {
public:
struct Edit {
std::string Path;
std::string Text;
unsigned Offset;
unsigned Length;
};
private:
std::vector<Edit> Edits;
public:
ArrayRef<Edit> getEdits() const { return Edits; }
void addEdit(SourceManager &SM, CharSourceRange Range, StringRef Text);
};
void writeEditsInJson(ArrayRef<SingleEdit> Edits, llvm::raw_ostream &OS);
void writeEditsInJson(const SourceEdits &Edits, llvm::raw_ostream &OS);
}
#endif // SWIFT_BASIC_EDIT_H

View File

@@ -14,28 +14,37 @@
#include "swift/Basic/Edit.h"
#include "swift/Basic/SourceManager.h"
void swift::
writeEditsInJson(ArrayRef<SingleEdit> AllEdits, llvm::raw_ostream &OS) {
OS << "[\n";
for (auto &Edit : AllEdits) {
SourceManager &SM = Edit.SM;
CharSourceRange Range = Edit.Range;
StringRef Text = Edit.Text;
SourceLoc Loc = Range.getStart();
unsigned BufID = SM.findBufferContainingLoc(Loc);
unsigned Offset = SM.getLocOffsetInBuffer(Loc, BufID);
unsigned Length = Range.getByteLength();
StringRef Path(SM.getIdentifierForBuffer(BufID));
using namespace swift;
void SourceEdits::addEdit(SourceManager &SM, CharSourceRange Range,
StringRef Text) {
SourceLoc Loc = Range.getStart();
unsigned BufID = SM.findBufferContainingLoc(Loc);
unsigned Offset = SM.getLocOffsetInBuffer(Loc, BufID);
unsigned Length = Range.getByteLength();
StringRef Path = SM.getIdentifierForBuffer(BufID);
// NOTE: We cannot store SourceManager here since this logic is used by a
// DiagnosticConsumer where the SourceManager may not remain valid. This is
// the case when e.g build swift interfaces, we create a fresh
// CompilerInstance for a limited scope, but diagnostics are passed outside of
// it.
Edits.push_back({Path.str(), Text.str(), Offset, Length});
}
void swift::
writeEditsInJson(const SourceEdits &AllEdits, llvm::raw_ostream &OS) {
OS << "[\n";
for (auto &Edit : AllEdits.getEdits()) {
OS << " {\n";
OS << " \"file\": \"";
OS.write_escaped(Path) << "\",\n";
OS << " \"offset\": " << Offset << ",\n";
if (Length != 0)
OS << " \"remove\": " << Length << ",\n";
if (!Text.empty()) {
OS.write_escaped(Edit.Path) << "\",\n";
OS << " \"offset\": " << Edit.Offset << ",\n";
if (Edit.Length != 0)
OS << " \"remove\": " << Edit.Length << ",\n";
if (!Edit.Text.empty()) {
OS << " \"text\": \"";
OS.write_escaped(Text) << "\",\n";
OS.write_escaped(Edit.Text) << "\",\n";
}
OS << " },\n";
}

View File

@@ -216,7 +216,7 @@ class JSONFixitWriter
std::string FixitsOutputPath;
std::unique_ptr<llvm::raw_ostream> OSPtr;
bool FixitAll;
std::vector<SingleEdit> AllEdits;
SourceEdits AllEdits;
public:
JSONFixitWriter(std::string fixitsOutputPath,
@@ -229,9 +229,8 @@ private:
const DiagnosticInfo &Info) override {
if (!(FixitAll || shouldTakeFixit(Info)))
return;
for (const auto &Fix : Info.FixIts) {
AllEdits.push_back({SM, Fix.getRange(), Fix.getText().str()});
}
for (const auto &Fix : Info.FixIts)
AllEdits.addEdit(SM, Fix.getRange(), Fix.getText());
}
bool finishProcessing() override {
@@ -251,7 +250,7 @@ private:
return true;
}
swift::writeEditsInJson(llvm::makeArrayRef(AllEdits), *OS);
swift::writeEditsInJson(AllEdits, *OS);
return false;
}
};

View File

@@ -722,14 +722,14 @@ void swift::ide::SourceEditConsumer::acceptMacroExpansionBuffer(
struct swift::ide::SourceEditJsonConsumer::Implementation {
llvm::raw_ostream &OS;
std::vector<SingleEdit> AllEdits;
SourceEdits AllEdits;
Implementation(llvm::raw_ostream &OS) : OS(OS) {}
~Implementation() {
writeEditsInJson(AllEdits, OS);
}
void accept(SourceManager &SM, CharSourceRange Range,
llvm::StringRef Text) {
AllEdits.push_back({SM, Range, Text.str()});
AllEdits.addEdit(SM, Range, Text);
}
};