feat: instances for

main
Henrik Böving 2022-07-23 15:40:08 +02:00
parent 3aae640f69
commit 247b930364
9 changed files with 75 additions and 12 deletions

View File

@ -127,6 +127,7 @@ def htmlOutputIndex (baseConfig : SiteBaseContext) : IO Unit := do
let mut allInstances : HashMap String (Array String) := .empty let mut allInstances : HashMap String (Array String) := .empty
let mut importedBy : HashMap String (Array String) := .empty let mut importedBy : HashMap String (Array String) := .empty
let mut allModules : List (String × Json) := [] let mut allModules : List (String × Json) := []
let mut instancesFor : HashMap String (Array String) := .empty
for entry in ←System.FilePath.readDir declarationsBasePath do for entry in ←System.FilePath.readDir declarationsBasePath do
if entry.fileName.startsWith "declaration-data-" && entry.fileName.endsWith ".bmp" then if entry.fileName.startsWith "declaration-data-" && entry.fileName.endsWith ".bmp" then
let fileContent ← FS.readFile entry.path let fileContent ← FS.readFile entry.path
@ -138,6 +139,10 @@ def htmlOutputIndex (baseConfig : SiteBaseContext) : IO Unit := do
let mut insts := allInstances.findD inst.className #[] let mut insts := allInstances.findD inst.className #[]
insts := insts.push inst.name insts := insts.push inst.name
allInstances := allInstances.insert inst.className insts allInstances := allInstances.insert inst.className insts
for typeName in inst.typeNames do
let mut instsFor := instancesFor.findD typeName #[]
instsFor := instsFor.push inst.name
instancesFor := instancesFor.insert typeName instsFor
for imp in module.imports do for imp in module.imports do
let mut impBy := importedBy.findD imp #[] let mut impBy := importedBy.findD imp #[]
impBy := impBy.push module.name impBy := impBy.push module.name
@ -145,11 +150,14 @@ def htmlOutputIndex (baseConfig : SiteBaseContext) : IO Unit := do
let postProcessInstances := allInstances.toList.map (λ(k, v) => (k, toJson v)) let postProcessInstances := allInstances.toList.map (λ(k, v) => (k, toJson v))
let postProcessImportedBy := importedBy.toList.map (λ(k, v) => (k, toJson v)) let postProcessImportedBy := importedBy.toList.map (λ(k, v) => (k, toJson v))
let postProcessInstancesFor := instancesFor.toList.map (λ(k, v) => (k, toJson v))
let finalJson := Json.mkObj [ let finalJson := Json.mkObj [
("declarations", Json.mkObj allDecls), ("declarations", Json.mkObj allDecls),
("instances", Json.mkObj postProcessInstances), ("instances", Json.mkObj postProcessInstances),
("importedBy", Json.mkObj postProcessImportedBy), ("importedBy", Json.mkObj postProcessImportedBy),
("modules", Json.mkObj allModules) ("modules", Json.mkObj allModules),
("instancesFor", Json.mkObj postProcessInstancesFor)
] ]
-- The root JSON for find -- The root JSON for find
FS.writeFile (declarationsBasePath / "declaration-data.bmp") finalJson.compress FS.writeFile (declarationsBasePath / "declaration-data.bmp") finalJson.compress

View File

@ -8,9 +8,6 @@ namespace Output
open scoped DocGen4.Jsx open scoped DocGen4.Jsx
open Lean open Lean
--def classInstanceToHtml (name : Name) : HtmlM Html := do
-- pure <li>{←declNameToHtmlLink name}</li>
def classInstancesToHtml (className : Name) : HtmlM Html := do def classInstancesToHtml (className : Name) : HtmlM Html := do
pure pure
<details «class»="instances"> <details «class»="instances">

View File

@ -6,6 +6,14 @@ namespace DocGen4
namespace Output namespace Output
open scoped DocGen4.Jsx open scoped DocGen4.Jsx
open Lean
def instancesForToHtml (typeName : Name) : HtmlM Html := do
pure
<details «class»="instances">
<summary>Instances For</summary>
<ul id={s!"instances-for-list-{typeName}"} class="instances-for-list"></ul>
</details>
def ctorToHtml (c : Process.NameInfo) : HtmlM Html := do def ctorToHtml (c : Process.NameInfo) : HtmlM Html := do
let shortName := c.name.components'.head!.toString let shortName := c.name.components'.head!.toString

View File

@ -106,6 +106,8 @@ def docInfoToHtml (module : Name) (doc : DocInfo) : HtmlM Html := do
| DocInfo.definitionInfo i => equationsToHtml i | DocInfo.definitionInfo i => equationsToHtml i
| DocInfo.instanceInfo i => equationsToHtml i.toDefinitionInfo | DocInfo.instanceInfo i => equationsToHtml i.toDefinitionInfo
| DocInfo.classInductiveInfo i => pure #[←classInstancesToHtml i.name] | DocInfo.classInductiveInfo i => pure #[←classInstancesToHtml i.name]
| DocInfo.inductiveInfo i => pure #[←instancesForToHtml i.name]
| DocInfo.structureInfo i => pure #[←instancesForToHtml i.name]
| _ => pure #[] | _ => pure #[]
let attrs := doc.getAttrs let attrs := doc.getAttrs
let attrsHtml := let attrsHtml :=

View File

