mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Avoid storing a SourceManager on JSONFixitWriter
Switch to storing the necessary edit information instead.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user