From 59c72497696eaafa294c34699795788d24d68c68 Mon Sep 17 00:00:00 2001 From: zimbatm Date: Wed, 23 Oct 2019 17:21:10 +0200 Subject: [PATCH] libexpr: add findDerivationFilename extract the derivation to filename:lineno heuristic --- src/libexpr/attr-path.cc | 28 ++++++++++++++++++++++++++++ src/libexpr/attr-path.hh | 5 +++++ src/nix/edit.cc | 23 ++--------------------- src/nix/repl.cc | 23 +---------------------- 4 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc index b0f80db32..7a6d8dfd0 100644 --- a/src/libexpr/attr-path.cc +++ b/src/libexpr/attr-path.cc @@ -93,4 +93,32 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath, } +std::tuple findDerivationFilename(EvalState & state, Value & v, std::string what) +{ + Value * v2; + try { + auto dummyArgs = state.allocBindings(0); + v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v); + } catch (Error &) { + throw Error("package '%s' has no source location information", what); + } + + auto pos = state.forceString(*v2); + + auto colon = pos.rfind(':'); + if (colon == std::string::npos) + throw Error("cannot parse meta.position attribute '%s'", pos); + + std::string filename(pos, 0, colon); + int lineno; + try { + lineno = std::stoi(std::string(pos, colon + 1)); + } catch (std::invalid_argument & e) { + throw Error("cannot parse line number '%s'", pos); + } + + return std::make_tuple(filename, lineno); +} + + } diff --git a/src/libexpr/attr-path.hh b/src/libexpr/attr-path.hh index 46a341950..dca94cc78 100644 --- a/src/libexpr/attr-path.hh +++ b/src/libexpr/attr-path.hh @@ -4,10 +4,15 @@ #include #include +#include namespace nix { Value * findAlongAttrPath(EvalState & state, const string & attrPath, Bindings & autoArgs, Value & vIn); +/* Heuristic to find the filename and lineno or a derivation. */ +std::tuple findDerivationFilename(EvalState & state, + Value & v, std::string what); + } diff --git a/src/nix/edit.cc b/src/nix/edit.cc index 3a27b9cca..a4aa40bed 100644 --- a/src/nix/edit.cc +++ b/src/nix/edit.cc @@ -36,28 +36,9 @@ struct CmdEdit : InstallableCommand auto v = installable->toValue(*state); - Value * v2; - try { - auto dummyArgs = state->allocBindings(0); - v2 = findAlongAttrPath(*state, "meta.position", *dummyArgs, *v); - } catch (Error &) { - throw Error("package '%s' has no source location information", installable->what()); - } - - auto pos = state->forceString(*v2); - debug("position is %s", pos); - - auto colon = pos.rfind(':'); - if (colon == std::string::npos) - throw Error("cannot parse meta.position attribute '%s'", pos); - - std::string filename(pos, 0, colon); + std::string filename; int lineno; - try { - lineno = std::stoi(std::string(pos, colon + 1)); - } catch (std::invalid_argument & e) { - throw Error("cannot parse line number '%s'", pos); - } + std::tie(filename, lineno) = findDerivationFilename(*state, *v, installable->what()); stopProgressBar(); diff --git a/src/nix/repl.cc b/src/nix/repl.cc index d4334cf7f..5cfb408f7 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -481,28 +481,7 @@ bool NixRepl::processLine(string line) lineno = 0; } else { // assume it's a derivation - Value * v2; - try { - auto dummyArgs = state.allocBindings(0); - v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v); - } catch (Error &) { - throw Error("package '%s' has no source location information", arg); - } - - auto pos = state.forceString(*v2); - debug("position is %s", pos); - - auto colon = pos.rfind(':'); - if (colon == std::string::npos) - throw Error("cannot parse meta.position attribute '%s'", pos); - - filename = std::string(pos, 0, colon); - try { - lineno = std::stoi(std::string(pos, colon + 1)); - } catch (std::invalid_argument & e) { - throw Error("cannot parse line number '%s'", pos); - } - + std::tie(filename, lineno) = findDerivationFilename(state, v, arg); } // Open in EDITOR