Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merged pull request #126 from benblank/master.

Add WSH support to JSHint
  • Loading branch information...
commit 94e186d66b842e28599cc320abb411a9f21d4cfb 2 parents 36465a5 + 051acc9
Anton Kovalyov valueof authored
Showing with 263 additions and 57 deletions.
  1. +4 −0 README.markdown
  2. +168 −0 env/wsh.js
  3. +73 −57 jshint.js
  4. +18 −0 tests/envs.js
4 README.markdown
View
@@ -49,6 +49,10 @@ If you use Rhino, we have a special wrapper script for that:
java -jar /path/to/js.jar env/rhino.js myscript.js
+Also included is a Windows Scripting Host wrapper:
+
+ cscript env/wsh.js myscript.js
+
Tests
-----
168 env/wsh.js
View
@@ -0,0 +1,168 @@
+/*jshint evil: true, shadow: true, wsh: true */
+/*global JSHINT: false */
+
+(function() {
+ function readFile(path) {
+ try {
+ return new ActiveXObject("Scripting.FileSystemObject").OpenTextFile(path, 1).ReadAll();
+ } catch (ex) {
+ return null;
+ }
+ }
+
+ var formatters = {
+ errors: function(errors, lines) {
+ for (var i = 0; i < errors.length; i++) {
+ var error = errors[i];
+
+ if (!error) continue;
+
+ if (i) lines.push("");
+
+ lines.push("Line " + error.line + " character " + error.character + ": " + error.reason);
+
+ if (error.evidence) lines.push(" " + error.evidence.replace(/^\s*((?:[\S\s]*\S)?)\s*$/, "$1"));
+ }
+ },
+
+ implieds: function(implieds, lines) {
+ lines.push("Implied globals:");
+
+ var globals = {};
+
+ for (var i = 0; i < implieds.length; i++) {
+ var item = implieds[i];
+
+ if (!(item.name in globals)) globals[item.name] = [];
+
+ globals[item.name].push(item.line);
+ }
+
+ for (var name in globals) {
+ lines.push(" " + name + ": " + globals[name].join(", "));
+ }
+ },
+
+ unused: function(unused, lines) {
+ lines.push("Unused variables:");
+
+ var func, names = {};
+
+ for (var i = 0; i < unused.length; i++) {
+ var item = unused[i];
+
+ func = item["function"];
+
+ if (!(func in names)) names[func] = [];
+
+ names[func].push(item.name + " (" + item.line + ")");
+ }
+
+ for (func in names) {
+ lines.push(" " + func + ": " + names[func].join(", "));
+ }
+ }
+ };
+
+ var scriptName = WScript.ScriptName;
+ var scriptPath = WScript.ScriptFullName;
+
+ scriptPath = scriptPath.substr(0, scriptPath.length - scriptName.length);
+
+ // load JSHint if the two scripts have not been concatenated
+ if (typeof JSHINT === "undefined") {
+ eval(readFile(scriptPath + "..\\jshint.js"));
+
+ if (typeof JSHINT === "undefined") {
+ WScript.StdOut.WriteLine("ERROR: Could not find 'jshint.js'.");
+
+ WScript.Quit(-2);
+ }
+ }
+
+ var globals = {};
+ var options = {};
+ var named = WScript.Arguments.Named;
+ var unnamed = WScript.Arguments.Unnamed;
+
+ if (unnamed.length !== 1) {
+ WScript.StdOut.WriteLine(" usage: cscript " + scriptName + " [options] <script>");
+ WScript.StdOut.WriteLine("");
+ WScript.StdOut.WriteLine("Scans the specified script with JSHint and reports any errors encountered. If");
+ WScript.StdOut.WriteLine("the script name is \"-\", it will be read from standard input instead.");
+ WScript.StdOut.WriteLine("");
+ WScript.StdOut.WriteLine("JSHint configuration options can be passed in via optional, Windows-style");
+ WScript.StdOut.WriteLine("arguments. For example:");
+ WScript.StdOut.WriteLine(" cscript " + scriptName + " /jquery:true myscript.js");
+ WScript.StdOut.WriteLine(" cscript " + scriptName + " /globals:QUnit:false,_:false,foo:true foo.js");
+
+ WScript.Quit(-1);
+ }
+
+ var script = unnamed(0);
+
+ if (script === "-") {
+ try {
+ script = WScript.StdIn.ReadAll();
+ } catch (ex) {
+ script = null;
+ }
+ } else {
+ script = readFile(script);
+ }
+
+ if (script === null) {
+ WScript.StdOut.WriteLine("ERROR: Could not read target script.");
+
+ WScript.Quit(2);
+ }
+
+ for (var etor = new Enumerator(named); !etor.atEnd(); etor.moveNext()) {
+ var option = etor.item();
+ var value = named(option);
+
+ if (option === "global") {
+ value = value.split(",");
+
+ for (var i = 0; i < value.length; i++) {
+ var name = value[i].split(":");
+
+ if (name.length === 1 || name[1] === "false") {
+ globals[name[0]] = false;
+ } else if (name[1] === "true") {
+ globals[name[0]] = true;
+ } else {
+ WScript.StdOut.WriteLine("Unrecognized value for global: " + name[0]);
+ WScript.StdOut.WriteLine("Must be \"true\", \"false\", or omitted.");
+
+ WScript.Quit(-1);
+ }
+ }
+ } else {
+ options[option] = value === "true" ? true : value === "false" ? false : value;
+ }
+ }
+
+ JSHINT(script, options, globals);
+
+ var data = JSHINT.data();
+ var lines = [];
+
+ for (var formatter in formatters) {
+ if (data[formatter]) {
+ if (lines.length) lines.push("");
+
+ formatters[formatter](data[formatter], lines);
+ }
+ }
+
+ if (lines.length) {
+ for (var i = 0; i < lines.length; i++) {
+ WScript.StdOut.WriteLine(lines[i]);
+ }
+
+ WScript.Quit(1);
+ } else {
+ WScript.Quit(0);
+ }
+}());
130 jshint.js
View
@@ -154,62 +154,61 @@
evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true
*/
-/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%",
- "(begin)", "(breakage)", "(context)", "(error)", "(global)",
- "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)",
- "(params)", "(scope)", "(statement)", "(verb)", "*", "+", "++", "-",
- "--", "\/", "<", "<=", "==", "===", ">", ">=", $, $$, $A, $F, $H, $R, $break,
- $continue, $w, Abstract, Ajax, __filename, __dirname, ActiveXObject, Array,
- ArrayBuffer, ArrayBufferView, Autocompleter, Assets, Boolean, Builder,
- Buffer, Browser, COM, CScript, Canvas, CustomAnimation, Class, Control,
- Chain, Color, Cookie, Core, DataView, Date, Debug, Draggable, Draggables,
- Droppables, Document, DomReady, DOMReady, Drag, E, Enumerator, Enumerable,
- Element, Elements, Error, Effect, EvalError, Event, Events, FadeAnimation,
- Field, Flash, Float32Array, Float64Array, Form, FormField, Frame, Function,
- Fx, Group, Hash, HotKey, HTMLElement, HtmlTable, Iframe, IframeShim, Image,
- Int16Array, Int32Array, Int8Array, Insertion, InputValidator, JSON, Keyboard,
- Locale, LN10, LN2, LOG10E, LOG2E, MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem,
- MoveAnimation, MooTools, Native, NEGATIVE_INFINITY, Number, Object,
- ObjectRange, Option, Options, OverText, PI, POSITIVE_INFINITY,
- PeriodicalExecuter, Point, Position, Prototype, RangeError, Rectangle,
- ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation, SQRT1_2,
- SQRT2, ScrollBar, Scriptaculous, Scroller, Slick, Slider, Selector, String,
- Style, SyntaxError, Sortable, Sortables, SortableObserver, Sound, Spinner,
- System, Swiff, Text, TextArea, Template, Timer, Tips, Type, TypeError,
- Toggle, Try, URI, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
- XMLHttpRequest, XPathEvaluator, XPathException, XPathExpression,
- XPathNamespace, XPathNSResolver, XPathResult, "\\", a, addEventListener,
- address, alert, apply, applicationCache, arguments, arity, asi, b, bitwise,
- block, blur, boolOptions, boss, browser, c, call, callee, caller, cases,
- charAt, charCodeAt, character, clearInterval, clearTimeout, close, closed,
- closure, comment, condition, confirm, console, constructor, content, couch,
- create, css, curly, d, data, datalist, dd, debug, decodeURI,
- decodeURIComponent, defaultStatus, defineClass, deserialize, devel,
- document, edition, else, emit, encodeURI, encodeURIComponent, entityify,
- eqeqeq, eqnull, errors, es5, escape, eval, event, evidence, evil, ex,
- exception, exec, exps, expr, exports, FileReader, first, floor, focus,
- forin, fragment, frames, from, fromCharCode, fud, funct, function, functions,
- g, gc, getComputedStyle, getRow, GLOBAL, global, globals, globalstrict,
- hasOwnProperty, help, history, i, id, identifier, immed, implieds,
- include, indent, indexOf, init, ins, instanceOf, isAlpha,
- isApplicationRunning, isArray, isDigit, isFinite, isNaN, join, jshint,
- JSHINT, json, jquery, jQuery, keys, label, labelled, last, laxbreak,
- latedef, lbp, led, left, length, line, load, loadClass, localStorage,
- location, log, loopfunc, m, match, maxerr, maxlen, member,message, meta,
- module, moveBy, moveTo, mootools, name, navigator, new, newcap, noarg,
- node, noempty, nomen, nonew, nud, onbeforeunload, onblur, onerror, onevar,
- onfocus, onload, onresize, onunload, open, openDatabase, openURL, opener,
- opera, outer, param, parent, parseFloat, parseInt, passfail, plusplus,
- predef, print, process, prompt, prototype, prototypejs, push, quit, range,
- raw, reach, reason, regexp, readFile, readUrl, removeEventListener, replace,
- report, require, reserved, resizeBy, resizeTo, resolvePath, resumeUpdates,
- respond, rhino, right, runCommand, scroll, screen, scrollBy, scrollTo,
- scrollbar, search, seal, send, serialize, setInterval, setTimeout, shift,
- slice, sort,spawn, split, stack, status, start, strict, sub, substr, supernew,
- shadow, supplant, sum, sync, test, toLowerCase, toString, toUpperCase, toint32,
- token, top, type, typeOf, Uint16Array, Uint32Array, Uint8Array, undef,
- unused, urls, value, valueOf, var, version, WebSocket, white, window, Worker
-*/
+/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)",
+ "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)",
+ "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)",
+ "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
+ "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax,
+ __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView,
+ Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas,
+ CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date,
+ Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, Drag,
+ E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
+ Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form,
+ FormField, Frame, Function, Fx, GetObject, Group, Hash, HotKey, HTMLElement,
+ HtmlTable, Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array,
+ Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E,
+ MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MoveAnimation, MooTools, Native,
+ NEGATIVE_INFINITY, Number, Object, ObjectRange, Option, Options, OverText, PI,
+ POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, RangeError,
+ Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation,
+ SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion,
+ ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller,
+ Slick, Slider, Selector, String, Style, SyntaxError, Sortable, Sortables,
+ SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template,
+ Timer, Tips, Type, TypeError, Toggle, Try, URI, URIError, URL, VBArray, WSH,
+ WScript, Web, Window, XMLDOM, XMLHttpRequest, XPathEvaluator, XPathException,
+ XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, "\\", a,
+ addEventListener, address, alert, apply, applicationCache, arguments, arity,
+ asi, b, bitwise, block, blur, boolOptions, boss, browser, c, call, callee,
+ caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout,
+ close, closed, closure, comment, condition, confirm, console, constructor,
+ content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI,
+ decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
+ edition, else, emit, encodeURI, encodeURIComponent, entityify, eqeqeq, eqnull,
+ errors, es5, escape, eval, event, evidence, evil, ex, exception, exec, exps,
+ expr, exports, FileReader, first, floor, focus, forin, fragment, frames, from,
+ fromCharCode, fud, funct, function, functions, g, gc, getComputedStyle, getRow,
+ GLOBAL, global, globals, globalstrict, hasOwnProperty, help, history, i, id,
+ identifier, immed, implieds, include, indent, indexOf, init, ins, instanceOf,
+ isAlpha, isApplicationRunning, isArray, isDigit, isFinite, isNaN, join, jshint,
+ JSHINT, json, jquery, jQuery, keys, label, labelled, last, laxbreak, latedef,
+ lbp, led, left, length, line, load, loadClass, localStorage, location, log,
+ loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy,
+ moveTo, mootools, name, navigator, new, newcap, noarg, node, noempty, nomen,
+ nonew, nud, onbeforeunload, onblur, onerror, onevar, onfocus, onload, onresize,
+ onunload, open, openDatabase, openURL, opener, opera, outer, param, parent,
+ parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt,
+ prototype, prototypejs, push, quit, range, raw, reach, reason, regexp,
+ readFile, readUrl, removeEventListener, replace, report, require, reserved,
+ resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right,
+ runCommand, scroll, screen, scrollBy, scrollTo, scrollbar, search, seal, send,
+ serialize, setInterval, setTimeout, shift, slice, sort,spawn, split, stack,
+ status, start, strict, sub, substr, supernew, shadow, supplant, sum, sync,
+ test, toLowerCase, toString, toUpperCase, toint32, token, top, type, typeOf,
+ Uint16Array, Uint32Array, Uint8Array, undef, unused, urls, value, valueOf, var,
+ version, WebSocket, white, window, Worker,
+ wsh*/
/*global exports: false */
@@ -281,7 +280,8 @@ var JSHINT = (function () {
strict : true, // require the "use strict"; pragma
sub : true, // if all forms of subscript notation are tolerated
supernew : true, // if `new function () { ... };` and `new Object;` should be tolerated
- white : true // if strict whitespace rules apply
+ white : true, // if strict whitespace rules apply
+ wsh : true // if the Windows Scripting Host environment globals should be predefined
},
// browser contains a set of global names which are commonly provided by a
@@ -604,6 +604,19 @@ var JSHINT = (function () {
urls,
warnings,
+ wsh = {
+ ActiveXObject : true,
+ Enumerator : true,
+ GetObject : true,
+ ScriptEngine : true,
+ ScriptEngineBuildVersion : true,
+ ScriptEngineMajorVersion : true,
+ ScriptEngineMinorVersion : true,
+ VBArray : true,
+ WSH : true,
+ WScript : true
+ },
+
// Regular expressions. Some of these are stupidly long.
// unsafe comment or string
@@ -754,6 +767,9 @@ var JSHINT = (function () {
if (option.mootools)
combine(predefined, mootools);
+ if (option.wsh)
+ combine(predefined, wsh);
+
if (option.globalstrict)
option.strict = true;
}
18 tests/envs.js
View
@@ -264,6 +264,24 @@ exports.rhino = function () {
assert.globalsKnown(globals, { rhino: true });
};
+exports.wsh = function () {
+ var globals = [
+ 'ActiveXObject'
+ , 'Enumerator'
+ , 'GetObject'
+ , 'ScriptEngine'
+ , 'ScriptEngineBuildVersion'
+ , 'ScriptEngineMajorVersion'
+ , 'ScriptEngineMinorVersion'
+ , 'VBArray'
+ , 'WSH'
+ , 'WScript'
+ ];
+
+ assert.globalsImplied(globals);
+ assert.globalsKnown(globals, { wsh: true });
+};
+
exports.es5 = function () {
var src = fs.readFileSync(__dirname + "/fixtures/es5.js", "utf8");
Please sign in to comment.
Something went wrong with that request. Please try again.