Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / config / static-checking.js
bloba67cb11d4e8d5cafeba627351df4b14094a5b969
1 /**
2  * A script for GCC-dehydra to analyze the Mozilla codebase and catch
3  * patterns that are incorrect, but which cannot be detected by a compiler. */
5 /**
6  * Activate Treehydra outparams analysis if running in Treehydra.
7  */
9 function treehydra_enabled() {
10   return this.hasOwnProperty('TREE_CODE');
13 sys.include_path.push(options.topsrcdir);
15 include('string-format.js');
17 let modules = [];
19 function LoadModules(modulelist)
21   if (modulelist == "")
22     return;
24   let modulenames = modulelist.split(',');
25   for each (let modulename in modulenames) {
26     let module = { __proto__: this };
27     include(modulename, module);
28     modules.push(module);
29   }
32 LoadModules(options['dehydra-modules']);
33 if (treehydra_enabled())
34   LoadModules(options['treehydra-modules']);
36 function process_type(c)
38   for each (let module in modules)
39     if (module.hasOwnProperty('process_type'))
40       module.process_type(c);
43 function hasAttribute(c, attrname)
45   var attr;
47   if (c.attributes === undefined)
48     return false;
50   for each (attr in c.attributes)
51     if (attr.name == 'user' && attr.value[0] == attrname)
52       return true;
54   return false;
57 // This is useful for detecting method overrides
58 function signaturesMatch(m1, m2)
60   if (m1.shortName != m2.shortName)
61     return false;
63   if ((!!m1.isVirtual) != (!!m2.isVirtual))
64     return false;
65   
66   if (m1.isStatic != m2.isStatic)
67     return false;
68   
69   let p1 = m1.type.parameters;
70   let p2 = m2.type.parameters;
72   if (p1.length != p2.length)
73     return false;
74   
75   for (let i = 0; i < p1.length; ++i)
76     if (!params_match(p1[i], p2[i]))
77       return false;
79   return true;
82 function params_match(p1, p2)
84   [p1, p2] = unwrap_types(p1, p2);
86   for (let i in p1)
87     if (i == "type" && !types_match(p1.type, p2.type))
88       return false;
89     else if (i != "type" && p1[i] !== p2[i])
90       return false;
92   for (let i in p2)
93     if (!(i in p1))
94       return false;
96   return true;
99 function types_match(t1, t2)
101   if (!t1 || !t2)
102     return false;
104   [t1, t2] = unwrap_types(t1, t2);
106   return t1 === t2;
109 function unwrap_types(t1, t2)
111   while (t1.variantOf)
112     t1 = t1.variantOf;
114   while (t2.variantOf)
115     t2 = t2.variantOf;
117   return [t1, t2];
120 const forward_functions = [
121   'process_type',
122   'process_tree_type',
123   'process_decl',
124   'process_tree_decl',
125   'process_function',
126   'process_tree',
127   'process_cp_pre_genericize',
128   'input_end'
131 function setup_forwarding(n)
133   this[n] = function() {
134     for each (let module in modules) {
135       if (module.hasOwnProperty(n)) {
136         module[n].apply(this, arguments);
137       }
138     }
139   }
142 for each (let n in forward_functions)
143   setup_forwarding(n);