1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/config/static-checking.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,147 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/** 1.9 + * A script for GCC-dehydra to analyze the Mozilla codebase and catch 1.10 + * patterns that are incorrect, but which cannot be detected by a compiler. */ 1.11 + 1.12 +/** 1.13 + * Activate Treehydra outparams analysis if running in Treehydra. 1.14 + */ 1.15 + 1.16 +function treehydra_enabled() { 1.17 + return this.hasOwnProperty('TREE_CODE'); 1.18 +} 1.19 + 1.20 +sys.include_path.push(options.topsrcdir); 1.21 + 1.22 +include('string-format.js'); 1.23 + 1.24 +let modules = []; 1.25 + 1.26 +function LoadModules(modulelist) 1.27 +{ 1.28 + if (modulelist == "") 1.29 + return; 1.30 + 1.31 + let modulenames = modulelist.split(','); 1.32 + for each (let modulename in modulenames) { 1.33 + let module = { __proto__: this }; 1.34 + include(modulename, module); 1.35 + modules.push(module); 1.36 + } 1.37 +} 1.38 + 1.39 +LoadModules(options['dehydra-modules']); 1.40 +if (treehydra_enabled()) 1.41 + LoadModules(options['treehydra-modules']); 1.42 + 1.43 +function process_type(c) 1.44 +{ 1.45 + for each (let module in modules) 1.46 + if (module.hasOwnProperty('process_type')) 1.47 + module.process_type(c); 1.48 +} 1.49 + 1.50 +function hasAttribute(c, attrname) 1.51 +{ 1.52 + var attr; 1.53 + 1.54 + if (c.attributes === undefined) 1.55 + return false; 1.56 + 1.57 + for each (attr in c.attributes) 1.58 + if (attr.name == 'user' && attr.value[0] == attrname) 1.59 + return true; 1.60 + 1.61 + return false; 1.62 +} 1.63 + 1.64 +// This is useful for detecting method overrides 1.65 +function signaturesMatch(m1, m2) 1.66 +{ 1.67 + if (m1.shortName != m2.shortName) 1.68 + return false; 1.69 + 1.70 + if ((!!m1.isVirtual) != (!!m2.isVirtual)) 1.71 + return false; 1.72 + 1.73 + if (m1.isStatic != m2.isStatic) 1.74 + return false; 1.75 + 1.76 + let p1 = m1.type.parameters; 1.77 + let p2 = m2.type.parameters; 1.78 + 1.79 + if (p1.length != p2.length) 1.80 + return false; 1.81 + 1.82 + for (let i = 0; i < p1.length; ++i) 1.83 + if (!params_match(p1[i], p2[i])) 1.84 + return false; 1.85 + 1.86 + return true; 1.87 +} 1.88 + 1.89 +function params_match(p1, p2) 1.90 +{ 1.91 + [p1, p2] = unwrap_types(p1, p2); 1.92 + 1.93 + for (let i in p1) 1.94 + if (i == "type" && !types_match(p1.type, p2.type)) 1.95 + return false; 1.96 + else if (i != "type" && p1[i] !== p2[i]) 1.97 + return false; 1.98 + 1.99 + for (let i in p2) 1.100 + if (!(i in p1)) 1.101 + return false; 1.102 + 1.103 + return true; 1.104 +} 1.105 + 1.106 +function types_match(t1, t2) 1.107 +{ 1.108 + if (!t1 || !t2) 1.109 + return false; 1.110 + 1.111 + [t1, t2] = unwrap_types(t1, t2); 1.112 + 1.113 + return t1 === t2; 1.114 +} 1.115 + 1.116 +function unwrap_types(t1, t2) 1.117 +{ 1.118 + while (t1.variantOf) 1.119 + t1 = t1.variantOf; 1.120 + 1.121 + while (t2.variantOf) 1.122 + t2 = t2.variantOf; 1.123 + 1.124 + return [t1, t2]; 1.125 +} 1.126 + 1.127 +const forward_functions = [ 1.128 + 'process_type', 1.129 + 'process_tree_type', 1.130 + 'process_decl', 1.131 + 'process_tree_decl', 1.132 + 'process_function', 1.133 + 'process_tree', 1.134 + 'process_cp_pre_genericize', 1.135 + 'input_end' 1.136 +]; 1.137 + 1.138 +function setup_forwarding(n) 1.139 +{ 1.140 + this[n] = function() { 1.141 + for each (let module in modules) { 1.142 + if (module.hasOwnProperty(n)) { 1.143 + module[n].apply(this, arguments); 1.144 + } 1.145 + } 1.146 + } 1.147 +} 1.148 + 1.149 +for each (let n in forward_functions) 1.150 + setup_forwarding(n);