|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /** |
|
6 * graph-frameclasses.js: a dehydra script to collect information about |
|
7 * the class hierarchy of frame types. |
|
8 */ |
|
9 |
|
10 function inheritsFrom(t, baseName) |
|
11 { |
|
12 let name = t.name; |
|
13 if (name == baseName) |
|
14 return true; |
|
15 |
|
16 for each (let base in t.bases) |
|
17 if (inheritsFrom(base.type, baseName)) |
|
18 return true; |
|
19 |
|
20 return false; |
|
21 } |
|
22 |
|
23 let output = []; |
|
24 |
|
25 function process_type(t) |
|
26 { |
|
27 if ((t.kind == "class" || t.kind == "struct")) { |
|
28 if (!t.isIncomplete && inheritsFrom(t, 'nsIFrame')) { |
|
29 if (inheritsFrom(t, 'nsISupports')) |
|
30 warning("nsIFrame derivative %s inherits from nsISupports but is not refcounted.".format(t.name), t.loc); |
|
31 |
|
32 let nonFrameBases = []; |
|
33 |
|
34 output.push('CLASS-DEF: %s'.format(t.name)); |
|
35 |
|
36 for each (let base in t.bases) { |
|
37 if (inheritsFrom(base.type, 'nsIFrame')) { |
|
38 output.push('%s -> %s;'.format(base.type.name, t.name)); |
|
39 } |
|
40 else if (base.type.name != 'nsQueryFrame') { |
|
41 nonFrameBases.push(base.type.name); |
|
42 } |
|
43 } |
|
44 |
|
45 output.push('%s [label="%s%s"];'.format(t.name, t.name, |
|
46 ["\\n(%s)".format(b) for each (b in nonFrameBases)].join(''))); |
|
47 } |
|
48 } |
|
49 } |
|
50 |
|
51 let frameIIDRE = /::kFrameIID$/; |
|
52 let queryFrameRE = /^do_QueryFrame::operator/; |
|
53 |
|
54 /* A list of class names T that have do_QueryFrame<T> used */ |
|
55 let needIDs = []; |
|
56 |
|
57 /* A map of class names that have a kFrameIID declared */ |
|
58 let haveIDs = {}; |
|
59 |
|
60 // We match up needIDs with haveIDs at the end because static variables are |
|
61 // not present in the .members array of a type |
|
62 |
|
63 function process_tree_decl(d) |
|
64 { |
|
65 d = dehydra_convert(d); |
|
66 |
|
67 if (d.name && frameIIDRE.exec(d.name)) { |
|
68 haveIDs[d.memberOf.name] = 1; |
|
69 } |
|
70 } |
|
71 |
|
72 function process_cp_pre_genericize(d) |
|
73 { |
|
74 d = dehydra_convert(d); |
|
75 if (queryFrameRE.exec(d.name) && d.template === undefined) { |
|
76 let templtype = d.type.type.type; |
|
77 while (templtype.typedef !== undefined) |
|
78 templtype = templtype.typedef; |
|
79 |
|
80 needIDs.push([templtype.name, d.loc]); |
|
81 } |
|
82 } |
|
83 |
|
84 function input_end() |
|
85 { |
|
86 for each (let [name, loc] in needIDs) { |
|
87 if (!haveIDs.hasOwnProperty(name)) { |
|
88 error("nsQueryFrame<%s> found, but %s::kFrameIID is not declared".format(name, name), loc); |
|
89 } |
|
90 } |
|
91 |
|
92 if (output.length > 0) { |
|
93 write_file(sys.aux_base_name + '.framedata', output.join('\n')); |
|
94 } |
|
95 } |