Reputation: 349
I have looked at many stackoverflow answers about getting rid of (necessary) unused parameters errors from jslint by locally wrapping functions as follows:
/*jslint unparam: true*/
//my function with unused parameters
/*jslint unparam: false*/
However when I try to do this I get the following error from JSLint instead:
Unexpected '/*jslint'.
I have tried all manner of white space around it, such as:
/* jslint unparam: true */
/*jslint unparam : true */
/* jslint unparam: true*/
But if such changes have any effect at all, it is that the jslint inline directive is not seen at all, and the unused errors remain instead.
After a bit of toying around, I suspect the issue is JSLint being in some other mode during processing. The function in question is inside of a custom class declaration, similar to the following:
var myClass = CreateClass({
Constructor : function myClass()
{
//initialize
},
Parent : null,
Definition :
{
//member functions that will be copied into prototype,
// be added to custom chaining functionality, etc go here
/*jslint unparam: true*/
doSomething : function doSomething(inUnusedInterfaceParam, inUsedParam)
{
//do something with inUsedParam, but NOT inUnusedInterfaceParam
}
/*jslint unparam: false*/
}
});
And no matter how I move the directive around it doesn't work. For example I have also tried variations of:
doSomething : /*jslint unparam: true*/
function doSomething(inUnusedInterfaceParam, inUsedParam)
{
//do something with inUsedParam, but NOT inUnusedInterfaceParam
}
/*jslint unparam: false*/
This issue is just one of many that is causing me to develop a real love/hate relationship to JSLint. I will probably strip it out of my build at some point in favor of JSHint, but I have not yet wanted to devote the time to do that. In the mean time, is there a way to get jslint to shut up here? And what condition(s) cause jslint to complain about it's own inline directives, as it is currently doing?
Upvotes: 3
Views: 540
Reputation: 17473
The quick answer is that JSLint directives operate at function scope (links are to current version of jslint.js), so where you're trying to set those options isn't supposed to work.
// JSLint provides three inline directives. They look like slashstar comments,
// and allow for setting options, declaring global variables, and establishing a
// set of allowed property names.
// These directives respect function scope.
So you're busting out on line 3243. Here's the general context. The key is that (afaict quickly) we are in the context of a block starting with a {
. Here's the code from JSLint.js:
prefix('{', function (that) {
//...
while (next_token.id !== '}') {
indent.wrap = false;
edge();
if (next_token.string === 'get' && peek().id !== ':') {
//...
} else {
name = next_token;
i = property_name();
if (typeof i !== 'string') {
next_token.stop('missing_property'); // line 3243
}
advance(':');
spaces();
name.first = expression(10);
}
Since you're in the middle of processing a {
tag, it's not expecting or looking for directives, so your changes will bork.
Not realizing that at first, I initially (blindly) tried moving the /*jslint unparam: true*/
up, out of the squiggly brackets and near Definition :
, to see if that'd make it happy, but got:
Error (error): unexpected_a
/*jslint unparam: true*/
Unexpected '/*jslint'.
That's when it started dawning on me that this is not a valid time to use a directive, which JSLint's code and comments confirm.
Now I agree with you[r implicit claim] that it would be useful to be able to set directives here. And you could even potentially cheat and do that to the jslint code if you really wanted. But that's simply not how JSLint is built.
Just to be insanely evil, here's a completely hacky, Crockford is standing over my cube about to burn my keyboard and rip up my Programmers' Card, way to make jslint do what you want.
Go to line 3240. Check to see if the next_token that's stored in name
has "/*jslint"
in its string
property. If so, completely hijack the jslint parsing routine and set unparam
to true
(or, better yet, grok do_jslint()
, which sets these values. Seriously, though, I feel dirty for pasting this.
} else {
name = next_token;
//================================================
// HIJACK!!!!
//================================================
if (name.string === "/*jslint")
{
console.log && console.log("evil beginning");
advance();
// Completely cheating here. You'd need to grok do_jslint()
// (I don't yet) or at least parse the jslint line.
option.unparam = true;
// Splice out our reading the /*jslint line.
while (next_token.string !== "*/")
{
advance();
}
advance();
name = next_token;
}
//================================================
// Return control
//================================================
i = property_name();
if (typeof i !== 'string') {
// ....
Then do the same thing at 3413:
default:
//================================================
//================================================
if (next_token.string == "/*jslint")
{
console.log && console.log("evil ending");
// Same warning about super-kludging.
option.unparam = false;
while (next_token.string !== "*/")
{
advance();
}
advance();
}
else
{
next_token.stop('unexpected_a');
}
//================================================
//================================================
Here's a pasteee with those changes and a few more horrible, never to be repeated, quick debugging hacks.
I'm including all this evil mainly to show that you could parse for jslint
directives at these places, but 1.) JSLint obviously doesn't and 2.) You'd have to take a good deal of time to make that work correctly across the board, not just in this particular use case.
Upvotes: 2