feat(ui): the type hierarchy — what a type is built on, and what dispatches through it (CG-58)
A vertical tree above the members outline for classes, interfaces, structs, traits, protocols, enums, unions and type aliases: ancestors above (the whole chain, not just the direct parent), the focus in accent, subtypes below indented per level. `extends` draws solid, `implements` dashed; a synthesized edge — Go's implicit interface satisfaction — draws dashed wider and carries the site it was wired at, so a relation the resolver inferred never reads like one the source wrote down. For an interface the fan below IS the set of runtime targets a call can land on, and a type with eight or more implementers leads with that in a sentence. Members that redeclare an ancestor's are marked in the outline. The walk lives in `src/graph/type-hierarchy.ts`, following CG-50/CG-51: shared computation in `src/graph/`, presentation in the caller. Its `countImplementers` is now also what `ToolHandler.buildPolymorphicBoundaries` counts with, so "N types implement X" is the same N whether an agent reads it or a person does. `/api/node` carries the block as `hierarchy` rather than a second endpoint — it is part of the Symbol view's first paint, and gated to types, so a function costs one kind test. Layout is arithmetic (24px rows, 22px indent, orthogonal connectors computed from the two): no ResizeObserver, same payload → same picture. The header's `extends X` / `implemented by …` chips are suppressed while the tree is on screen — two renderings of one relation in one column is how a reader ends up trusting neither. `TypeHierarchy` is exported from `@colbymchenry/codegraph-ui` and takes its data as a prop, so a host holding a `WireSymbolPayload` renders it without a second read.
This commit is contained in:
@@ -111,6 +111,8 @@ export { default as DriftBanner } from './components/DriftBanner.svelte';
|
||||
export { default as KindGlyph } from './components/KindGlyph.svelte';
|
||||
/** Copy image / download SVG for a Flow strip or a Map layout. */
|
||||
export { default as ExportButtons } from './components/ExportButtons.svelte';
|
||||
/** Ancestors up, subtypes down, and the fan an interface call dispatches into. */
|
||||
export { default as TypeHierarchy } from './components/symbol/TypeHierarchy.svelte';
|
||||
|
||||
/* ------------------------------------------------------------- the state -- */
|
||||
|
||||
@@ -174,6 +176,21 @@ export type {
|
||||
FlowLinkLayout,
|
||||
} from './lib/flow-model';
|
||||
|
||||
export {
|
||||
buildHierarchyModel,
|
||||
connectorPath,
|
||||
visibleHierarchy,
|
||||
HIER_FOLD_AT,
|
||||
HIER_INDENT,
|
||||
HIER_PORT_X,
|
||||
HIER_ROW_H,
|
||||
} from './lib/hierarchy-model';
|
||||
export type {
|
||||
HierarchyConnector,
|
||||
HierarchyModel,
|
||||
HierarchyRow,
|
||||
} from './lib/hierarchy-model';
|
||||
|
||||
export { buildMapLayout, isEdgeVisible, moduleMetaLabel } from './lib/map-model';
|
||||
export type {
|
||||
MapEdgeLayout,
|
||||
|
||||
Reference in New Issue
Block a user