Skip to content

Commit

Permalink
[[FIX]] Do not enable newcap within strict mode
Browse files Browse the repository at this point in the history
Since the first public release of JSLint (ca120a7), this codebase has
automatically enabled the `newcap` option for all strict mode code:

    function use_strict() {
        if (nexttoken.value === 'use strict') {
            advance();
            advance(';');
            strict_mode = true;
            option.newcap = true;
            option.undef = true;
            return true;
        } else {
            return false;
        }
    }

Commit 8de8247 unified the way JSHint detects and enforces strict mode
across contexts. Among other modifications, it included the following
change:

    - if (state.tokens.curr.value === "use strict") {
    + if (state.isStrict()) {
        if (!state.option["(explicitNewcap)"]) {
          state.option.newcap = true;
        }
        state.option.undef = true;
      }

This change introduced a regression: it enables the `newcap` option for
class bodies and ES2015 module code as well.

Because ES5's strict mode and the warnings enabled by the `newcap`
option are orthogonal (and because as a stylistic concern, the `newcap`
is deprecated) correct the regression by relaxing the behavior for all
cases--do not automatically enable `newcap` when entering strict mode,
for whatever reason.

This change is backward-compatible because it will not cause JSHint to
produce new warnings. It corrects undocumented and surprising behavior,
so it should be considered a bug fix (despite the age of the bug in
question).
  • Loading branch information
jugglinmike committed Nov 5, 2015
1 parent 0d87919 commit acaf3f7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
9 changes: 0 additions & 9 deletions src/jshint.js
Original file line number Diff line number Diff line change
Expand Up @@ -738,9 +738,6 @@ var JSHINT = (function() {
state.option[key] = (val === "true");
}

if (key === "newcap") {
state.option["(explicitNewcap)"] = true;
}
return;
}

Expand Down Expand Up @@ -1776,9 +1773,6 @@ var JSHINT = (function() {
}

if (state.isStrict()) {
if (!state.option["(explicitNewcap)"]) {
state.option.newcap = true;
}
state.option.undef = true;
}
}
Expand Down Expand Up @@ -5180,9 +5174,6 @@ var JSHINT = (function() {
(optionKey === "es5" && o[optionKey])) {
warning("I003");
}

if (optionKeys[x] === "newcap" && o[optionKey] === false)
newOptionObj["(explicitNewcap)"] = true;
}
}
}
Expand Down
15 changes: 14 additions & 1 deletion tests/unit/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -1618,7 +1618,6 @@ exports.strict = function (test) {
run.test(src2, { es3: true, strict: false });

TestRun(test)
.addError(6, "Missing 'new' prefix when invoking a constructor.")
.test(src3, {es3 : true});

TestRun(test).test(code2, { es3: true, strict: true });
Expand Down Expand Up @@ -3211,6 +3210,20 @@ exports.module.declarationRestrictions = function( test ) {
test.done();
};

exports.module.newcap = function(test) {
var code = [
"var ctor = function() {};",
"var Ctor = function() {};",
"var c1 = new ctor();",
"var c2 = Ctor();"
];

TestRun(test, "The `newcap` option is not automatically enabled for module code.")
.test(code, { esversion: 6, module: true });

test.done();
};

exports.esversion = function(test) {
var code = [
"// jshint esversion: 3",
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5939,6 +5939,24 @@ exports["class method this"] = function (test) {
test.done();
};

exports.classNewcap = function (test) {
var code = [
"class C {",
" m() {",
" var ctor = function() {};",
" var Ctor = function() {};",
" var c1 = new ctor();",
" var c2 = Ctor();",
" }",
"}"
];

TestRun(test, "The `newcap` option is not automatically enabled within class bodies.")
.test(code, { esversion: 6 });

test.done();
};

exports.classExpression = function (test) {
var code = [
"void class MyClass {",
Expand Down

0 comments on commit acaf3f7

Please sign in to comment.