/- Infoductor.Foundation.MacroAlias — `@[macroAlias]` attribute =============================================================== Phase C of `docs/ALGEBRA_PLAN.md`. Provides the user-extensible registry of frozen `restructure` invocations. When a developer notices that a `restructure` invocation pattern recurs ("oh, this is just a relocate-with-namespace-fixup"), they attach `@[macroAlias]` to a `def` that wraps the pattern. The attribute records the alias in a global registry (`AliasRegistry`) keyed by name. The widget can then suggest "name this pattern as X" when an instantiation matches an existing alias's signature. Per ALGEBRA_PLAN §2.3: > The codebase ships with `restructure` itself (~150 lines). Each > `@[macroAlias] def …` is a 1–3-line shorthand. This module provides the attribute and the registry; concrete alias declarations (`transport_artifact`, `relocate_invariant`, …) live in `Algebra/Restructure.lean`. -/ import Lean import Infoductor.Foundation.Restructure namespace Infoductor open Lean -- ── The alias registry ────────────────────────────────────────────────────── /-- An entry in the alias registry: a `Name` paired with its documentary description (extracted from the `def`'s docstring if present). -/ structure AliasEntry where name : Name description : String := "" deriving Repr, Inhabited /-- Global registry of `@[macroAlias]`-tagged declarations, indexed by name. Implemented as a Lean `EnvExtension` so that adds in one module are visible from any importing module. Per ALGEBRA_PLAN §10 OQ #2 the registry is on-the-fly; persistence via `lake exe algebra-cache` is deferred. -/ initialize aliasRegistryExt : SimplePersistentEnvExtension AliasEntry (Array AliasEntry) ← registerSimplePersistentEnvExtension { name := `Infoductor.aliasRegistry addEntryFn := fun arr e => arr.push e addImportedFn := fun arrs => arrs.foldl (init := #[]) Array.append asyncMode := .sync } /-- Look up every registered alias. Order is unspecified (no guarantees beyond "all registered entries are in the array"). -/ def getAliases : CoreM (Array AliasEntry) := do let env ← getEnv return aliasRegistryExt.getState env /-- Register an alias entry. Inserts into the env extension. -/ def registerAlias (entry : AliasEntry) : CoreM Unit := do modifyEnv (aliasRegistryExt.addEntry · entry) -- ── The `@[macroAlias]` attribute ─────────────────────────────────────────── /-- Lean attribute syntax registered as `@[macroAlias]`. Attached to a `def` to register it as a frozen `restructure` invocation accessible via `Infoductor.getAliases`. -/ initialize macroAliasAttr : Unit ← registerBuiltinAttribute { name := `macroAlias descr := "Register this declaration as a `restructure` alias \ (Phase C of ALGEBRA_PLAN.md). The decl's name and \ docstring become an `AliasEntry` in the global \ `aliasRegistryExt`." add := fun declName _stx _kind => do let env ← getEnv let docstring? := (← findDocString? env declName).getD "" registerAlias { name := declName, description := docstring? } } -- ── Diagnostics ───────────────────────────────────────────────────────────── /-- Print the current alias registry to `IO.println`. Used by `lake exe algebra-list-aliases` and the widget's "show registered aliases" button. -/ def printAliases : CoreM Unit := do let aliases ← getAliases IO.println s!"── Algebra macro-alias registry ({aliases.size}) ──" for entry in aliases do if entry.description.isEmpty then IO.println s!" {entry.name}" else IO.println s!" {entry.name} — {entry.description}" end Infoductor