Restore display of source lines for stdin/string inputs

This commit is contained in:
Eelco Dolstra 2022-12-13 16:00:44 +01:00
parent aea97f07a3
commit c9b0a85b08
3 changed files with 44 additions and 48 deletions

View file

@ -8,62 +8,55 @@
namespace nix { namespace nix {
struct SourcePathAdapter : AbstractPos struct PosAdapter : AbstractPos
{ {
Path path; Pos::Origin origin;
SourcePathAdapter(Path path) PosAdapter(Pos::Origin origin)
: path(std::move(path)) : origin(std::move(origin))
{ {
} }
std::optional<std::string> getSource() const override std::optional<std::string> getSource() const override
{ {
return std::visit(overloaded {
[](const Pos::none_tag &) -> std::optional<std::string> {
return std::nullopt;
},
[](const Pos::Stdin & s) -> std::optional<std::string> {
// Get rid of the null terminators added by the parser.
return std::string(s.source->c_str());
},
[](const Pos::String & s) -> std::optional<std::string> {
// Get rid of the null terminators added by the parser.
return std::string(s.source->c_str());
},
[](const Path & path) -> std::optional<std::string> {
try { try {
return readFile(path); return readFile(path);
} catch (Error &) { } catch (Error &) {
return std::nullopt; return std::nullopt;
} }
} }
}, origin);
void print(std::ostream & out) const override
{
out << path;
} }
};
struct StringPosAdapter : AbstractPos
{
void print(std::ostream & out) const override void print(std::ostream & out) const override
{ {
out << "«string»"; std::visit(overloaded {
} [&](const Pos::none_tag &) { out << "«none»"; },
}; [&](const Pos::Stdin &) { out << "«stdin»"; },
[&](const Pos::String & s) { out << "«string»"; },
struct StdinPosAdapter : AbstractPos [&](const Path & path) { out << path; }
{ }, origin);
void print(std::ostream & out) const override
{
out << "«stdin»";
} }
}; };
Pos::operator std::shared_ptr<AbstractPos>() const Pos::operator std::shared_ptr<AbstractPos>() const
{ {
std::shared_ptr<AbstractPos> pos; auto pos = std::make_shared<PosAdapter>(origin);
if (auto path = std::get_if<Path>(&origin))
pos = std::make_shared<SourcePathAdapter>(*path);
else if (std::get_if<stdin_tag>(&origin))
pos = std::make_shared<StdinPosAdapter>();
else if (std::get_if<string_tag>(&origin))
pos = std::make_shared<StringPosAdapter>();
if (pos) {
pos->line = line; pos->line = line;
pos->column = column; pos->column = column;
}
return pos; return pos;
} }

View file

@ -28,10 +28,11 @@ struct Pos
uint32_t line; uint32_t line;
uint32_t column; uint32_t column;
struct stdin_tag {}; struct none_tag { };
struct string_tag {}; struct Stdin { ref<std::string> source; };
struct String { ref<std::string> source; };
typedef std::variant<stdin_tag, string_tag, Path> Origin; typedef std::variant<none_tag, Stdin, String, Path> Origin;
Origin origin; Origin origin;
@ -72,7 +73,7 @@ public:
mutable uint32_t idx = std::numeric_limits<uint32_t>::max(); mutable uint32_t idx = std::numeric_limits<uint32_t>::max();
// Used for searching in PosTable::[]. // Used for searching in PosTable::[].
explicit Origin(uint32_t idx): idx(idx), origin{Pos::stdin_tag()} {} explicit Origin(uint32_t idx): idx(idx), origin{Pos::none_tag()} {}
public: public:
const Pos::Origin origin; const Pos::Origin origin;

View file

@ -713,10 +713,11 @@ Expr * EvalState::parseExprFromFile(const Path & path, std::shared_ptr<StaticEnv
} }
Expr * EvalState::parseExprFromString(std::string s, const Path & basePath, std::shared_ptr<StaticEnv> & staticEnv) Expr * EvalState::parseExprFromString(std::string s_, const Path & basePath, std::shared_ptr<StaticEnv> & staticEnv)
{ {
s.append("\0\0", 2); auto s = make_ref<std::string>(std::move(s_));
return parse(s.data(), s.size(), Pos::string_tag(), basePath, staticEnv); s->append("\0\0", 2);
return parse(s->data(), s->size(), Pos::String{.source = s}, basePath, staticEnv);
} }
@ -732,7 +733,8 @@ Expr * EvalState::parseStdin()
auto buffer = drainFD(0); auto buffer = drainFD(0);
// drainFD should have left some extra space for terminators // drainFD should have left some extra space for terminators
buffer.append("\0\0", 2); buffer.append("\0\0", 2);
return parse(buffer.data(), buffer.size(), Pos::stdin_tag(), absPath("."), staticBaseEnv); auto s = make_ref<std::string>(std::move(buffer));
return parse(s->data(), s->size(), Pos::Stdin{.source = s}, absPath("."), staticBaseEnv);
} }