Skip to content

Verifier: Support line numbers in fix-it verification #39572

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/swift/AST/DiagnosticConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ struct DiagnosticInfo {
public:
FixIt(CharSourceRange R, StringRef Str, ArrayRef<DiagnosticArgument> Args);

CharSourceRange getRange() const { return Range; }
CharSourceRange &getRange() { return Range; }
const CharSourceRange &getRange() const { return Range; }

StringRef getText() const { return Text; }
};

Expand Down
3 changes: 3 additions & 0 deletions include/swift/Basic/SourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ class SourceManager {
return LLVMSourceMgr.getLineAndColumn(Loc.Value, BufferID);
}

/// Returns the column for the given source location in the given buffer.
unsigned getColumnInBuffer(SourceLoc Loc, unsigned BufferID) const;

StringRef getEntireTextForBuffer(unsigned BufferID) const;

StringRef extractText(CharSourceRange Range,
Expand Down
42 changes: 37 additions & 5 deletions include/swift/Frontend/DiagnosticVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,53 @@ bool verifyDependencies(SourceManager &SM, ArrayRef<SourceFile *> SFs);
// MARK: - DiagnosticVerifier
struct ExpectedFixIt;

/// A range expressed in terms of line-and-column pairs.
struct LineColumnRange {
static constexpr unsigned NoValue = ~0u;

unsigned StartLine, StartCol;
unsigned EndLine, EndCol;

LineColumnRange()
: StartLine(NoValue), StartCol(NoValue), EndLine(NoValue),
EndCol(NoValue) {}
};

class CapturedFixItInfo final {
DiagnosticInfo::FixIt FixIt;
mutable LineColumnRange LineColRange;

public:
CapturedFixItInfo(DiagnosticInfo::FixIt FixIt) : FixIt(FixIt) {}

CharSourceRange &getSourceRange() { return FixIt.getRange(); }
const CharSourceRange &getSourceRange() const { return FixIt.getRange(); }

StringRef getText() const { return FixIt.getText(); }

/// Obtain the line-column range corresponding to the fix-it's
/// replacement range.
const LineColumnRange &getLineColumnRange(const SourceManager &SM,
unsigned BufferID,
bool ComputeStartLocLine,
bool ComputeEndLocLine) const;
};

struct CapturedDiagnosticInfo {
llvm::SmallString<128> Message;
llvm::SmallString<32> FileName;
DiagnosticKind Classification;
SourceLoc Loc;
unsigned Line;
unsigned Column;
SmallVector<DiagnosticInfo::FixIt, 2> FixIts;
SmallVector<CapturedFixItInfo, 2> FixIts;
SmallVector<std::string, 1> EducationalNotes;

CapturedDiagnosticInfo(llvm::SmallString<128> Message,
llvm::SmallString<32> FileName,
DiagnosticKind Classification, SourceLoc Loc,
unsigned Line, unsigned Column,
SmallVector<DiagnosticInfo::FixIt, 2> FixIts,
SmallVector<CapturedFixItInfo, 2> FixIts,
SmallVector<std::string, 1> EducationalNotes)
: Message(Message), FileName(FileName), Classification(Classification),
Loc(Loc), Line(Line), Column(Column), FixIts(FixIts),
Expand Down Expand Up @@ -101,11 +133,11 @@ class DiagnosticVerifier : public DiagnosticConsumer {
Result verifyFile(unsigned BufferID);

bool checkForFixIt(const ExpectedFixIt &Expected,
const CapturedDiagnosticInfo &D, StringRef buffer);
const CapturedDiagnosticInfo &D, unsigned BufferID) const;

// Render the verifier syntax for a given set of fix-its.
std::string renderFixits(ArrayRef<DiagnosticInfo::FixIt> fixits,
StringRef InputFile);
std::string renderFixits(ArrayRef<CapturedFixItInfo> ActualFixIts,
unsigned BufferID, unsigned DiagnosticLineNo) const;

void printRemainingDiagnostics() const;
};
Expand Down
17 changes: 17 additions & 0 deletions lib/Basic/SourceLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,23 @@ unsigned SourceManager::getByteDistance(SourceLoc Start, SourceLoc End) const {
return End.Value.getPointer() - Start.Value.getPointer();
}

unsigned SourceManager::getColumnInBuffer(SourceLoc Loc,
unsigned BufferID) const {
assert(Loc.isValid());

const StringRef Buffer = getEntireTextForBuffer(BufferID);
const char *Ptr = static_cast<const char *>(Loc.getOpaquePointerValue());

StringRef UpToLoc = Buffer.slice(0, Ptr - Buffer.data());

size_t ColumnNo = UpToLoc.size();
size_t NewlinePos = UpToLoc.find_last_of("\r\n");
if (NewlinePos != StringRef::npos)
ColumnNo -= NewlinePos;

return static_cast<unsigned>(ColumnNo);
}

StringRef SourceManager::getEntireTextForBuffer(unsigned BufferID) const {
return LLVMSourceMgr.getMemoryBuffer(BufferID)->getBuffer();
}
Expand Down
Loading