if (seenNodes.has(id)) return id;
seenNodes.add(id);
const known = classById.get(id);
+ // Include the class's tyvars in the label when we have them
+ // (i.e. the class is defined in this project). External classes
+ // fall back to bare qnName — we don't have their tyvars here.
+ const label = (known && known.ciTyVars && known.ciTyVars.length > 0)
+ ? known.ciName.qnName + ' ' + known.ciTyVars.map(tv => tv.tvName).join(' ')
+ : qn.qnName;
els.push({ group: 'nodes', data: Object.assign({
id,
- label: qn.qnName,
+ label,
kind: 'class',
external: !known,
package: qn.qnPackage,
if (seenNodes.has(id)) return id;
seenNodes.add(id);
const known = classById.get(id);
+ const label = (known && known.ciTyVars && known.ciTyVars.length > 0)
+ ? known.ciName.qnName + ' ' + known.ciTyVars.map(tv => tv.tvName).join(' ')
+ : qn.qnName;
els.push({ group: 'nodes', data: {
id,
- label: qn.qnName,
+ label,
kind: 'class',
external: !known,
package: qn.qnPackage,
classNodes =
[ CyNode $ Aeson.object
[ "id" Aeson..= renderQualName (ciName c)
- , "label" Aeson..= qnName (ciName c)
+ , "label" Aeson..= classNodeLabel c
, "kind" Aeson..= ("class" :: Text)
, "module" Aeson..= qnModule (ciName c)
, "package" Aeson..= qnPackage (ciName c)
| c <- pdClasses pd
]
+ -- A class node renders as `Foo a b c`, with the same names the
+ -- user wrote. Edge labels (positional substitution into a
+ -- superclass's args) keep using the *origin* class's tyvar names
+ -- via 'edgeLabel', so an arrow from `Bar a b` up to `Foo a` reads
+ -- as `(a)` on the edge and `Foo a` on the target node — same
+ -- letter, no aliasing.
+ classNodeLabel c = case ciTyVars c of
+ [] -> qnName (ciName c)
+ tvs -> qnName (ciName c) <> " "
+ <> T.intercalate " " (map tvName tvs)
+
familyNodes =
[ CyNode $ Aeson.object
[ "id" Aeson..= renderQualName (tfName f)