mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-20 17:20:54 +00:00
Bug 468717 - enable static analysis for js/src, r=jorendorff
--HG-- rename : xpcom/analysis/static-checking.js => config/static-checking.js rename : xpcom/analysis/string-format.js => config/string-format.js rename : xpcom/analysis/static-checking.js => js/src/config/static-checking.js rename : xpcom/analysis/string-format.js => js/src/config/string-format.js rename : xpcom/analysis/jsstack.js => js/src/jsstack.js
This commit is contained in:
parent
23836bf5df
commit
e930891ad0
@ -1,7 +1,7 @@
|
||||
# The entire tree should be subject to static analysis using the XPCOM
|
||||
# script. Additional scripts may be added by specific subdirectories.
|
||||
|
||||
DEHYDRA_SCRIPT = $(topsrcdir)/xpcom/analysis/static-checking.js
|
||||
DEHYDRA_SCRIPT = $(topsrcdir)/config/static-checking.js
|
||||
|
||||
DEHYDRA_MODULES = \
|
||||
$(topsrcdir)/xpcom/analysis/final.js \
|
||||
@ -11,7 +11,7 @@ TREEHYDRA_MODULES = \
|
||||
$(topsrcdir)/xpcom/analysis/outparams.js \
|
||||
$(topsrcdir)/xpcom/analysis/stack.js \
|
||||
$(topsrcdir)/xpcom/analysis/flow.js \
|
||||
$(topsrcdir)/xpcom/analysis/jsstack.js \
|
||||
$(topsrcdir)/js/src/jsstack.js \
|
||||
$(NULL)
|
||||
|
||||
DEHYDRA_ARGS = \
|
||||
|
@ -13,8 +13,6 @@ function treehydra_enabled() {
|
||||
include('unstable/getopt.js');
|
||||
[options, args] = getopt();
|
||||
|
||||
// XXXbugfix: when you pass arguments to -fplugin-arg, include_path[0] is bad
|
||||
sys.include_path[0] = options.topsrcdir + "/xpcom/analysis";
|
||||
sys.include_path.push(options.topsrcdir);
|
||||
|
||||
include('string-format.js');
|
@ -1,13 +1,10 @@
|
||||
# Currently spidermonkey has no static checking infrastructure, but it will...
|
||||
# This is all dummy values now: see the Mozilla version of this file for
|
||||
# an example with real data.
|
||||
|
||||
DEHYDRA_SCRIPT = $(error No Spidermonkey static-checking.js yet!)
|
||||
DEHYDRA_SCRIPT = $(topsrcdir)/config/static-checking.js
|
||||
|
||||
DEHYDRA_MODULES = \
|
||||
$(NULL)
|
||||
|
||||
TREEHYDRA_MODULES = \
|
||||
$(topsrcdir)/jsstack.js \
|
||||
$(NULL)
|
||||
|
||||
DEHYDRA_ARGS = \
|
||||
@ -19,6 +16,6 @@ DEHYDRA_ARGS = \
|
||||
|
||||
DEHYDRA_FLAGS = -fplugin=$(DEHYDRA_PATH) -fplugin-arg='$(DEHYDRA_SCRIPT) $(DEHYDRA_ARGS)'
|
||||
|
||||
# ifdef DEHYDRA_PATH
|
||||
# OS_CXXFLAGS += $(DEHYDRA_FLAGS)
|
||||
# endif
|
||||
ifdef DEHYDRA_PATH
|
||||
OS_CXXFLAGS += $(DEHYDRA_FLAGS)
|
||||
endif
|
||||
|
92
js/src/config/static-checking.js
Normal file
92
js/src/config/static-checking.js
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* A script for GCC-dehydra to analyze the Mozilla codebase and catch
|
||||
* patterns that are incorrect, but which cannot be detected by a compiler. */
|
||||
|
||||
/**
|
||||
* Activate Treehydra outparams analysis if running in Treehydra.
|
||||
*/
|
||||
|
||||
function treehydra_enabled() {
|
||||
return this.hasOwnProperty('TREE_CODE');
|
||||
}
|
||||
|
||||
include('unstable/getopt.js');
|
||||
[options, args] = getopt();
|
||||
|
||||
sys.include_path.push(options.topsrcdir);
|
||||
|
||||
include('string-format.js');
|
||||
|
||||
let modules = [];
|
||||
|
||||
function LoadModules(modulelist)
|
||||
{
|
||||
if (modulelist == "")
|
||||
return;
|
||||
|
||||
let modulenames = modulelist.split(',');
|
||||
for each (let modulename in modulenames) {
|
||||
let module = { __proto__: this };
|
||||
include(modulename, module);
|
||||
modules.push(module);
|
||||
}
|
||||
}
|
||||
|
||||
LoadModules(options['dehydra-modules']);
|
||||
if (treehydra_enabled())
|
||||
LoadModules(options['treehydra-modules']);
|
||||
|
||||
function process_type(c)
|
||||
{
|
||||
for each (let module in modules)
|
||||
if (module.hasOwnProperty('process_type'))
|
||||
module.process_type(c);
|
||||
}
|
||||
|
||||
function hasAttribute(c, attrname)
|
||||
{
|
||||
var attr;
|
||||
|
||||
if (c.attributes === undefined)
|
||||
return false;
|
||||
|
||||
for each (attr in c.attributes)
|
||||
if (attr.name == 'user' && attr.value[0] == attrname)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
function process_function(f, stmts)
|
||||
{
|
||||
for each (let module in modules)
|
||||
if (module.hasOwnProperty('process_function'))
|
||||
module.process_function(f, stmts);
|
||||
}
|
||||
|
||||
function process_tree(fndecl)
|
||||
{
|
||||
for each (let module in modules)
|
||||
if (module.hasOwnProperty('process_tree'))
|
||||
module.process_tree(fndecl);
|
||||
}
|
||||
|
||||
function process_decl(decl)
|
||||
{
|
||||
for each (let module in modules)
|
||||
if (module.hasOwnProperty('process_var'))
|
||||
module.process_decl(decl);
|
||||
}
|
||||
|
||||
function process_cp_pre_genericize(fndecl)
|
||||
{
|
||||
for each (let module in modules)
|
||||
if (module.hasOwnProperty('process_cp_pre_genericize'))
|
||||
module.process_cp_pre_genericize(fndecl);
|
||||
}
|
||||
|
||||
function input_end()
|
||||
{
|
||||
for each (let module in modules)
|
||||
if (module.hasOwnProperty('input_end'))
|
||||
module.input_end();
|
||||
}
|
61
js/src/config/string-format.js
Normal file
61
js/src/config/string-format.js
Normal file
@ -0,0 +1,61 @@
|
||||
String.prototype.format = function string_format() {
|
||||
// there are two modes of operation... unnamed indices are read in order;
|
||||
// named indices using %(name)s. The two styles cannot be mixed.
|
||||
// Unnamed indices can be passed as either a single argument to this function,
|
||||
// multiple arguments to this function, or as a single array argument
|
||||
let curindex = 0;
|
||||
let d;
|
||||
|
||||
if (arguments.length > 1) {
|
||||
d = arguments;
|
||||
}
|
||||
else
|
||||
d = arguments[0];
|
||||
|
||||
function r(s, key, type) {
|
||||
if (type == '%')
|
||||
return '%';
|
||||
|
||||
let v;
|
||||
if (key == "") {
|
||||
if (curindex == -1)
|
||||
throw Error("Cannot mix named and positional indices in string formatting.");
|
||||
|
||||
if (curindex == 0 && (!(d instanceof Object) || !(0 in d))) {
|
||||
v = d;
|
||||
}
|
||||
else if (!(curindex in d))
|
||||
throw Error("Insufficient number of items in format, requesting item %i".format(curindex));
|
||||
else {
|
||||
v = d[curindex];
|
||||
}
|
||||
|
||||
++curindex;
|
||||
}
|
||||
else {
|
||||
key = key.slice(1, -1);
|
||||
if (curindex > 0)
|
||||
throw Error("Cannot mix named and positional indices in string formatting.");
|
||||
curindex = -1;
|
||||
|
||||
if (!(key in d))
|
||||
throw Error("Key '%s' not present during string substitution.".format(key));
|
||||
v = d[key];
|
||||
}
|
||||
switch (type) {
|
||||
case "s":
|
||||
if (v === undefined)
|
||||
return "<undefined>";
|
||||
return v.toString();
|
||||
case "r":
|
||||
return uneval(v);
|
||||
case "i":
|
||||
return parseInt(v);
|
||||
case "f":
|
||||
return Number(v);
|
||||
default:
|
||||
throw Error("Unexpected format character '%s'.".format(type));
|
||||
}
|
||||
}
|
||||
return this.replace(/%(\([^)]+\))?(.)/g, r);
|
||||
};
|
@ -12,7 +12,7 @@ include('unstable/esp.js');
|
||||
let Zero_NonZero = {};
|
||||
include('unstable/zero_nonzero.js', Zero_NonZero);
|
||||
|
||||
include('mayreturn.js');
|
||||
include('xpcom/analysis/mayreturn.js');
|
||||
|
||||
function safe_location_of(t) {
|
||||
if (t === undefined)
|
||||
|
Loading…
x
Reference in New Issue
Block a user