Antranig Basman antranig.basman at colorado.edu
Tue Mar 8 17:04:53 UTC 2011

I have placed a revised version of the implementation of the JSLint tool that we have inherited from Douglas 
Crockford up at http://ponder.org.uk/fluid/fulljslint.html - the source code is also available for 
inspection in my github area.
Since we have established that no economies of development are possible by sharing even the most 
conservative fixes upstream, I've taken the opportunity to overhaul the implementation thoroughly, and have 
fixed several bugs relating to outright misparses as well as misinterpretation of wrapping constructs, as 
will as implementing some new options and configuration to make it easier for our project to use. I am 
surfacing a list of what some of these are (in cases where there might be different opinions) so that we can 
decide now we have a free hand what kinds of code we want to tolerate. Please also speak up if you have any 
suggestions for completely new features of JSLint that are not in this set, since our implementation is now 
our own and it has been found fairly straightforward to implement new features.

Firstly, the reason for the original fork in the first place, an option to tolerate the for (var x in ...) 
construction which recent versions of JSLint threw out as an unconditional parse error, aborting further 
processing. (forvar)

Secondly, an option to tolerate two variants for block indentation of "run-on" control structures, being 
if...else and try..catch..finally - original JSLint would ONLY tolerate the following variant
if (cond) {
     material 1;
} else if {
     material 2;
whereas we may now tolerate BOTH the above variant and ALSO the following (I believe more commonly seen) 
form (elsecatch)
if (cond) {
     material 1;
else if {
     material 2;

Thirdly, an option to tolerate zero or one spaces in a few cases around operators - the vast majority remain 
at the original defaults of requiring exactly 1 space for binary operators (&&, ===, etc.) and zero spaces 
for unary operators (++, --) but at least in my opinion, our rules for spaces following the "function" 
keyword have been annoyingly inconsistent, with exactly zero spaces tolerated in one case and exactly one 
space tolerated in another. With the option (operator), either zero or one space are tolerated - for 
example, both
var x = function (x) {....
var x = function(x) {...
are acceptable.

The indentation rules in general are unchanged in this implementation, apart from a few bug fixes in cases 
of multiple constructs per line which would sometimes lead to original JSLint to recommend NO indentation on 
the next, multiply nested line which was clearly a bug (constructions like
var y = fluid.transform(list, function(value, key) {
     ... would often require faulty indenting HERE. )

Fourthly, there is a new "emergency escape" rule in the form of a specially formatted comment accepted on a 
line (this is a common option with the implementations of linting tools in the C world from which JSLint 
takes heritage) - of the form // jslint:ok - this allows a one-off override of the linting rules for a 
particular line of code that has been determined through specific inspection to be safe. Clearly this rule 
must be used very sparingly since most linting violations (especially in the new implementation) are 
genuine. It was used a few times in the renderer code, particularly to allow exceptions for the "var x is 
already defined" warning caused by JavaScript's anomalous scoping rules, and for the "do not declare 
functions in a loop" rule which is a blanket recommendation which JSLint makes without any inspection of the 
flow involved. In particular, functions which do not bind to the loop counter variable for the loop they are 
nested in should be excepted from this rule. Lots of the renderer code is quite intricate and allowing a 
handful of violations (in my opinion) allowed the code to remain more readable by not having to arbitrarily 
rename some variables which clearly served the same function, or reduce locality by breaking small anonymous 
functions out of loops.

Please chime in with your opinions on what you think we should do about these various options and 
constructions :)


More information about the fluid-work mailing list