Skip to content

Commit c812394

Browse files
committed
feat: lean --src-deps
1 parent 1214e64 commit c812394

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

src/Lean/Elab/Import.lean

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Authors: Leonardo de Moura, Sebastian Ullrich
55
-/
66
prelude
77
import Lean.Parser.Module
8-
import Lean.Data.Json
8+
import Lean.Util.Paths
99

1010
namespace Lean.Elab
1111

@@ -42,4 +42,12 @@ def printImports (input : String) (fileName : Option String) : IO Unit := do
4242
let fname ← findOLean dep.module
4343
IO.println fname
4444

45+
@[export lean_print_import_srcs]
46+
def printImportSrcs (input : String) (fileName : Option String) : IO Unit := do
47+
let sp ← initSrcSearchPath
48+
let (deps, _, _) ← parseImports input fileName
49+
for dep in deps do
50+
let fname ← findLean sp dep.module
51+
IO.println fname
52+
4553
end Lean.Elab

src/Lean/Util/Path.lean

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,26 @@ def initSearchPath (leanSysroot : FilePath) (sp : SearchPath := ∅) : IO Unit :
104104
private def initSearchPathInternal : IO Unit := do
105105
initSearchPath (← getBuildDir)
106106

107+
/-- Find the compiled `.olean` of a module in the `LEAN_PATH` search path. -/
107108
partial def findOLean (mod : Name) : IO FilePath := do
108109
let sp ← searchPathRef.get
109110
if let some fname ← sp.findWithExt "olean" mod then
110111
return fname
111112
else
112113
let pkg := FilePath.mk <| mod.getRoot.toString (escape := false)
113-
let mut msg := s!"unknown module prefix '{pkg}'
114+
throw <| IO.userError s!"unknown module prefix '{pkg}'\n\n\
115+
No directory '{pkg}' or file '{pkg}.olean' in the search path entries:\n\
116+
{"\n".intercalate <| sp.map (·.toString)}"
114117

115-
No directory '{pkg}' or file '{pkg}.olean' in the search path entries:
116-
{"\n".intercalate <| sp.map (·.toString)}"
117-
throw <| IO.userError msg
118+
/-- Find the `.lean` source of a module in a `LEAN_SRC_PATH` search path. -/
119+
partial def findLean (sp : SearchPath) (mod : Name) : IO FilePath := do
120+
if let some fname ← sp.findWithExt "lean" mod then
121+
return fname
122+
else
123+
let pkg := FilePath.mk <| mod.getRoot.toString (escape := false)
124+
throw <| IO.userError s!"unknown module prefix '{pkg}'\n\n\
125+
No directory '{pkg}' or file '{pkg}.lean' in the search path entries:\n\
126+
{"\n".intercalate <| sp.map (·.toString)}"
118127

119128
/-- Infer module name of source file name. -/
120129
@[export lean_module_name_of_file]

src/util/shell.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ static void display_help(std::ostream & out) {
225225
std::cout << " --json report Lean output (e.g., messages) as JSON (one per line)\n";
226226
std::cout << " -E --error=kind report Lean messages of kind as errors\n";
227227
std::cout << " --deps just print dependencies of a Lean input\n";
228+
std::cout << " --src-deps just print dependency sources of a Lean input\n";
228229
std::cout << " --print-prefix print the installation prefix for Lean and exit\n";
229230
std::cout << " --print-libdir print the installation directory for Lean's built-in libraries and exit\n";
230231
std::cout << " --profile display elaboration/type checking time for each definition/theorem\n";
@@ -235,6 +236,7 @@ static void display_help(std::ostream & out) {
235236
std::cout << " -D name=value set a configuration option (see set_option command)\n";
236237
}
237238

239+
static int only_src_deps = 0;
238240
static int print_prefix = 0;
239241
static int print_libdir = 0;
240242
static int json_output = 0;
@@ -255,6 +257,7 @@ static struct option g_long_options[] = {
255257
{"stats", no_argument, 0, 'a'},
256258
{"quiet", no_argument, 0, 'q'},
257259
{"deps", no_argument, 0, 'd'},
260+
{"src-deps", no_argument, &only_src_deps, 1},
258261
{"deps-json", no_argument, 0, 'J'},
259262
{"timeout", optional_argument, 0, 'T'},
260263
{"c", optional_argument, 0, 'c'},
@@ -399,6 +402,12 @@ void print_imports(std::string const & input, std::string const & fname) {
399402
consume_io_result(lean_print_imports(mk_string(input), mk_option_some(mk_string(fname)), io_mk_world()));
400403
}
401404

405+
/* def printImportSrcs (input : String) (fileName : Option String := none) : IO Unit */
406+
extern "C" object* lean_print_import_srcs(object* input, object* file_name, object* w);
407+
void print_import_srcs(std::string const & input, std::string const & fname) {
408+
consume_io_result(lean_print_import_srcs(mk_string(input), mk_option_some(mk_string(fname)), io_mk_world()));
409+
}
410+
402411
/* def printImportsJson (fileNames : Array String) : IO Unit */
403412
extern "C" object* lean_print_imports_json(object * file_names, object * w);
404413
void print_imports_json(array_ref<string_ref> const & fnames) {
@@ -697,6 +706,11 @@ extern "C" LEAN_EXPORT int lean_main(int argc, char ** argv) {
697706
return 0;
698707
}
699708

709+
if (only_src_deps) {
710+
print_import_srcs(contents, mod_fn);
711+
return 0;
712+
}
713+
700714
// Quick and dirty `#lang` support
701715
// TODO: make it extensible, and add `lean4md`
702716
if (contents.compare(0, 5, "#lang") == 0) {

0 commit comments

Comments
 (0)