4feb7d9f71
Also move `SourcePath` into `libutil`. These changes allow `error.hh` and `error.cc` to access source path and position information, which we can use to produce better error messages (for example, we could consider omitting filenames when two or more consecutive stack frames originate from the same file).
69 lines
2 KiB
C++
69 lines
2 KiB
C++
#include "installable-value.hh"
|
|
#include "eval-cache.hh"
|
|
#include "fetch-to-store.hh"
|
|
|
|
namespace nix {
|
|
|
|
std::vector<ref<eval_cache::AttrCursor>>
|
|
InstallableValue::getCursors(EvalState & state)
|
|
{
|
|
auto evalCache =
|
|
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state,
|
|
[&]() { return toValue(state).first; });
|
|
return {evalCache->getRoot()};
|
|
}
|
|
|
|
ref<eval_cache::AttrCursor>
|
|
InstallableValue::getCursor(EvalState & state)
|
|
{
|
|
/* Although getCursors should return at least one element, in case it doesn't,
|
|
bound check to avoid an undefined behavior for vector[0] */
|
|
return getCursors(state).at(0);
|
|
}
|
|
|
|
static UsageError nonValueInstallable(Installable & installable)
|
|
{
|
|
return UsageError("installable '%s' does not correspond to a Nix language value", installable.what());
|
|
}
|
|
|
|
InstallableValue & InstallableValue::require(Installable & installable)
|
|
{
|
|
auto * castedInstallable = dynamic_cast<InstallableValue *>(&installable);
|
|
if (!castedInstallable)
|
|
throw nonValueInstallable(installable);
|
|
return *castedInstallable;
|
|
}
|
|
|
|
ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
|
|
{
|
|
auto castedInstallable = installable.dynamic_pointer_cast<InstallableValue>();
|
|
if (!castedInstallable)
|
|
throw nonValueInstallable(*installable);
|
|
return ref { castedInstallable };
|
|
}
|
|
|
|
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
|
|
{
|
|
if (v.type() == nPath) {
|
|
auto storePath = fetchToStore(*state->store, v.path());
|
|
return {{
|
|
.path = DerivedPath::Opaque {
|
|
.path = std::move(storePath),
|
|
},
|
|
.info = make_ref<ExtraPathInfo>(),
|
|
}};
|
|
}
|
|
|
|
else if (v.type() == nString) {
|
|
return {{
|
|
.path = DerivedPath::fromSingle(
|
|
state->coerceToSingleDerivedPath(pos, v, errorCtx)),
|
|
.info = make_ref<ExtraPathInfo>(),
|
|
}};
|
|
}
|
|
|
|
else return std::nullopt;
|
|
}
|
|
|
|
}
|