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; } } } /** * 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 =