Skip to content

Commit f88d3bb

Browse files
committed
refactor: move module header-specific data into syntax-tagged snapshots
1 parent c90aafb commit f88d3bb

File tree

7 files changed

+49
-22
lines changed

7 files changed

+49
-22
lines changed

src/Lean/Elab/Frontend.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ where
112112
|>.foldl (· ++ ·) {}
113113
-- In contrast to messages, we should collect info trees only from the top-level command
114114
-- snapshots as they subsume any info trees reported incrementally by their children.
115-
let trees := commands.map (·.infoTreeSnap.get.infoTree?) |>.filterMap id |>.toPArray'
115+
let trees := commands.map (·.elabSnap.infoTreeSnap.get.infoTree?) |>.filterMap id |>.toPArray'
116116
return {
117-
commandState := { snap.resultSnap.get.cmdState with messages, infoState.trees := trees }
117+
commandState := { snap.elabSnap.resultSnap.get.cmdState with messages, infoState.trees := trees }
118118
parserState := snap.parserState
119119
cmdPos := snap.parserState.pos
120120
commands := commands.map (·.stx)

src/Lean/Language/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ partial def SnapshotTask.cancelRec [ToSnapshotTree α] (t : SnapshotTask α) : B
218218

219219
/-- Snapshot type without child nodes. -/
220220
structure SnapshotLeaf extends Snapshot
221-
deriving Nonempty, TypeName
221+
deriving Inhabited, TypeName
222222

223223
instance : ToSnapshotTree SnapshotLeaf where
224224
toSnapshotTree s := SnapshotTree.mk s.toSnapshot #[]

src/Lean/Language/Lean.lean

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -392,21 +392,27 @@ where
392392
return {
393393
ictx
394394
stx := newStx
395-
diagnostics := old.diagnostics
395+
diagnostics := .empty
396+
metaSnap := .finished newStx {
397+
diagnostics := old.diagnostics
398+
}
396399
result? := some {
397400
parserState := newParserState
398-
processedSnap := (← oldSuccess.processedSnap.bindIO (stx? := newStx)
401+
processedSnap := (← oldSuccess.processedSnap.bindIO
399402
(cancelTk? := none) (reportingRange? := progressRange?) (sync := true) fun oldProcessed => do
400403
if let some oldProcSuccess := oldProcessed.result? then
401404
-- also wait on old command parse snapshot as parsing is cheap and may allow for
402405
-- elaboration reuse
403-
oldProcSuccess.firstCmdSnap.bindIO (sync := true) (stx? := newStx)
406+
oldProcSuccess.firstCmdSnap.bindIO (sync := true)
404407
(cancelTk? := none) (reportingRange? := progressRange?) fun oldCmd => do
405408
let prom ← IO.Promise.new
406409
let cancelTk ← IO.CancelToken.new
407410
parseCmd oldCmd newParserState oldProcSuccess.cmdState prom (sync := true) cancelTk ctx
408-
return .finished newStx {
409-
diagnostics := oldProcessed.diagnostics
411+
return .finished none {
412+
diagnostics := .empty
413+
metaSnap := .finished newStx {
414+
diagnostics := oldProcessed.diagnostics
415+
}
410416
result? := some {
411417
cmdState := oldProcSuccess.cmdState
412418
firstCmdSnap := { stx? := none, task := prom.result!, cancelTk? := cancelTk } } }
@@ -425,13 +431,16 @@ where
425431
-- ...go immediately to next snapshot
426432
return (← unchanged old old.stx oldSuccess.parserState)
427433

428-
withHeaderExceptions ({ · with ictx, stx := .missing, result? := none }) do
434+
withHeaderExceptions ({ · with ictx, stx := .missing, result? := none, metaSnap := default }) do
429435
-- parsing the header should be cheap enough to do synchronously
430436
let (stx, parserState, msgLog) ← Parser.parseHeader ictx
431437
if msgLog.hasErrors then
432438
return {
433439
ictx, stx
434-
diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
440+
diagnostics := .empty
441+
metaSnap := .finished stx {
442+
diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
443+
}
435444
result? := none
436445
}
437446

@@ -452,7 +461,10 @@ where
452461
old.result?.forM (·.processedSnap.cancelRec)
453462
return {
454463
ictx, stx
455-
diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
464+
diagnostics := .empty
465+
metaSnap := .finished stx {
466+
diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
467+
}
456468
result? := some {
457469
parserState
458470
processedSnap := (← processHeader ⟨trimmedStx⟩ parserState)
@@ -462,9 +474,9 @@ where
462474
processHeader (stx : HeaderSyntax) (parserState : Parser.ModuleParserState) :
463475
LeanProcessingM (SnapshotTask HeaderProcessedSnapshot) := do
464476
let ctx ← read
465-
SnapshotTask.ofIO stx none (some ⟨0, ctx.input.endPos⟩) <|
477+
SnapshotTask.ofIO none none (some ⟨0, ctx.input.endPos⟩) <|
466478
ReaderT.run (r := ctx) <| -- re-enter reader in new task
467-
withHeaderExceptions (α := HeaderProcessedSnapshot) ({ · with result? := none }) do
479+
withHeaderExceptions (α := HeaderProcessedSnapshot) ({ · with result? := none, metaSnap := default }) do
468480
let setup ← match (← setupImports stx) with
469481
| .ok setup => pure setup
470482
| .error snap => return snap
@@ -483,7 +495,7 @@ where
483495
let stopTime := (← IO.monoNanosNow).toFloat / 1000000000
484496
let diagnostics := (← Snapshot.Diagnostics.ofMessageLog msgLog)
485497
if msgLog.hasErrors then
486-
return { diagnostics, result? := none }
498+
return { diagnostics, result? := none, metaSnap := default }
487499

488500
let mut traceState := default
489501
if trace.profiler.output.get? setup.opts |>.isSome then
@@ -521,8 +533,11 @@ where
521533
let cancelTk ← IO.CancelToken.new
522534
parseCmd none parserState cmdState prom (sync := true) cancelTk ctx
523535
return {
524-
diagnostics
525-
infoTree? := cmdState.infoState.trees[0]!
536+
diagnostics := .empty
537+
metaSnap := .finished stx {
538+
diagnostics
539+
infoTree? := cmdState.infoState.trees[0]!
540+
}
526541
result? := some {
527542
cmdState
528543
firstCmdSnap := { stx? := none, task := prom.result!, cancelTk? := cancelTk }

src/Lean/Language/Lean/Types.lean

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,16 @@ structure HeaderProcessedState where
8989

9090
/-- State after the module header has been processed including imports. -/
9191
structure HeaderProcessedSnapshot extends Snapshot where
92+
/--
93+
Holds produced diagnostics and info tree. Separate snapshot so that it can be tagged with the
94+
header syntax, which should not be done for this snapshot containing `firstCmdSnap`.
95+
-/
96+
metaSnap : SnapshotTask SnapshotLeaf
9297
/-- State after successful importing. -/
9398
result? : Option HeaderProcessedState
9499
isFatal := result?.isNone
95100
instance : ToSnapshotTree HeaderProcessedSnapshot where
96-
toSnapshotTree s := ⟨s.toSnapshot, #[] |>
101+
toSnapshotTree s := ⟨s.toSnapshot, #[s.metaSnap.map (sync := true) toSnapshotTree] |>
97102
pushOpt (s.result?.map (·.firstCmdSnap.map (sync := true) toSnapshotTree))⟩
98103

99104
/-- State after successfully parsing the module header. -/
@@ -105,6 +110,11 @@ structure HeaderParsedState where
105110

106111
/-- State after the module header has been parsed. -/
107112
structure HeaderParsedSnapshot extends Snapshot where
113+
/--
114+
Holds produced diagnostics. Separate snapshot so that it can be tagged with the header syntax,
115+
which should not be done for this snapshot containing `firstCmdSnap`.
116+
-/
117+
metaSnap : SnapshotTask SnapshotLeaf
108118
/-- Parser input context supplied by the driver, stored here for incremental parsing. -/
109119
ictx : Parser.InputContext
110120
/-- Resulting syntax tree. -/
@@ -114,8 +124,8 @@ structure HeaderParsedSnapshot extends Snapshot where
114124
isFatal := result?.isNone
115125

116126
instance : ToSnapshotTree HeaderParsedSnapshot where
117-
toSnapshotTree s := ⟨s.toSnapshot,
118-
#[] |> pushOpt (s.result?.map (·.processedSnap.map (sync := true) toSnapshotTree))⟩
127+
toSnapshotTree s := ⟨s.toSnapshot, #[s.metaSnap.map (sync := true) toSnapshotTree] |>
128+
pushOpt (s.result?.map (·.processedSnap.map (sync := true) toSnapshotTree))⟩
119129

120130
/-- Shortcut accessor to the final header state, if successful. -/
121131
def HeaderParsedSnapshot.processedResult (snap : HeaderParsedSnapshot) :

src/Lean/Server/FileWorker.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ def setupImports
382382
unless (← IO.checkCanceled) do
383383
IO.Process.exit 2 -- signal restart request to watchdog
384384
-- should not be visible to user as task is already canceled
385-
return .error { diagnostics := .empty, result? := none }
385+
return .error { diagnostics := .empty, result? := none, metaSnap := default }
386386

387387
chanOut.sync.send <| mkInitialIleanInfoUpdateNotification doc <| collectImports stx
388388
let imports := Elab.headerToImports stx
@@ -404,11 +404,13 @@ def setupImports
404404
"Imports are out of date and must be rebuilt; \
405405
use the \"Restart File\" command in your editor.")
406406
result? := none
407+
metaSnap := default
407408
}
408409
| .error msg =>
409410
return .error {
410411
diagnostics := (← diagnosticsOfHeaderError msg)
411412
result? := none
413+
metaSnap := default
412414
}
413415
| _ => pure ()
414416

src/Lean/Server/FileWorker/Utils.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ private partial def mkCmdSnaps (initSnap : Language.Lean.InitialSnapshot) :
2828
} <| .delayed <| headerSuccess.firstCmdSnap.task.asServerTask.bindCheap go
2929
where
3030
go cmdParsed :=
31-
cmdParsed.resultSnap.task.asServerTask.mapCheap fun result =>
31+
cmdParsed.elabSnap.resultSnap.task.asServerTask.mapCheap fun result =>
3232
.ok <| .cons {
3333
stx := cmdParsed.stx
3434
mpState := cmdParsed.parserState

src/Lean/Server/Requests.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ def findCmdDataAtPos
396396
findCmdParsedSnap doc hoverPos |>.bindCheap fun
397397
| some cmdParsed => toSnapshotTree cmdParsed |>.findInfoTreeAtPos doc.meta.text hoverPos includeStop |>.bindCheap fun
398398
| some infoTree => .pure <| some (cmdParsed.stx, infoTree)
399-
| none => cmdParsed.infoTreeSnap.task.asServerTask.mapCheap fun s =>
399+
| none => cmdParsed.elabSnap.infoTreeSnap.task.asServerTask.mapCheap fun s =>
400400
assert! s.infoTree?.isSome
401401
some (cmdParsed.stx, s.infoTree?.get!)
402402
| none => .pure none

0 commit comments

Comments
 (0)