@@ -528,7 +528,7 @@ structure Environment where
528528 /--
529529 Additional imported environment extension state for use in the language server. This field is
530530 identical to `base.extensions` in other contexts. Access via
531- `getModuleEntries (includeServer := true )`.
531+ `getModuleEntries (level := .server )`.
532532 -/
533533 private serverBaseExts : Array EnvExtensionState := base.private.extensions
534534 /--
@@ -1457,6 +1457,19 @@ structure ImportM.Context where
14571457
14581458abbrev ImportM := ReaderT Lean.ImportM.Context IO
14591459
1460+ /-- The level of information to save/load. Each level includes all previous ones. -/
1461+ inductive OLeanLevel where
1462+ /-- Information from exported contexts. -/
1463+ | exported
1464+ /-- Environment extension state for the language server. -/
1465+ | server
1466+ /-- Private module data. -/
1467+ | «private »
1468+ deriving DecidableEq, Ord, Repr
1469+
1470+ instance : LE OLeanLevel := leOfOrd
1471+ instance : LT OLeanLevel := ltOfOrd
1472+
14601473/--
14611474An environment extension with support for storing/retrieving entries from a .olean file.
14621475 - α is the type of the entries that are stored in .olean files.
@@ -1507,15 +1520,17 @@ structure PersistentEnvExtension (α : Type) (β : Type) (σ : Type) where
15071520 name : Name
15081521 addImportedFn : Array (Array α) → ImportM σ
15091522 addEntryFn : σ → β → σ
1510- /-- Function to transform state into data that should always be imported into other modules. -/
1511- exportEntriesFn : σ → Array α
15121523 /--
1513- Function to transform state into data that should be imported into other modules when the module
1514- system is disabled. When it is enabled, the data is loaded only in the language server and
1515- accessible via `getModuleEntries (includeServer := true)`. Conventionally, this is a superset of
1516- the data returned by `exportEntriesFn`.
1524+ Function to transform state into data that should be imported into other modules. When using the
1525+ module system without `import all`, `OLeanLevel.exported` is imported, else `OLeanLevel.private`.
1526+ Additionally, when using the module system in the language server, the `OLeanLevel.server` data is
1527+ accessible via `getModuleEntries (level := .server)`. By convention, each level should include all
1528+ data of previous levels.
1529+
1530+ This function is run after elaborating the file and joining all asynchronous threads. It is run
1531+ once for each level when the module system is enabled, otherwise once for `private`.
15171532 -/
1518- saveEntriesFn : σ → Array α
1533+ exportEntriesFn : Environment → σ → OLeanLevel → Array α
15191534 statsFn : σ → Format
15201535
15211536instance {α σ} [Inhabited σ] : Inhabited (PersistentEnvExtensionState α σ) :=
@@ -1527,20 +1542,21 @@ instance {α β σ} [Inhabited σ] : Inhabited (PersistentEnvExtension α β σ)
15271542 name := default,
15281543 addImportedFn := fun _ => default,
15291544 addEntryFn := fun s _ => s,
1530- exportEntriesFn := fun _ => #[],
1531- saveEntriesFn := fun _ => #[],
1545+ exportEntriesFn := fun _ _ _ => #[],
15321546 statsFn := fun _ => Format.nil
15331547 }
15341548
15351549namespace PersistentEnvExtension
15361550
15371551/--
1538- Returns the data saved by `ext.exportEntriesFn/saveEntriesFn` when `m` was elaborated. See docs on
1539- the functions for details.
1552+ Returns the data saved by `ext.exportEntriesFn` when `m` was elaborated. See docs on the function for
1553+ details. When using the module system, `level` can be used to select the level of data to retrieve,
1554+ but is limited to the maximum level actually imported: `exported` on the cmdline and `server` in the
1555+ language server. Higher levels will return the data of the maximum imported level.
15401556-/
15411557def getModuleEntries {α β σ : Type } [Inhabited σ] (ext : PersistentEnvExtension α β σ)
1542- (env : Environment) (m : ModuleIdx) (includeServer := false ) : Array α :=
1543- let exts := if includeServer then env.serverBaseExts else env.base.private.extensions
1558+ (env : Environment) (m : ModuleIdx) (level := OLeanLevel.exported ) : Array α :=
1559+ let exts := if level = .exported then env.base.private.extensions else env.serverBaseExts
15441560 -- safety: as in `getStateUnsafe`
15451561 unsafe (ext.toEnvExtension.getStateImpl exts).importedEntries[m]!
15461562
@@ -1573,19 +1589,36 @@ end PersistentEnvExtension
15731589
15741590builtin_initialize persistentEnvExtensionsRef : IO.Ref (Array (PersistentEnvExtension EnvExtensionEntry EnvExtensionEntry EnvExtensionState)) ← IO.mkRef #[]
15751591
1576- structure PersistentEnvExtensionDescr (α β σ : Type ) where
1577- name : Name := by exact decl_name%
1578- mkInitial : IO σ
1579- addImportedFn : Array (Array α) → ImportM σ
1580- addEntryFn : σ → β → σ
1581- exportEntriesFn : σ → Array α
1582- saveEntriesFn : σ → Array α := exportEntriesFn
1583- statsFn : σ → Format := fun _ => Format.nil
1584- asyncMode : EnvExtension.AsyncMode := .mainOnly
1585- replay? : Option (ReplayFn σ) := none
1592+ -- Helper structure to enable cyclic default values of `exportEntriesFn` and `exportEntriesFnEx`.
1593+ structure PersistentEnvExtensionDescrCore (α β σ : Type ) where
1594+ name : Name := by exact decl_name%
1595+ mkInitial : IO σ
1596+ addImportedFn : Array (Array α) → ImportM σ
1597+ addEntryFn : σ → β → σ
1598+ exportEntriesFnEx : Environment → σ → OLeanLevel → Array α
1599+ statsFn : σ → Format := fun _ => Format.nil
1600+ asyncMode : EnvExtension.AsyncMode := .mainOnly
1601+ replay? : Option (ReplayFn σ) := none
15861602
1587- attribute [inherit_doc PersistentEnvExtension.exportEntriesFn] PersistentEnvExtensionDescr.exportEntriesFn
1588- attribute [inherit_doc PersistentEnvExtension.saveEntriesFn] PersistentEnvExtensionDescr.saveEntriesFn
1603+ attribute [inherit_doc PersistentEnvExtension.exportEntriesFn]
1604+ PersistentEnvExtensionDescrCore.exportEntriesFnEx
1605+
1606+ /--
1607+ Auxiliary function to signal to the structure instance elaborator that `default` should be used as
1608+ the default value for a field but only if `_otherField` has been given, which is added as an
1609+ artifical dependency.
1610+ -/
1611+ def useDefaultIfOtherFieldGiven (default : α) (_otherField : β) : α :=
1612+ default
1613+
1614+ structure PersistentEnvExtensionDescr (α β σ : Type ) extends PersistentEnvExtensionDescrCore α β σ where
1615+ -- The cyclic default values force the user to specify at least one of the two following fields.
1616+ /--
1617+ Obsolete simpler version of `exportEntriesFnEx`. Its value is ignored if the latter is also
1618+ specified.
1619+ -/
1620+ exportEntriesFn : σ → Array α := useDefaultIfOtherFieldGiven (fun _ => #[]) exportEntriesFnEx
1621+ exportEntriesFnEx := fun _ s _ => exportEntriesFn s
15891622
15901623unsafe def registerPersistentEnvExtensionUnsafe {α β σ : Type } [Inhabited σ] (descr : PersistentEnvExtensionDescr α β σ) : IO (PersistentEnvExtension α β σ) := do
15911624 let pExts ← persistentEnvExtensionsRef.get
@@ -1604,8 +1637,7 @@ unsafe def registerPersistentEnvExtensionUnsafe {α β σ : Type} [Inhabited σ]
16041637 name := descr.name,
16051638 addImportedFn := descr.addImportedFn,
16061639 addEntryFn := descr.addEntryFn,
1607- exportEntriesFn := descr.exportEntriesFn,
1608- saveEntriesFn := descr.saveEntriesFn,
1640+ exportEntriesFn := descr.exportEntriesFnEx,
16091641 statsFn := descr.statsFn
16101642 }
16111643 persistentEnvExtensionsRef.modify fun pExts => pExts.push (unsafeCast pExt)
@@ -1661,16 +1693,6 @@ unsafe def Environment.freeRegions (env : Environment) : IO Unit :=
16611693 TODO: statically check for this. -/
16621694 env.header.regions.forM CompactedRegion.free
16631695
1664- /-- The level of information to save/load. Each level includes all previous ones. -/
1665- inductive OLeanLevel where
1666- /-- Information from exported contexts. -/
1667- | exported
1668- /-- Environment extension state for the language server. -/
1669- | server
1670- /-- Private module data. -/
1671- | «private »
1672- deriving DecidableEq
1673-
16741696def OLeanLevel.adjustFileName (base : System.FilePath) : OLeanLevel → System.FilePath
16751697 | .exported => base
16761698 | .server => base.addExtension "server"
@@ -1688,7 +1710,7 @@ def mkModuleData (env : Environment) (level : OLeanLevel := .private) : IO Modul
16881710 if asyncMode matches .async then
16891711 asyncMode := .sync
16901712 let state := pExt.getState (asyncMode := asyncMode) env
1691- (pExt.name, if level = .exported then pExt.exportEntriesFn state else pExt.saveEntriesFn state)
1713+ (pExt.name, pExt.exportEntriesFn env state level )
16921714 let kenv := env.toKernelEnv
16931715 let env := env.setExporting (level != .private)
16941716 let constNames := kenv.constants.foldStage2 (fun names name _ => names.push name) #[]
0 commit comments