function checkVariable(e,r,t){for(;e;){if(e.cur.hasOwnProperty(r))return;e=e.prev}fail("Accidental global: "+r,t)}function checkProperty(e,r){reserved.hasOwnProperty(e)&&fail("Using a keyword or reserved word as a property: "+e,r)}function walk(e,r){function t(e){e&&walk(e,r)}function c(e){e&&e.forEach(t)}var i=e[0];if("string"!=typeof i&&(i=i.name),"block"==i||"splice"==i||"toplevel"==i||"array"==i)c(e[1]);else if("var"==i||"const"==i)e[1].forEach(function(e){r.cur[e[0]]=!0,e[1]&&t(e[1])});else if("try"==i)c(e[1]),e[2]&&(r.cur[e[2][0]]=!0,c(e[2][1])),c(e[3]);else if("throw"==i||"return"==i||"dot"==i||"stat"==i)t(e[1]);else if("dot"==i)t(e[1]),checkProperty(e[2],e[0]);else if("new"==i||"call"==i)t(e[1]),c(e[2]);else if("switch"==i)t(e[1]),e[2].forEach(function(e){t(e[0]),c(e[1])});else if("conditional"==i||"if"==i||"for"==i||"for-in"==i)t(e[1]),t(e[2]),t(e[3]),t(e[4]);else if("assign"==i)"name"==e[2][0].name&&checkVariable(r,e[2][1],e[2][0]),t(e[2]),t(e[3]);else if("function"==i||"defun"==i){"defun"==i&&(r.cur[e[1]]=!0);var a={prev:r,cur:{}};e[2].forEach(function(e){a.cur[e]=!0}),e[3].forEach(function(e){walk(e,a)})}else"while"==i||"do"==i||"sub"==i||"with"==i?(t(e[1]),t(e[2])):"binary"==i||"unary-prefix"==i||"unary-postfix"==i||"label"==i?(/\+\+|--/.test(e[1])&&"name"==e[2][0].name&&checkVariable(r,e[2][1],e[2][0]),t(e[2]),t(e[3])):"object"==i?e[1].forEach(function(r){"string"!=r.type&&checkProperty(r[0],e[0]),t(r[1]),t(r[2])}):"seq"==i?c(e.slice(1)):"name"==i&&reserved.hasOwnProperty(e[1])&&!/^(?:null|true|false)$/.test(e[1])&&fail("Using reserved word as variable name: "+e[1],e[0])}function fail(e,r){"object"==typeof r&&(r=r.start.line+1),console.log(curFile+": "+e+("number"==typeof r?" ("+r+")":"")),failed=!0}function checkFile(e){curFile=e.match(/[^\/+]*\.js$/)[0];var r=fs.readFileSync(e,"utf8"),t=r.match(/[\x00-\x08\x0b\x0c\x0e-\x19\uFEFF]/);t&&fail("Undesirable character "+t[0].charCodeAt(0)+" at position "+t.index),/^#!/.test(r)&&(r=r.slice(r.indexOf("\n")+1));try{var c=parse_js(r,!0,!0)}catch(i){return fail(i.message,i.line),void 0}walk(c,{prev:null,cur:{}})}function checkDir(e){fs.readdirSync(e).forEach(function(r){var t=e+"/"+r;/\.js$/.test(r)?checkFile(t):fs.lstatSync(t).isDirectory()&&checkDir(t)})}var fs=require("fs"),parse_js=require("./parse-js").parse,reserved={};"break case catch continue debugger default delete do else false finally for function if in instanceof new null return switch throw true try typeof var void while with abstract enum int short boolean export interface static byte extends long super char final native synchonized class float package throws const goto private transient implements protected volatile double import public const".split(" ").forEach(function(e){reserved[e]=!0});var failed=!1,curFile;exports.checkDir=checkDir,exports.checkFile=checkFile,exports.success=function(){return!failed};