let dumpTypes = options['dump-types'].split(','); let interestingList = {}; let typelist = {}; function interestingType(t) { let name = t.name; if (dumpTypes.some(function(n) n == name)) { interestingList[name] = t; typelist[name] = t; return true; } for each (let base in t.bases) { if (base.access == 'public' && interestingType(base.type)) { typelist[name] = t; return true; } } return false; } function addSubtype(t, subt) { if (subt.typedef === undefined && subt.kind === undefined) throw Error("Unexpected subtype: not class or typedef: " + subt); if (t.subtypes === undefined) t.subtypes = []; t.subtypes.push(subt); } function process_type(t) { interestingType(t); for each (let base in t.bases) addSubtype(base.type, t); } function process_decl(d) { if (d.typedef !== undefined && d.memberOf) addSubtype(d.memberOf, d); } function publicBases(t) { yield t; for each (let base in t.bases) if (base.access == "public") for each (let gbase in publicBases(base.type)) yield gbase; } function publicMembers(t) { for each (let base in publicBases(t)) { for each (let member in base.members) { if (member.access === undefined) throw Error("Harumph: member without access? " + member); if (member.access != "public") continue; yield member; } } } function signaturesMatch(m1, m2) { let p1 = m1.type.parameters; let p2 = m2.type.parameters; if (p1.length != p2.length) return false; for (let i = 0; i < p1.length; ++i) if (p1[i] !== p2[i]) return false; return true; } /** * Get the short name of a decl name. E.g. turn * "MyNamespace::MyClass::Method(int j) const" into * "Method" */ function getShortName(decl) { let name = decl.name; let lp = name.lastIndexOf('('); if (lp != -1) name = name.slice(0, lp); lp = name.lastIndexOf('::'); if (lp != -1) name = name.slice(lp + 2); return name; } /** * Remove functions in a base class which were overridden in a derived * class. * * Although really, we should perhaps do this the other way around, or even * group the two together, but that can come later. */ function removeOverrides(members) { let overrideMap = {}; for (let i = members.length - 1; i >= 0; --i) { let m = members[i]; if (!m.isFunction) continue; let shortName = getShortName(m); let overrides = overrideMap[shortName]; if (overrides === undefined) { overrideMap[shortName] = [m]; continue; } let found = false; for each (let override in overrides) { if (signaturesMatch(override, m)) { // remove members[i], it was overridden members.splice(i, 1); found = true; } } if (found) continue; overrides.push(m); } } /** * Generates the starting position of lines within a file. */ function getLineLocations(fdata) { yield 0; let r = /\n/y; let pos = 0; let i = 1; for (;;) { pos = fdata.indexOf('\n', pos) + 1; if (pos == 0) break; yield pos; i++; } } /** * Find and return the doxygen comment immediately prior to the location * object that was passed in. * * @todo: parse doccomment data such as @param, @returns * @todo: parse comments for markup */ function getDocComment(loc) { let fdata = read_file(loc.file); let linemap = [l for (l in getLineLocations(fdata))]; if (loc.line >= linemap.length) { warning("Location larger than actual header: " + loc); return <>>; } let endpos = linemap[loc.line - 1] + loc.column - 1; let semipos = fdata.lastIndexOf(';', endpos); let bracepos = fdata.lastIndexOf('}', endpos); let searchslice = fdata.slice(Math.max(semipos, bracepos) + 1, endpos); let m = searchslice.match(/\/\*\*[\s\S]*?\*\//gm); if (m === null) return <>>; let dc = m[m.length - 1].slice(3, -2); dc = dc.replace(/^\s*(\*+[ \t]*)?/gm, ""); return
{dc}; } function typeName(t) { if (t.name !== undefined) return t.name; if (t.isPointer) return "%s%s*".format(t.isConst ? "const " : "", typeName(t.type)); if (t.isReference) return "%s%s&".format(t.isConst ? "const " : "", typeName(t.type)); return t.toString(); } function publicBaseList(t) { let l =
{typeName(m.type.type)} {name}
- {getLocLink(m.loc, "source")}
{getLocLink(t.loc, "Class Declaration")}
{getDocComment(t.loc)} {dumpTypes.some(function(n) n == t.name) ? <> [MAP{t.name}-graph.map] > : <>> } {methodOverview.*.length() > 0 ? <>No public members.
}No public methods.
} ; write_file(t.name + ".html", r.toXMLString()); } function graphType(t) { print("GRAPH-TYPE(%s)".format(t.name)); let contents = "digraph classes {\n" + " node [shape=rectangle fontsize=11]\n" + " %s;\n".format(t.name); function graphClass(c) { contents += '%s [URL="http://developer.mozilla.org/en/%s"]\n'.format(c.name, c.name); for each (let st in c.subtypes) { contents += " %s -> %s;\n".format(c.name, st.name); graphClass(st); } } graphClass(t); contents += "}\n"; write_file(t.name + "-graph.gv", contents); } function input_end() { for (let p in typelist) dumpType(typelist[p]); for (let n in interestingList) graphType(interestingList[n]); }