config/static-checking.js

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:f26cbbe72700
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 * A script for GCC-dehydra to analyze the Mozilla codebase and catch
7 * patterns that are incorrect, but which cannot be detected by a compiler. */
8
9 /**
10 * Activate Treehydra outparams analysis if running in Treehydra.
11 */
12
13 function treehydra_enabled() {
14 return this.hasOwnProperty('TREE_CODE');
15 }
16
17 sys.include_path.push(options.topsrcdir);
18
19 include('string-format.js');
20
21 let modules = [];
22
23 function LoadModules(modulelist)
24 {
25 if (modulelist == "")
26 return;
27
28 let modulenames = modulelist.split(',');
29 for each (let modulename in modulenames) {
30 let module = { __proto__: this };
31 include(modulename, module);
32 modules.push(module);
33 }
34 }
35
36 LoadModules(options['dehydra-modules']);
37 if (treehydra_enabled())
38 LoadModules(options['treehydra-modules']);
39
40 function process_type(c)
41 {
42 for each (let module in modules)
43 if (module.hasOwnProperty('process_type'))
44 module.process_type(c);
45 }
46
47 function hasAttribute(c, attrname)
48 {
49 var attr;
50
51 if (c.attributes === undefined)
52 return false;
53
54 for each (attr in c.attributes)
55 if (attr.name == 'user' && attr.value[0] == attrname)
56 return true;
57
58 return false;
59 }
60
61 // This is useful for detecting method overrides
62 function signaturesMatch(m1, m2)
63 {
64 if (m1.shortName != m2.shortName)
65 return false;
66
67 if ((!!m1.isVirtual) != (!!m2.isVirtual))
68 return false;
69
70 if (m1.isStatic != m2.isStatic)
71 return false;
72
73 let p1 = m1.type.parameters;
74 let p2 = m2.type.parameters;
75
76 if (p1.length != p2.length)
77 return false;
78
79 for (let i = 0; i < p1.length; ++i)
80 if (!params_match(p1[i], p2[i]))
81 return false;
82
83 return true;
84 }
85
86 function params_match(p1, p2)
87 {
88 [p1, p2] = unwrap_types(p1, p2);
89
90 for (let i in p1)
91 if (i == "type" && !types_match(p1.type, p2.type))
92 return false;
93 else if (i != "type" && p1[i] !== p2[i])
94 return false;
95
96 for (let i in p2)
97 if (!(i in p1))
98 return false;
99
100 return true;
101 }
102
103 function types_match(t1, t2)
104 {
105 if (!t1 || !t2)
106 return false;
107
108 [t1, t2] = unwrap_types(t1, t2);
109
110 return t1 === t2;
111 }
112
113 function unwrap_types(t1, t2)
114 {
115 while (t1.variantOf)
116 t1 = t1.variantOf;
117
118 while (t2.variantOf)
119 t2 = t2.variantOf;
120
121 return [t1, t2];
122 }
123
124 const forward_functions = [
125 'process_type',
126 'process_tree_type',
127 'process_decl',
128 'process_tree_decl',
129 'process_function',
130 'process_tree',
131 'process_cp_pre_genericize',
132 'input_end'
133 ];
134
135 function setup_forwarding(n)
136 {
137 this[n] = function() {
138 for each (let module in modules) {
139 if (module.hasOwnProperty(n)) {
140 module[n].apply(this, arguments);
141 }
142 }
143 }
144 }
145
146 for each (let n in forward_functions)
147 setup_forwarding(n);

mercurial