/- Copyright (c) 2019 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura, Mac Malone -/ module prelude public import Lean.Data.Json.Parser public import Lean.Util.LeanOptions set_option doc.verso true public section /-! # Module Setup Information Data types used by Lean module headers and the `--setup` CLI. -/ namespace Lean /- Abstract structure of an `import` statement. -/ structure Import where module : Name /-- `import all`; whether to import and expose all data saved by the module. -/ importAll : Bool := false /-- Whether to activate this import when the current module itself is imported. -/ isExported : Bool := true /-- Whether to import IR for all definitions (transitively) reachable. -/ isMeta : Bool := false deriving Repr, Inhabited, ToJson, FromJson, BEq, Hashable -- needed by Lake (in `Lake.Load.Elab.Lean`) instance : Coe Name Import := ⟨({module := ·})⟩ instance : ToString Import := ⟨fun imp => s!"{if imp.isExported then "public " else ""}{if imp.isMeta then "meta " else ""}import \ {if imp.importAll then "all " else ""}{imp.module}"⟩ /-- Abstract structure of a module's header. -/ structure ModuleHeader where /-- The module's direct imports (i.e., those listed in the header). -/ imports : Array Import /-- Whether the module is participating in the module system. -/ isModule : Bool deriving Repr, Inhabited, ToJson, FromJson /-- Module data files used for an {lit}`import` statement. This structure is designed for efficient JSON serialization. -/ structure ImportArtifacts where ofArray :: toArray : Array System.FilePath deriving Repr, Inhabited instance : ToJson ImportArtifacts := ⟨(toJson ·.toArray)⟩ instance : FromJson ImportArtifacts := ⟨(.ofArray <$> fromJson? ·)⟩ def ImportArtifacts.size (arts : ImportArtifacts) := arts.toArray.size def ImportArtifacts.olean? (arts : ImportArtifacts) := arts.toArray[0]? def ImportArtifacts.ir? (arts : ImportArtifacts) := arts.toArray[1]? def ImportArtifacts.oleanServer? (arts : ImportArtifacts) := arts.toArray[2]? def ImportArtifacts.oleanPrivate? (arts : ImportArtifacts) := arts.toArray[3]? def ImportArtifacts.oleanParts (inServer : Bool) (arts : ImportArtifacts) : Array System.FilePath := Id.run do let mut fnames := #[] if let some mFile := arts.olean? then fnames := fnames.push mFile if let some sFile := arts.oleanServer? then -- For uniformity, Lake always provides us with .olean.server, so load it only when we are in -- server mode or we need it to load further files. if inServer || arts.oleanPrivate?.isSome then fnames := fnames.push sFile if let some pFile := arts.oleanPrivate? then fnames := fnames.push pFile return fnames /-- Files containing data for a single module. -/ structure ModuleArtifacts where lean? : Option System.FilePath := none olean? : Option System.FilePath := none oleanServer? : Option System.FilePath := none oleanPrivate? : Option System.FilePath := none ilean? : Option System.FilePath := none ir? : Option System.FilePath := none c? : Option System.FilePath := none bc? : Option System.FilePath := none deriving Repr, Inhabited, ToJson, FromJson def ModuleArtifacts.oleanParts (arts : ModuleArtifacts) : Array System.FilePath := Id.run do let mut fnames := #[] if let some mFile := arts.olean? then fnames := fnames.push mFile if let some sFile := arts.oleanServer? then fnames := fnames.push sFile if let some pFile := arts.oleanPrivate? then fnames := fnames.push pFile return fnames /-- The type of module package identifiers. This is a {name}`String` that is used to disambiguate native symbol prefixes between different packages (and different versions of the same package). -/ public abbrev PkgId := String /-- A module's setup information as described by a JSON file. -/ structure ModuleSetup where /-- The name of the module. -/ name : Name /-- The package to which the module belongs (if any). -/ package? : Option PkgId := none /-- Whether the module, by default, participates in the module system. Even if {lean}`false`, a module can still choose to participate by using {lit}`module` in its header. -/ isModule : Bool := false /-- The module's direct imports. If {lean}`none`, uses the imports from the module header. -/ imports? : Option (Array Import) := none /-- Pre-resolved artifacts of transitively imported modules. -/ importArts : NameMap ImportArtifacts := {} /-- Dynamic libraries to load with the module. -/ dynlibs : Array System.FilePath := #[] /-- Plugins to initialize with the module. -/ plugins : Array System.FilePath := #[] /-- Additional options for the module. -/ options : LeanOptions := {} deriving Repr, Inhabited, ToJson, FromJson /-- Load a {lean}`ModuleSetup` from a JSON file. -/ def ModuleSetup.load (path : System.FilePath) : IO ModuleSetup := do let contents ← IO.FS.readFile path match Json.parse contents >>= fromJson? with | .ok info => pure info | .error msg => throw <| IO.userError s!"failed to load header from {path}: {msg}"