http://fossjon.wordpress.com/2011/05/20/checking-javascript-variables-with-python/
> I would assume something like this (see link below) could be very easily handled with Shaper, and it seems like a good candidate for an example/tutorial involving a realworld, non-toy task. I've not yet been able to get Shaper to do any real work for me (I must be thick), so such a tutorial would be useful, to me at least! So how would one replace this Python script with a nice sweet Shaper plugin?
>
> http://fossjon.wordpress.com/2011/05/20/checking-javascript-variables-with-python/
You can use Shaper for that kind of static code analysis but it's not trivial to do it properly in any language or framework. Consider for instance that if x is not declared then <var y = x + 1> is an error, <typeof x> is fine but <typeof x.y> is an error. I'm sure that helpers such as Shaper.traverseTree and Shaper.match are useful when performing the analysis. Beware that an IDENTIFIER in the AST can mean different things depending on its surrounding nodes. Inspect <Shaper.parseExpression("function blk() { var x = 1; function f(x) {}; typeof x; o.x = 3; }").printTree()> for some examples.
I don't have the time to create that plugin but I will help out by answering questions for anyone who does. I agree it would be a nice example and I'm sure it would improve Shaper by pointing out missing spots or by refactoring parts of the plugin into Shaper helpers.
/Olov
> I don't have the time to create that plugin but I will help out by answering questions for anyone who does.
I changed that to "don't have the time to document it up and write a tutorial".
Check out the scoper plugin, just pushed. It performs static analysis on a JS program to count reads and writes of variable references (resolvable and unresolvable/global) on a per scope basis.
Run it on this example (simple.js):
gx = 3;
var gy = 3;
gx += gz;
function f(fa) {
var fx, fy = 3;
try {} catch (e) { e += 1; }
function g(ga, gb) {
var notused;
return fx;
}
for (var v in o) {}
for (w in o) {}
for (var x = 0; false; false) {}
for (y = 0; false; false) {}
fa.prop = 3;
print({objpropname: 1});
return typeof ref;
}
And it'll print this:
scope variables: {"e":{"r":1,"w":1}}
scope variables: {"ga":{"r":0,"w":1},"gb":{"r":0,"w":1},"notused":{"r":0,"w":1}}
scope variables: {"fa":{"r":1,"w":1},"fx":{"r":1,"w":1},"fy":{"r":1,"w":0},"v":{"r":0,"w":1},"x":{"r":1,"w":0},"g":{"r":0,"w":1},"unresolvable variables":{"o":{"r":2,"w":0},"w":{"r":0,"w":1},"y":{"r":1,"w":0},"print":{"r":1,"w":0}}}
scope variables: {"gy":{"r":1,"w":0},"f":{"r":0,"w":1},"unresolvable variables":{"gx":{"r":2,"w":0},"gz":{"r":1,"w":0}}}
/Olov