2022-07-22 12:48:36 +00:00
|
|
|
|
import Lean
|
|
|
|
|
import DocGen4.Process
|
|
|
|
|
import DocGen4.Output.Base
|
2023-08-06 13:36:43 +00:00
|
|
|
|
import DocGen4.Output.Module
|
2022-10-05 10:05:58 +00:00
|
|
|
|
import Lean.Data.RBMap
|
2022-07-22 12:48:36 +00:00
|
|
|
|
|
|
|
|
|
namespace DocGen4.Output
|
|
|
|
|
|
2022-10-05 10:05:58 +00:00
|
|
|
|
open Lean
|
2022-07-22 12:48:36 +00:00
|
|
|
|
|
2023-08-06 13:36:43 +00:00
|
|
|
|
structure JsonDeclarationInfo where
|
2022-07-22 12:48:36 +00:00
|
|
|
|
name : String
|
2023-01-31 19:31:27 +00:00
|
|
|
|
kind : String
|
2022-07-22 12:48:36 +00:00
|
|
|
|
doc : String
|
|
|
|
|
docLink : String
|
|
|
|
|
sourceLink : String
|
2023-08-06 13:36:43 +00:00
|
|
|
|
line : Nat
|
2022-07-22 12:48:36 +00:00
|
|
|
|
deriving FromJson, ToJson
|
|
|
|
|
|
2023-08-06 13:36:43 +00:00
|
|
|
|
structure JsonDeclaration where
|
|
|
|
|
info : JsonDeclarationInfo
|
|
|
|
|
header : String
|
|
|
|
|
deriving FromJson, ToJson
|
|
|
|
|
|
2022-07-22 12:48:36 +00:00
|
|
|
|
structure JsonInstance where
|
|
|
|
|
name : String
|
|
|
|
|
className : String
|
2022-07-23 13:40:08 +00:00
|
|
|
|
typeNames : Array String
|
2022-07-22 12:48:36 +00:00
|
|
|
|
deriving FromJson, ToJson
|
|
|
|
|
|
|
|
|
|
structure JsonModule where
|
|
|
|
|
name : String
|
|
|
|
|
declarations : List JsonDeclaration
|
|
|
|
|
instances : Array JsonInstance
|
|
|
|
|
imports : Array String
|
|
|
|
|
deriving FromJson, ToJson
|
|
|
|
|
|
2023-08-06 13:36:43 +00:00
|
|
|
|
structure JsonHeaderIndex where
|
2023-09-14 22:39:28 +00:00
|
|
|
|
declarations : List (String × JsonDeclaration) := []
|
2023-08-06 13:36:43 +00:00
|
|
|
|
|
2023-09-10 10:39:37 +00:00
|
|
|
|
structure JsonIndexedDeclarationInfo where
|
|
|
|
|
kind : String
|
|
|
|
|
docLink : String
|
|
|
|
|
deriving FromJson, ToJson
|
|
|
|
|
|
2023-12-09 23:37:14 +00:00
|
|
|
|
structure JsonIndexedModule where
|
|
|
|
|
importedBy : Array String
|
|
|
|
|
url : String
|
|
|
|
|
deriving FromJson, ToJson
|
|
|
|
|
|
2022-07-23 18:40:08 +00:00
|
|
|
|
structure JsonIndex where
|
2023-09-10 10:39:37 +00:00
|
|
|
|
declarations : List (String × JsonIndexedDeclarationInfo) := []
|
2023-07-31 18:42:15 +00:00
|
|
|
|
instances : HashMap String (RBTree String Ord.compare) := .empty
|
2023-12-09 23:37:14 +00:00
|
|
|
|
modules : HashMap String JsonIndexedModule := {}
|
2023-07-31 18:42:15 +00:00
|
|
|
|
instancesFor : HashMap String (RBTree String Ord.compare) := .empty
|
2022-07-23 18:40:08 +00:00
|
|
|
|
|
2023-08-06 13:36:43 +00:00
|
|
|
|
instance : ToJson JsonHeaderIndex where
|
2023-09-14 22:39:28 +00:00
|
|
|
|
toJson idx := Json.mkObj <| idx.declarations.map (fun (k, v) => (k, toJson v))
|
2023-08-06 13:36:43 +00:00
|
|
|
|
|
2022-07-23 18:40:08 +00:00
|
|
|
|
instance : ToJson JsonIndex where
|
|
|
|
|
toJson idx := Id.run do
|
2023-01-01 18:51:01 +00:00
|
|
|
|
let jsonDecls := Json.mkObj <| idx.declarations.map (fun (k, v) => (k, toJson v))
|
2023-07-31 18:42:15 +00:00
|
|
|
|
let jsonInstances := Json.mkObj <| idx.instances.toList.map (fun (k, v) => (k, toJson v.toArray))
|
2023-12-09 23:37:14 +00:00
|
|
|
|
let jsonModules := Json.mkObj <| idx.modules.toList.map (fun (k, v) => (k, toJson v))
|
2023-07-31 18:42:15 +00:00
|
|
|
|
let jsonInstancesFor := Json.mkObj <| idx.instancesFor.toList.map (fun (k, v) => (k, toJson v.toArray))
|
2022-07-23 18:40:08 +00:00
|
|
|
|
let finalJson := Json.mkObj [
|
|
|
|
|
("declarations", jsonDecls),
|
|
|
|
|
("instances", jsonInstances),
|
|
|
|
|
("modules", jsonModules),
|
|
|
|
|
("instancesFor", jsonInstancesFor)
|
|
|
|
|
]
|
2023-01-01 18:51:01 +00:00
|
|
|
|
return finalJson
|
2022-07-23 18:40:08 +00:00
|
|
|
|
|
2023-08-06 13:36:43 +00:00
|
|
|
|
def JsonHeaderIndex.addModule (index : JsonHeaderIndex) (module : JsonModule) : JsonHeaderIndex :=
|
2023-09-14 22:39:28 +00:00
|
|
|
|
let merge idx decl := { idx with declarations := (decl.info.name, decl) :: idx.declarations }
|
2023-08-06 13:36:43 +00:00
|
|
|
|
module.declarations.foldl merge index
|
|
|
|
|
|
2022-07-23 18:40:08 +00:00
|
|
|
|
def JsonIndex.addModule (index : JsonIndex) (module : JsonModule) : BaseHtmlM JsonIndex := do
|
|
|
|
|
let mut index := index
|
2023-09-10 10:39:37 +00:00
|
|
|
|
let newDecls := module.declarations.map (fun d => (d.info.name, {
|
|
|
|
|
kind := d.info.kind,
|
|
|
|
|
docLink := d.info.docLink,
|
|
|
|
|
}))
|
2022-07-23 18:40:08 +00:00
|
|
|
|
index := { index with
|
|
|
|
|
declarations := newDecls ++ index.declarations
|
|
|
|
|
}
|
2023-12-09 23:37:14 +00:00
|
|
|
|
|
2022-07-23 18:40:08 +00:00
|
|
|
|
-- TODO: In theory one could sort instances and imports by name and batch the writes
|
|
|
|
|
for inst in module.instances do
|
2023-07-31 18:42:15 +00:00
|
|
|
|
let mut insts := index.instances.findD inst.className {}
|
|
|
|
|
insts := insts.insert inst.name
|
2022-07-23 18:40:08 +00:00
|
|
|
|
index := { index with instances := index.instances.insert inst.className insts }
|
|
|
|
|
for typeName in inst.typeNames do
|
2023-07-31 18:42:15 +00:00
|
|
|
|
let mut instsFor := index.instancesFor.findD typeName {}
|
|
|
|
|
instsFor := instsFor.insert inst.name
|
2022-07-23 18:40:08 +00:00
|
|
|
|
index := { index with instancesFor := index.instancesFor.insert typeName instsFor }
|
|
|
|
|
|
2023-12-09 23:37:14 +00:00
|
|
|
|
-- TODO: dedup
|
|
|
|
|
if index.modules.find? module.name |>.isNone then
|
|
|
|
|
let moduleLink ← moduleNameToLink (String.toName module.name)
|
|
|
|
|
let indexedModule := { url := moduleLink, importedBy := #[] }
|
|
|
|
|
index := { index with modules := index.modules.insert module.name indexedModule }
|
|
|
|
|
|
2022-07-23 18:40:08 +00:00
|
|
|
|
for imp in module.imports do
|
2023-12-09 23:37:14 +00:00
|
|
|
|
let indexedImp ←
|
|
|
|
|
match index.modules.find? imp with
|
|
|
|
|
| some i => pure i
|
|
|
|
|
| none =>
|
|
|
|
|
let impLink ← moduleNameToLink (String.toName imp)
|
|
|
|
|
let indexedModule := { url := impLink, importedBy := #[] }
|
|
|
|
|
pure indexedModule
|
|
|
|
|
index := { index with
|
|
|
|
|
modules :=
|
|
|
|
|
index.modules.insert
|
|
|
|
|
imp
|
|
|
|
|
{ indexedImp with importedBy := indexedImp.importedBy.push module.name }
|
|
|
|
|
}
|
2023-01-01 18:51:01 +00:00
|
|
|
|
return index
|
2022-07-23 18:40:08 +00:00
|
|
|
|
|
2022-07-22 12:48:36 +00:00
|
|
|
|
def DocInfo.toJson (module : Name) (info : Process.DocInfo) : HtmlM JsonDeclaration := do
|
|
|
|
|
let name := info.getName.toString
|
2023-01-31 19:31:27 +00:00
|
|
|
|
let kind := info.getKind
|
2022-07-22 12:48:36 +00:00
|
|
|
|
let doc := info.getDocString.getD ""
|
|
|
|
|
let docLink ← declNameToLink info.getName
|
|
|
|
|
let sourceLink ← getSourceUrl module info.getDeclarationRange
|
2023-08-06 13:36:43 +00:00
|
|
|
|
let line := info.getDeclarationRange.pos.line
|
|
|
|
|
let header := (← docInfoHeader info).toString
|
|
|
|
|
let info := { name, kind, doc, docLink, sourceLink, line }
|
|
|
|
|
return { info, header }
|
2022-07-22 12:48:36 +00:00
|
|
|
|
|
|
|
|
|
def Process.Module.toJson (module : Process.Module) : HtmlM Json := do
|
|
|
|
|
let mut jsonDecls := []
|
|
|
|
|
let mut instances := #[]
|
2023-02-16 18:51:35 +00:00
|
|
|
|
let declInfo := Process.filterDocInfo module.members
|
2022-07-22 12:48:36 +00:00
|
|
|
|
for decl in declInfo do
|
2023-01-01 18:51:01 +00:00
|
|
|
|
jsonDecls := (← DocInfo.toJson module.name decl) :: jsonDecls
|
2022-07-22 12:48:36 +00:00
|
|
|
|
if let .instanceInfo i := decl then
|
2022-07-23 13:40:08 +00:00
|
|
|
|
instances := instances.push {
|
|
|
|
|
name := i.name.toString,
|
|
|
|
|
className := i.className.toString
|
|
|
|
|
typeNames := i.typeNames.map Name.toString
|
|
|
|
|
}
|
2022-07-22 12:48:36 +00:00
|
|
|
|
let jsonMod : JsonModule := {
|
|
|
|
|
name := module.name.toString,
|
|
|
|
|
declarations := jsonDecls,
|
2022-07-23 13:40:08 +00:00
|
|
|
|
instances,
|
2022-07-22 12:48:36 +00:00
|
|
|
|
imports := module.imports.map Name.toString
|
|
|
|
|
}
|
2023-01-01 18:51:01 +00:00
|
|
|
|
return ToJson.toJson jsonMod
|
2022-07-22 12:48:36 +00:00
|
|
|
|
|
|
|
|
|
end DocGen4.Output
|