JavaScript Lint on SmartOS


Photo by Sam Fraser-Smith

Back at Fishworks, we used a tool called JavaScript Lint (JSL) for static code analysis. You may know that lint was originally written to identify potential semantic problems in C code, like use of uninitialized variables or blocks of unreachable code. Lint warnings are usually static checks that could reasonably have been compiler warnings, but for whatever reasons those checks didn’t make it into the compiler.

JSL helps us catch similar errors in JavaScript: undeclared variables, variables hiding other variables in the same scope, etc. There exist several JavaScript linters out there, including Crockford’s JSLint and Google’s Closure Linter. But there are two relatively unique properties about JSL:

  • It does not conflate style with lint. Style refers to arbitrary code formatting rules (like leading whitespace rules). Lint refers to actual program correctness issues (like missing “break” statements inside a switch). The line is certainly fuzzy, as in the case of JavaScript semicolon style, but that’s why:
  • It’s highly configurable. Each individual warning can be turned on or off, and warnings can be overridden for individual lines of code. This is essential for cases where potentially dangerous behavior is being deliberately used (carefully, of course).

We’ve been using JSL on Cloud Analytics since day 1, but until recently we were using a hacked-up build I created back in November just to make forward progress. As we started using it more, it became clear that we needed to be able to build JSL reliably, which was not trivial on SmartOS because the old version of SpiderMonkey that JSL bundles doesn’t build on Solaris 10 or later out of the box. I worked out how to build it (see below), but in doing so I decided it wasn’t worth maintaining the complexity of the existing build system.  JSL hasn’t been changed much in the last many months, so I created a github fork of JSL where I removed everything that clearly wasn’t necessary for JSL and replaced the whole build system with a couple of Makefiles. The result is much less portable, but it builds on SmartOS and I expect it can be made to build on MacOS (note: see update below) and Linux with few modifications. If you want to build the existing JavaScript Lint subversion tree on Illumos, here’s what you have to do:

  • Since Sun Studio is no longer available, you’ll want to build with gcc.
  • Remove the file spidermonkey/src/lock_SunOS.s.  According to the comments, this file is only needed with Sun Studio, and it won’t build with the GNU assembler.  If you don’t remove the file, it will be picked up by a Makefile wildcard (not the line in Makefile.ref that appears to refer to it!).
  • Copy the file below into spidermonkey/src/config/SunOS5.11_i86pc.mk.
  • In the root, run “python setup.py build”.
  • This should work except for the very last step in the build.  The build system runs something like this:
    gcc -shared build/temp.solaris-2.11-i86pc-2.4/javascriptlint/pyspidermonkey/pyspidermonkey.o build/temp.solaris-2.11-i86pc-2.4/javascriptlint/pyspidermonkey/nodepos.o -Lbuild/spidermonkey -ljs -o build/lib.solaris-2.11-i86pc-2.4/javascriptlint/pyspidermonkey.so

    On my system, this produces hundreds of linker errors because gcc is trying to use the GNU linker instead of the OS linker. If you replace the “gcc” in that line with “ld” and run it by hand, it should work.

Here’s the contents of SunOS5.11_i86pc.mk:

#
# Config stuff for SunOS5.11
#

AS = as
CC = gcc
CCC = g++
CFLAGS +=  -Wall -Wno-format
RANLIB = echo
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -DSOLARIS -DHAVE_LOCALTIME_R
OS_LIBS = -lsocket -lnsl -ldl
HAVE_PURIFY = 1
MKSHLIB = $(LD) -G
# Use the editline library to provide line-editing support.
JS_EDITLINE = 1

Of course, these instructions are very specific to the build environment, so YMMV. It took me a while to figure out the right settings in SunOS5.11_i86pc.mk, so I wanted to make that available in case anyone else is trying to build JSL on SmartOS, Illumos or other Solaris-based systems.  That said, if you don’t care about remaining close to the original source, you may as well just use my fork on github. Even if it doesn’t build out of the box in your environment, the Makefiles should be far easier to understand and modify.

Update: The github fork now builds on MacOSX, too, though you need to install Python first because the one shipped with OSX doesn’t include headers.

4 thoughts on “JavaScript Lint on SmartOS

  1. >[JSL] does not conflate style with lint.

    So, you disagree with the conventions which JSLint enforces. Alright, nothing wrong with that.

    However, you do need a replacement for those things you’ve discarded. Those things are:

    a) A written style guide which explains every rule and the reason(s) behind it.

    b) Some kind of tool for automated conformance checks.

    If you can’t just borrow those things, it will require quite a lot of time (=money). Is it really worth the trouble? Are those conventions you prefer objectively better? Do they really prevent more mistakes? Do they improve productivity somehow?

    Personally, I’m fine with Crockford’s code conventions. They are kinda generic. Most people are familiar with that kind of style (from writing Java code or whatever) which makes the transition very straightforward. That’s a big plus in my book.

  2. Jos,

    Those are all good points. For mostly historical reasons, we’re using a form of cstyle (Solaris kernel C style) adapted to JavaScript. The document describing cstyle is here:

    http://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf

    and it required only minimal modifications to the “cstyle” style checking tool:

    https://github.com/davepacheco/jsstyle

    So we essentially leveraged the document and tool that already existed. If I were to start from scratch with a new code base, I would strongly consider Crockford’s or Google’s for the reasons you suggested, but I stand by the point that tools shouldn’t conflate style with lint. I wanted to run Google’s linter on our code base to see if it caught anything our lint didn’t, but basically couldn’t because of the all the style noise. Even if the Google linter found 10x more errors, having to restyle the entire code base to use it would make it a non-starter. Similarly, if someone created a new, better lint tool, one shouldn’t have to restyle the whole code base to use it.

  3. When I look at the news page for that linter I see that the oldest item dates from 2007. A lot has changed these days. When I look at the feature list for that linter, I cry a little. It says it doesn’t look at style, but it does warn you for leading or trailing dots in numbers?

    Either way, I would suggest you look at jshint, which is a branch of the original jslint (the Crockford one, anyways) but which has been extended and is completely optional. I don’t know about SmartOS integration though.

  4. Peter,

    I’ve looked at jshint before. I love that it’s completely configurable. But if it only catches the problems documented on jshint.com, it’s nowhere near as comprehensive as jsl. Examples: “switch” statement fall-through (and several other “switch” issues), unused variables and arguments (even when they’re assigned to but never again used), functions being inconsistent about whether they return values or not, and my favorite: trailing commas in arrays (which are legal, but break old browsers in ways that are very difficult to debug). The whole list is here:

    https://github.com/davepacheco/javascriptlint/blob/master/javascriptlint/warnings.py#L47

    It’s true that JSL hasn’t changed much in a few years, but it still appears way ahead of other tools in terms of the checks it can perform. The only more recent feature I see in jshint is requiring strict mode, which it seems would be a pretty easy addition to any tool (since it’s just checking whether “use strict” is present).

    In the abstract I’d prefer a tool with more active development work behind it (and also, for that matter, was written entirely in JS), but I’ve yet to find a tool nearly as comprehensive and configurable as JSL, so I stick with it.

Comments are closed.