}
} else if (data.kind === 'family') {
const fam = familyById.get(target.id());
- if (fam) el.innerHTML = renderFamilyPanel(fam);
+ if (fam) {
+ el.innerHTML = renderFamilyPanel(fam);
+ } else {
+ // External family — not in pdTypeFamilies but referenced
+ // via a FamilyApp somewhere. We still know its package and
+ // module from the QualName, so render a minimal panel.
+ el.innerHTML = renderExternalFamilyPanel(data);
+ }
} else if (data.kind === 'instance') {
el.innerHTML = renderInstancePanel(data.instance);
} else if (data.kind === 'fam-instance') {
</dl>`;
}
+ // External family panel — the family is referenced (so we have a
+ // QualName with package + module), but it isn't in pdTypeFamilies.
+ // We don't know its kind, flavour, or arity, so we just describe
+ // what we *do* know.
+ function renderExternalFamilyPanel(d) {
+ const pkg = d.package || '';
+ const mod = d.module || '';
+ let status;
+ if (pkg && mod) {
+ status = `Defined in module <code>${escape(mod)}</code> ` +
+ `(package <code>${escape(pkg)}</code>) — not extracted ` +
+ `by the plugin in this program. Re-run the plugin against ` +
+ `the package that owns this family if you'd like its ` +
+ `equations to surface here.`;
+ } else if (mod) {
+ status = `Defined in module <code>${escape(mod)}</code> — not ` +
+ `extracted by the plugin in this program.`;
+ } else if (pkg) {
+ status = `Defined in package <code>${escape(pkg)}</code> — not ` +
+ `extracted by the plugin in this program.`;
+ } else {
+ status = `Referenced but not extracted by the plugin in this program.`;
+ }
+ return `
+ <h2>${escape(d.label)}</h2>
+ <p class="pkgmod">${escape(pkg)} · ${escape(mod)}</p>
+ <dl>
+ <dt>Status</dt><dd>${status}</dd>
+ </dl>`;
+ }
+
function renderInstancePanel(inst) {
const head = escape(inst.iiClass.qnName) + ' ' +
escape(renderArgsCompact(inst.iiArgs, inst.iiTyVars));