@ -17,6 +17,7 @@ structure JsonDeclaration where
structure JsonInstance where structure JsonInstance where
name : String name : String
className : String className : String
typeNames : Array String
deriving FromJson, ToJson deriving FromJson, ToJson
structure JsonModule where structure JsonModule where
@ -40,11 +41,15 @@ def Process.Module.toJson (module : Process.Module) : HtmlM Json := do
for decl in declInfo do for decl in declInfo do
jsonDecls := (←DocInfo.toJson module.name decl) :: jsonDecls jsonDecls := (←DocInfo.toJson module.name decl) :: jsonDecls
if let .instanceInfo i := decl then if let .instanceInfo i := decl then
instances := instances.push { name := i.name.toString, className := i.className.toString} instances := instances.push {
name := i.name.toString,
className := i.className.toString
typeNames := i.typeNames.map Name.toString
}
let jsonMod : JsonModule := { let jsonMod : JsonModule := {
name := module.name.toString, name := module.name.toString,
declarations := jsonDecls, declarations := jsonDecls,
instances := instances instances,
imports := module.imports.map Name.toString imports := module.imports.map Name.toString
} }
pure <| ToJson.toJson jsonMod pure <| ToJson.toJson jsonMod

View File

@ -105,6 +105,7 @@ Information about an `instance` declaration.
-/ -/
structure InstanceInfo extends DefinitionInfo where structure InstanceInfo extends DefinitionInfo where
className : Name className : Name
typeNames : Array Name
deriving Inhabited deriving Inhabited
/-- /--

View File

@ -13,16 +13,28 @@ namespace DocGen4.Process
open Lean Meta open Lean Meta
def getInstanceTypes (typ : Expr) : MetaM (Array Name) := do
let (_, _, tail) ← forallMetaTelescopeReducing typ
let args := tail.getAppArgs
let (_, bar) ← args.mapM (Expr.forEach · findName) |>.run .empty
pure bar
where
findName : Expr → StateRefT (Array Name) MetaM Unit
| .const name _ => do set <| (←get).push name
| _ => pure ()
def InstanceInfo.ofDefinitionVal (v : DefinitionVal) : MetaM InstanceInfo := do def InstanceInfo.ofDefinitionVal (v : DefinitionVal) : MetaM InstanceInfo := do
let mut info ← DefinitionInfo.ofDefinitionVal v let mut info ← DefinitionInfo.ofDefinitionVal v
let some className := getClassName (←getEnv) v.type | unreachable! let some className := getClassName (←getEnv) v.type | unreachable!
if let some instAttr ← getDefaultInstance v.name className then if let some instAttr ← getDefaultInstance v.name className then
info := { info with attrs := info.attrs.push instAttr } info := { info with attrs := info.attrs.push instAttr }
let typeNames ← getInstanceTypes v.type
pure { pure {
toDefinitionInfo := info, toDefinitionInfo := info,
className className,
typeNames
} }
end DocGen4.Process end DocGen4.Process

View File

@ -92,6 +92,19 @@ export class DeclarationDataCenter {
} }
} }
/**
* Search for all instances that involve a certain type
* @returns {Array<String>}
*/
instancesForType(typeName) {
const instances = this.declarationData.instancesFor[typeName];
if (!instances) {
return [];
} else {
return instances;
}
}
/** /**
* Analogous to Lean declNameToLink * Analogous to Lean declNameToLink
* @returns {String} * @returns {String}

View File

@ -1,19 +1,36 @@
import { DeclarationDataCenter } from "./declaration-data.js"; import { DeclarationDataCenter } from "./declaration-data.js";
annotateInstances(); annotateInstances();
annotateInstancesFor()
async function annotateInstances() { async function annotateInstances() {
const dataCenter = await DeclarationDataCenter.init(); const dataCenter = await DeclarationDataCenter.init();
const instanceLists = [...(document.querySelectorAll(".instances-list"))]; const instanceForLists = [...(document.querySelectorAll(".instances-list"))];
for (const instanceList of instanceLists) { for (const instanceForList of instanceForLists) {
const className = instanceList.id.slice("instances-list-".length); const className = instanceForList.id.slice("instances-list-".length);
const instances = dataCenter.instancesForClass(className); const instances = dataCenter.instancesForClass(className);
var innerHTML = ""; var innerHTML = "";
for(var instance of instances) { for(var instance of instances) {
const instanceLink = dataCenter.declNameToLink(instance); const instanceLink = dataCenter.declNameToLink(instance);
innerHTML += `<li><a href="${SITE_ROOT}${instanceLink}">${instance}</a></li>` innerHTML += `<li><a href="${SITE_ROOT}${instanceLink}">${instance}</a></li>`
} }
instanceList.innerHTML = innerHTML; instanceForList.innerHTML = innerHTML;
}
}
async function annotateInstancesFor() {
const dataCenter = await DeclarationDataCenter.init();
const instanceForLists = [...(document.querySelectorAll(".instances-for-list"))];
for (const instanceForList of instanceForLists) {
const typeName = instanceForList.id.slice("instances-for-list-".length);
const instances = dataCenter.instancesForType(typeName);
var innerHTML = "";
for(var instance of instances) {
const instanceLink = dataCenter.declNameToLink(instance);
innerHTML += `<li><a href="${SITE_ROOT}${instanceLink}">${instance}</a></li>`
}
instanceForList.innerHTML = innerHTML;
} }
} }