1 let dumpTypes = options['dump-types'].split(',');
3 let interestingList = {};
6 function interestingType(t)
10 if (dumpTypes.some(function(n) n == name)) {
11 interestingList[name] = t;
16 for each (let base in t.bases) {
17 if (base.access == 'public' && interestingType(base.type)) {
26 function addSubtype(t, subt)
28 if (subt.typedef === undefined &&
29 subt.kind === undefined)
30 throw Error("Unexpected subtype: not class or typedef: " + subt);
32 if (t.subtypes === undefined)
35 t.subtypes.push(subt);
38 function process_type(t)
42 for each (let base in t.bases)
43 addSubtype(base.type, t);
46 function process_decl(d)
48 if (d.typedef !== undefined && d.memberOf)
49 addSubtype(d.memberOf, d);
52 function publicBases(t)
56 for each (let base in t.bases)
57 if (base.access == "public")
58 for each (let gbase in publicBases(base.type))
62 function publicMembers(t)
64 for each (let base in publicBases(t)) {
65 for each (let member in base.members) {
66 if (member.access === undefined)
67 throw Error("Harumph: member without access? " + member);
69 if (member.access != "public")
78 * Get the short name of a decl name. E.g. turn
79 * "MyNamespace::MyClass::Method(int j) const" into
82 function getShortName(decl)
85 let lp = name.lastIndexOf('(');
87 name = name.slice(0, lp);
89 lp = name.lastIndexOf('::');
91 name = name.slice(lp + 2);
97 * Remove functions in a base class which were overridden in a derived
100 * Although really, we should perhaps do this the other way around, or even
101 * group the two together, but that can come later.
103 function removeOverrides(members)
105 let overrideMap = {};
106 for (let i = members.length - 1; i >= 0; --i) {
111 let shortName = getShortName(m);
113 let overrides = overrideMap[shortName];
114 if (overrides === undefined) {
115 overrideMap[shortName] = [m];
120 for each (let override in overrides) {
121 if (signaturesMatch(override, m)) {
122 // remove members[i], it was overridden
123 members.splice(i, 1);
135 * Generates the starting position of lines within a file.
137 function getLineLocations(fdata)
145 pos = fdata.indexOf('\n', pos) + 1;
155 * Find and return the doxygen comment immediately prior to the location
156 * object that was passed in.
158 * @todo: parse doccomment data such as @param, @returns
159 * @todo: parse comments for markup
161 function getDocComment(loc)
163 let fdata = read_file(loc.file);
164 let linemap = [l for (l in getLineLocations(fdata))];
166 if (loc.line >= linemap.length) {
167 warning("Location larger than actual header: " + loc);
171 let endpos = linemap[loc.line - 1] + loc.column - 1;
172 let semipos = fdata.lastIndexOf(';', endpos);
173 let bracepos = fdata.lastIndexOf('}', endpos);
174 let searchslice = fdata.slice(Math.max(semipos, bracepos) + 1, endpos);
176 let m = searchslice.match(/\/\*\*[\s\S]*?\*\//gm);
180 let dc = m[m.length - 1].slice(3, -2);
181 dc = dc.replace(/^\s*(\*+[ \t]*)?/gm, "");
183 return <pre class="doccomment">{dc}</pre>;
188 if (t.name !== undefined)
192 return "%s%s*".format(t.isConst ? "const " : "", typeName(t.type));
195 return "%s%s&".format(t.isConst ? "const " : "", typeName(t.type));
200 function publicBaseList(t)
203 for each (let b in t.bases) {
204 if (b.access == 'public')
205 l.* += <li><a href={"/en/%s".format(b.type.name)}>{b.type.name}</a></li>;
208 if (l.*.length() == 0)
212 <h2>Base Classes</h2>
218 * Get a source-link for a given location.
220 function getLocLink(loc, text)
222 return <a class="loc"
223 href={"http://hg.mozilla.org/mozilla-central/file/%s/[LOC%s]#l%i".format(options.rev, loc.file, loc.line)}>{text}</a>;
228 print("DUMP-TYPE(%s)".format(t.name));
230 let methodOverview = <tbody />;
231 let methodList = <div/>;
232 let memberList = <></>;
234 let shortNameMap = {};
236 let members = [m for (m in publicMembers(t))];
238 removeOverrides(members);
240 for each (let m in members) {
241 let qname = m.memberOf.name + '::';
243 // we don't inherit constructors from base classes
244 if (m.isConstructor && m.memberOf !== t)
247 if (m.name.indexOf(qname) != 0)
248 throw Error("Member name not qualified?");
250 let name = m.name.slice(qname.length);
252 if (name.indexOf('~') == 0)
258 let shortName = getShortName(m);
260 shortName = 'Constructors';
262 if (shortNameMap.hasOwnProperty(shortName)) {
263 innerList = shortNameMap[shortName];
268 <a href={'#%s'.format(escape(shortName))}>{shortName}</a>
272 methodOverview.insertChildAfter(null, overview);
274 methodOverview.appendChild(overview);
278 <h3 id={shortName}>{shortName}</h3>
284 methodList.insertChildAfter(null, shortMarkup);
286 methodList.appendChild(shortMarkup);
288 innerList = shortMarkup.dl;
289 shortNameMap[shortName] = innerList;
292 let parameters = <ul/>;
293 for each (p in m.parameters) {
298 if (/^D_\d+$/.test(name))
299 name = '<anonymous>';
301 parameters.* += <li>{typeName(p.type)} {name}</li>;
306 <dt id={name} class="methodName">
307 <code>{typeName(m.type.type)} {name}</code> - {getLocLink(m.loc, "source")}
310 {getDocComment(m.loc)}
311 {parameters.*.length() > 0 ?
320 memberList += <li class="member">{name}</li>;
326 <p>{getLocLink(t.loc, "Class Declaration")}</p>
328 {getDocComment(t.loc)}
330 {dumpTypes.some(function(n) n == t.name) ?
332 [MAP{t.name}-graph.map]
333 <img src={"/@api/deki/pages/=en%%252F%s/files/=%s-graph.png".format(t.name, t.name)} usemap="#classes" />
337 {methodOverview.*.length() > 0 ?
339 <h2>Method Overview</h2>
340 <table class="standard-table">{methodOverview}</table>
347 <h2>Data Members</h2>
349 {memberList.*.length() > 0 ?
351 <p><em>No public members.</em></p>
356 {methodList.*.length() > 0 ?
358 <p><em>No public methods.</em></p>
363 write_file(t.name + ".html", r.toXMLString());
366 function graphType(t)
368 print("GRAPH-TYPE(%s)".format(t.name));
370 let contents = "digraph classes {\n"
371 + " node [shape=rectangle fontsize=11]\n"
372 + " %s;\n".format(t.name);
374 function graphClass(c)
376 contents += '%s [URL="http://developer.mozilla.org/en/%s"]\n'.format(c.name, c.name);
378 for each (let st in c.subtypes) {
379 contents += " %s -> %s;\n".format(c.name, st.name);
388 write_file(t.name + "-graph.gv", contents);
393 for (let p in typelist)
394 dumpType(typelist[p]);
396 for (let n in interestingList)
397 graphType(interestingList[n]);