Skip to content

Commit

Permalink
libnixf: address comments from @Origami404 (#296)
Browse files Browse the repository at this point in the history
  • Loading branch information
inclyc committed Jan 14, 2024
1 parent ab7a534 commit 371d1b5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 34 deletions.
40 changes: 34 additions & 6 deletions libnixf/include/nixf/Basic/Range.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,44 @@

namespace nixf {

struct Point {
/// \brief A point in the source file.
///
/// This class is used to represent a point in the source file. And it shall be
/// constructed by Lexer, to keep Line & Column information correct.
/// \see Lexer::consume(std::size_t)
class Point {
int64_t Line;
int64_t Column;
std::size_t Offset;
};
friend class Lexer;
Point(int64_t Line, int64_t Column, std::size_t Offset)
: Line(Line), Column(Column), Offset(Offset) {}

inline bool operator==(const Point &LHS, const Point &RHS) {
return LHS.Line == RHS.Line && LHS.Column == RHS.Column &&
LHS.Offset == RHS.Offset;
}
public:
friend bool operator==(const Point &LHS, const Point &RHS) {
return LHS.Line == RHS.Line && LHS.Column == RHS.Column &&
LHS.Offset == RHS.Offset;
}
Point() = default;

/// \brief Check if the point is at the given position.
[[nodiscard]] bool isAt(int64_t Line, int64_t Column,
std::size_t Offset) const {
return this->Line == Line && this->Column == Column &&
this->Offset == Offset;
}

/// \brief Line number, starting from 0.
///
/// Currently we only accept LF as the line terminator.
[[nodiscard]] int64_t line() const { return Line; }

/// \brief Column number, starting from 0.
[[nodiscard]] int64_t column() const { return Column; }

/// \brief Offset in the source file, starting from 0.
[[nodiscard]] std::size_t offset() const { return Offset; }
};

class RangeTy {
Point Begin;
Expand Down
56 changes: 28 additions & 28 deletions libnixf/lib/Parse/test/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ TEST(Parser, Float) {
ASSERT_EQ(Expr->kind(), Node::NK_ExprFloat);
ASSERT_EQ(static_cast<ExprFloat *>(Expr.get())->value(), 1.0);
ASSERT_EQ(Diags.diags().size(), 0);
ASSERT_EQ(Expr->range().begin(), Point(0, 0, 0));
ASSERT_EQ(Expr->range().end(), Point(0, 3, 3));
ASSERT_TRUE(Expr->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(Expr->range().end().isAt(0, 3, 3));
}

TEST(Parser, FloatLeading) {
Expand All @@ -45,8 +45,8 @@ TEST(Parser, FloatLeading) {
// Check the diagnostic.
ASSERT_EQ(Diags.diags().size(), 1);
auto &D = Diags.diags()[0];
ASSERT_EQ(Expr->range().begin(), Point(0, 0, 0));
ASSERT_EQ(Expr->range().end(), Point(0, 4, 4));
ASSERT_TRUE(Expr->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(Expr->range().end().isAt(0, 4, 4));
ASSERT_EQ(D->kind(), Diagnostic::DK_FloatLeadingZero);
ASSERT_EQ(D->args().size(), 1);
ASSERT_EQ(D->args()[0], "01");
Expand All @@ -60,8 +60,8 @@ TEST(Parser, FloatLeading00) {
ASSERT_EQ(Expr->kind(), Node::NK_ExprFloat);
ASSERT_EQ(static_cast<ExprFloat *>(Expr.get())->value(), 0.5);
ASSERT_EQ(Diags.diags().size(), 1);
ASSERT_EQ(Expr->range().begin(), Point(0, 0, 0));
ASSERT_EQ(Expr->range().end(), Point(0, 4, 4));
ASSERT_TRUE(Expr->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(Expr->range().end().isAt(0, 4, 4));
}

TEST(Parser, StringSimple) {
Expand All @@ -71,12 +71,12 @@ TEST(Parser, StringSimple) {
ASSERT_TRUE(Expr);
ASSERT_EQ(Expr->kind(), Node::NK_ExprString);
auto Parts = static_cast<ExprString *>(Expr.get())->parts();
ASSERT_EQ(Parts->range().begin(), Point(0, 1, 1));
ASSERT_EQ(Parts->range().end(), Point(0, 4, 4));
ASSERT_TRUE(Parts->range().begin().isAt(0, 1, 1));
ASSERT_TRUE(Parts->range().end().isAt(0, 4, 4));
ASSERT_EQ(Parts->fragments().size(), 1);
ASSERT_EQ(Diags.diags().size(), 0);
ASSERT_EQ(Expr->range().begin(), Point(0, 0, 0));
ASSERT_EQ(Expr->range().end(), Point(0, 5, 5));
ASSERT_TRUE(Expr->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(Expr->range().end().isAt(0, 5, 5));
}

TEST(Parser, StringMissingDQuote) {
Expand All @@ -86,33 +86,33 @@ TEST(Parser, StringMissingDQuote) {
ASSERT_TRUE(Expr);
ASSERT_EQ(Expr->kind(), Node::NK_ExprString);
auto Parts = static_cast<ExprString *>(Expr.get())->parts();
ASSERT_EQ(Parts->range().begin(), Point(0, 1, 1));
ASSERT_EQ(Parts->range().end(), Point(0, 4, 4));
ASSERT_TRUE(Parts->range().begin().isAt(0, 1, 1));
ASSERT_TRUE(Parts->range().end().isAt(0, 4, 4));
ASSERT_EQ(Parts->fragments().size(), 1);

// Check the diagnostic.
ASSERT_EQ(Diags.diags().size(), 1);
auto &D = Diags.diags()[0];
ASSERT_EQ(Expr->range().begin(), Point(0, 0, 0));
ASSERT_EQ(Expr->range().end(), Point(0, 4, 4));
ASSERT_TRUE(Expr->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(Expr->range().end().isAt(0, 4, 4));
ASSERT_EQ(D->kind(), Diagnostic::DK_Expected);
ASSERT_EQ(D->args().size(), 1);
ASSERT_EQ(D->args()[0], "\"");

// Check the note.
ASSERT_EQ(D->notes().size(), 1);
auto &N = D->notes()[0];
ASSERT_EQ(N->range().begin(), Point(0, 0, 0));
ASSERT_EQ(N->range().end(), Point(0, 1, 1));
ASSERT_TRUE(N->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(N->range().end().isAt(0, 1, 1));
ASSERT_EQ(N->kind(), Note::NK_ToMachThis);
ASSERT_EQ(N->args().size(), 1);
ASSERT_EQ(N->args()[0], "\"");

// Check fix-it hints.
ASSERT_EQ(D->fixes().size(), 1);
const auto &F = D->fixes()[0];
ASSERT_EQ(F.oldRange().begin(), Point(0, 4, 4));
ASSERT_EQ(F.oldRange().end(), Point(0, 4, 4));
ASSERT_TRUE(F.oldRange().begin().isAt(0, 4, 4));
ASSERT_TRUE(F.oldRange().end().isAt(0, 4, 4));
ASSERT_EQ(F.newText(), "\"");
}

Expand All @@ -123,17 +123,17 @@ TEST(Parser, StringInterpolation) {
ASSERT_TRUE(Expr);
ASSERT_EQ(Expr->kind(), Node::NK_ExprString);
auto Parts = static_cast<ExprString *>(Expr.get())->parts();
ASSERT_EQ(Parts->range().begin(), Point(0, 1, 1));
ASSERT_EQ(Parts->range().end(), Point(0, 13, 13));
ASSERT_TRUE(Parts->range().begin().isAt(0, 1, 1));
ASSERT_TRUE(Parts->range().end().isAt(0, 13, 13));
ASSERT_EQ(Parts->fragments().size(), 3);

ASSERT_EQ(Parts->fragments()[0].kind(), InterpolablePart::SPK_Escaped);
ASSERT_EQ(Parts->fragments()[1].kind(), InterpolablePart::SPK_Interpolation);
ASSERT_EQ(Parts->fragments()[2].kind(), InterpolablePart::SPK_Escaped);

ASSERT_EQ(Diags.diags().size(), 0);
ASSERT_EQ(Expr->range().begin(), Point(0, 0, 0));
ASSERT_EQ(Expr->range().end(), Point(0, 14, 14));
ASSERT_TRUE(Expr->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(Expr->range().end().isAt(0, 14, 14));
}

TEST(Parser, IndentedString) {
Expand All @@ -156,26 +156,26 @@ TEST(Parser, IndentedString) {
// Check the diagnostic.
ASSERT_EQ(Diags.diags().size(), 1);
auto &D = Diags.diags()[0];
ASSERT_EQ(D->range().begin(), Point(7, 3, 39));
ASSERT_EQ(D->range().end(), Point(7, 3, 39));
ASSERT_TRUE(D->range().begin().isAt(7, 3, 39));
ASSERT_TRUE(D->range().end().isAt(7, 3, 39));
ASSERT_EQ(D->kind(), Diagnostic::DK_Expected);
ASSERT_EQ(D->args().size(), 1);
ASSERT_EQ(D->args()[0], "''");

// Check the note.
ASSERT_EQ(D->notes().size(), 1);
auto &N = D->notes()[0];
ASSERT_EQ(N->range().begin(), Point(0, 0, 0));
ASSERT_EQ(N->range().end(), Point(0, 2, 2));
ASSERT_TRUE(N->range().begin().isAt(0, 0, 0));
ASSERT_TRUE(N->range().end().isAt(0, 2, 2));
ASSERT_EQ(N->kind(), Note::NK_ToMachThis);
ASSERT_EQ(N->args().size(), 1);
ASSERT_EQ(N->args()[0], "''");

// Check fix-it hints.
ASSERT_EQ(D->fixes().size(), 1);
const auto &F = D->fixes()[0];
ASSERT_EQ(F.oldRange().begin(), Point(7, 3, 39));
ASSERT_EQ(F.oldRange().end(), Point(7, 3, 39));
ASSERT_TRUE(F.oldRange().begin().isAt(7, 3, 39));
ASSERT_TRUE(F.oldRange().end().isAt(7, 3, 39));
ASSERT_EQ(F.newText(), "''");
}

Expand Down

0 comments on commit 371d1b5

Please sign in to comment.