Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

Commit e2e6c94

Browse files
gebnertydeu
authored andcommitted
perf: cache imported environment
1 parent a04e5a6 commit e2e6c94

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

Diff for: Lake/Config/Load.lean

+36-1
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,47 @@ unsafe def evalScriptDecl
4141

4242
namespace Package
4343

44+
deriving instance BEq, Hashable for Import
45+
46+
/- Cache for the imported header environment of Lake configuration files. -/
47+
initialize importEnvCache : IO.Ref (Std.HashMap (List Import) Environment) ← IO.mkRef {}
48+
49+
/-- Like `Lean.Elab.processHeader`, but using `importEnvCache`. -/
50+
def processHeader (header : Syntax) (messages : MessageLog) (inputCtx : Parser.InputContext) (trustLevel : UInt32)
51+
: IO (Environment × MessageLog) := do
52+
try
53+
let imports := Elab.headerToImports header
54+
if let some env := (← importEnvCache.get).find? imports then return (env, messages)
55+
let env ← importModules imports {} trustLevel
56+
importEnvCache.modify (·.insert imports env)
57+
return (env, messages)
58+
catch e =>
59+
let env ← mkEmptyEnvironment
60+
let spos := header.getPos?.getD 0
61+
let pos := inputCtx.fileMap.toPosition spos
62+
return (env, messages.add { fileName := inputCtx.fileName, data := toString e, pos })
63+
64+
/-- Like `Lean.Elab.runFrontend`, but using `importEnvCache`. -/
65+
def runFrontend (input : String) (opts : Options) (fileName : String) (mainModuleName : Name) (trustLevel : UInt32 := 1024)
66+
: IO (Environment × Bool) := do
67+
let inputCtx := Parser.mkInputContext input fileName
68+
let (header, parserState, messages) ← Parser.parseHeader inputCtx
69+
let (env, messages) ← processHeader header messages inputCtx trustLevel
70+
let env := env.setMainModule mainModuleName
71+
72+
let mut commandState := Elab.Command.mkState env {} opts
73+
let s ← Elab.IO.processCommands inputCtx parserState commandState
74+
for msg in s.commandState.messages.toList do
75+
IO.eprint (← msg.toString)
76+
77+
pure (s.commandState.env, !s.commandState.messages.hasErrors)
78+
4479
/-- Unsafe implementation of `load`. -/
4580
unsafe def loadUnsafe (dir : FilePath) (args : List String := [])
4681
(configFile := dir / defaultConfigFile) (leanOpts := Options.empty)
4782
: IO Package := do
4883
let input ← IO.FS.readFile configFile
49-
let (env, ok) ← Elab.runFrontend input leanOpts configFile.toString configModName
84+
let (env, ok) ← runFrontend input leanOpts configFile.toString configModName
5085
if ok then
5186
match packageAttr.ext.getState env |>.toList with
5287
| [] => error s!"configuration file is missing a `package` declaration"

0 commit comments

Comments
 (0)