@@ -238,7 +238,7 @@ structure SetupImportsResult where
238
238
register_builtin_option internal.minimalSnapshots : Bool := {
239
239
defValue := false
240
240
descr := "reduce information stored in snapshots to the minimum necessary for the cmdline \
241
- driver: diagnostics and environment per command "
241
+ driver: diagnostics per command and final full snapshot "
242
242
}
243
243
244
244
/--
@@ -352,31 +352,47 @@ where
352
352
let setup ← match (← setupImports stx) with
353
353
| .ok setup => pure setup
354
354
| .error snap => return snap
355
+
356
+ let startTime := (← IO.monoNanosNow).toFloat / 1000000000
355
357
-- allows `headerEnv` to be leaked, which would live until the end of the process anyway
356
358
let (headerEnv, msgLog) ← Elab.processHeader (leakEnv := true ) stx setup.opts .empty
357
359
ctx.toInputContext setup.trustLevel
360
+ let stopTime := (← IO.monoNanosNow).toFloat / 1000000000
358
361
let diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
359
362
if msgLog.hasErrors then
360
363
return { diagnostics, result? := none }
361
364
362
365
let headerEnv := headerEnv.setMainModule setup.mainModuleName
366
+ let mut traceState := default
367
+ if trace.profiler.output.get? setup.opts |>.isSome then
368
+ traceState := {
369
+ traces := #[{
370
+ ref := .missing,
371
+ msg := .trace { cls := `Import, startTime, stopTime }
372
+ (.ofFormat "importing" ) #[]
373
+ : TraceElem
374
+ }].toPArray'
375
+ }
363
376
let cmdState := Elab.Command.mkState headerEnv msgLog setup.opts
364
- let cmdState := { cmdState with infoState := {
365
- enabled := true
366
- trees := #[Elab.InfoTree.context (.commandCtx {
367
- env := headerEnv
368
- fileMap := ctx.fileMap
369
- ngen := { namePrefix := `_import }
370
- }) (Elab.InfoTree.node
371
- (Elab.Info.ofCommandInfo { elaborator := `header, stx })
372
- (stx[1 ].getArgs.toList.map (fun importStx =>
373
- Elab.InfoTree.node (Elab.Info.ofCommandInfo {
374
- elaborator := `import
375
- stx := importStx
376
- }) #[].toPArray'
377
- )).toPArray'
378
- )].toPArray'
379
- }}
377
+ let cmdState := { cmdState with
378
+ infoState := {
379
+ enabled := true
380
+ trees := #[Elab.InfoTree.context (.commandCtx {
381
+ env := headerEnv
382
+ fileMap := ctx.fileMap
383
+ ngen := { namePrefix := `_import }
384
+ }) (Elab.InfoTree.node
385
+ (Elab.Info.ofCommandInfo { elaborator := `header, stx })
386
+ (stx[1 ].getArgs.toList.map (fun importStx =>
387
+ Elab.InfoTree.node (Elab.Info.ofCommandInfo {
388
+ elaborator := `import
389
+ stx := importStx
390
+ }) #[].toPArray'
391
+ )).toPArray'
392
+ )].toPArray'
393
+ }
394
+ traceState
395
+ }
380
396
let prom ← IO.Promise.new
381
397
-- The speedup of these `markPersistent`s is negligible but they help in making unexpected
382
398
-- `inc_ref_cold`s more visible
@@ -440,15 +456,16 @@ where
440
456
env := cmdState.env, options := scope.opts, currNamespace := scope.currNamespace
441
457
openDecls := scope.openDecls
442
458
}
443
- let (stx, parserState, msgLog) := Parser.parseCommand ctx.toInputContext pmctx parserState
444
- .empty
459
+ let (stx, parserState, msgLog) :=
460
+ profileit "parsing" scope.opts fun _ =>
461
+ Parser.parseCommand ctx.toInputContext pmctx parserState .empty
445
462
446
463
-- semi-fast path
447
464
if let some old := old? then
448
465
-- NOTE: as `parserState.pos` includes trailing whitespace, this forces reprocessing even if
449
- -- only that whitespace changes, which is wasteful but still necessary because it may
450
- -- influence the range of error messages such as from a trailing `exact`
451
- if stx.eqWithInfo old.data.stx then
466
+ -- only that whitespace changes, which is wasteful but still necessary because it may
467
+ -- influence the range of error messages such as from a trailing `exact`
468
+ if stx.eqWithInfo old.data.stx then
452
469
-- Here we must make sure to pass the *new* parser state; see NOTE in `unchanged`
453
470
return (← unchanged old parserState)
454
471
-- on first change, make sure to cancel old invocation
@@ -470,23 +487,27 @@ where
470
487
let next? ← if Parser.isTerminalCommand stx then pure none
471
488
-- for now, wait on "command finished" snapshot before parsing next command
472
489
else some <$> IO.Promise.new
473
- prom.resolve <| .mk (nextCmdSnap? := next?.map ({ range? := some ⟨parserState.pos, ctx.input.endPos⟩, task := ·.result })) {
474
- diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
475
- stx := if minimalSnapshots then .missing else stx
476
- parserState := if minimalSnapshots then {} else parserState
490
+ let diagnostics ← Snapshot.Diagnostics.ofMessageLog msgLog
491
+ let data := if minimalSnapshots && !Parser.isTerminalCommand stx then {
492
+ diagnostics
493
+ stx := .missing
494
+ parserState := {}
477
495
elabSnap := { range? := stx.getRange?, task := elabPromise.result }
478
- finishedSnap := .pure <|
479
- if minimalSnapshots then
480
- { finishedSnap with
481
- infoTree? := none
482
- cmdState := {
483
- env := Runtime.markPersistent (if Parser.isTerminalCommand stx then finishedSnap.cmdState.env else initEnv)
484
- maxRecDepth := 0
485
- }
486
- }
487
- else finishedSnap
496
+ finishedSnap := .pure {
497
+ diagnostics := finishedSnap.diagnostics
498
+ infoTree? := none
499
+ cmdState := {
500
+ env := initEnv
501
+ maxRecDepth := 0
502
+ }
503
+ }
488
504
tacticCache
505
+ } else {
506
+ diagnostics, stx, parserState, tacticCache
507
+ elabSnap := { range? := stx.getRange?, task := elabPromise.result }
508
+ finishedSnap := .pure finishedSnap
489
509
}
510
+ prom.resolve <| .mk (nextCmdSnap? := next?.map ({ range? := some ⟨parserState.pos, ctx.input.endPos⟩, task := ·.result })) data
490
511
if let some next := next? then
491
512
parseCmd none parserState finishedSnap.cmdState initEnv next ctx
492
513
@@ -555,16 +576,15 @@ def processCommands (inputCtx : Parser.InputContext) (parserState : Parser.Modul
555
576
|>.run { inputCtx with }
556
577
return prom.result
557
578
558
-
559
- /-- Waits for and returns final environment, if importing was successful. -/
560
- partial def waitForFinalEnv? (snap : InitialSnapshot) : Option Environment := do
579
+ /-- Waits for and returns final command state, if importing was successful. -/
580
+ partial def waitForFinalCmdState? (snap : InitialSnapshot) : Option Command.State := do
561
581
let snap ← snap.result?
562
582
let snap ← snap.processedSnap.get.result?
563
583
goCmd snap.firstCmdSnap.get
564
584
where goCmd snap :=
565
585
if let some next := snap.nextCmdSnap? then
566
586
goCmd next.get
567
587
else
568
- snap.data.finishedSnap.get.cmdState.env
588
+ snap.data.finishedSnap.get.cmdState
569
589
570
590
end Lean
0 commit comments