Skip to content
Permalink
Browse files

Update: 'implied strict mode' ecmaFeature (fixes #4832)

  • Loading branch information...
nre committed Jan 12, 2016
1 parent 97ac91c commit 0a599261bf720bf29ec80e5b9fad22c7f08cabfa
@@ -35,7 +35,7 @@ There are four options for this rule:
1. `"function"` - require `"use strict"` in function scopes only
1. `"safe"` - require `"use strict"` globally when inside a module wrapper and in function scopes everywhere else.

All strict mode directives are flagged as unnecessary if ECMAScript modules are enabled (see [Specifying Parser Options](../user-guide/configuring#specifying-parser-options)). This behaviour does not depend on the rule options, but can be silenced by disabling this rule.
All strict mode directives are flagged as unnecessary if ECMAScript modules or implied strict mode are enabled (see [Specifying Parser Options](../user-guide/configuring#specifying-parser-options)). This behaviour does not depend on the rule options, but can be silenced by disabling this rule.

### "never"

@@ -23,6 +23,7 @@ Parser options are set in your `.eslintrc.*` file by using the `parserOptions` p
* `sourceType` - set to `"script"` (default) or `"module"` if your code is in ECMAScript modules.
* `ecmaFeatures` - an object indicating which additional language features you'd like to use:
* `globalReturn` - allow `return` statements in the global scope
* `impliedStrict` - enable global [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) (if `ecmaVersion` is 5 or greater)
* `jsx` - enable [JSX](http://facebook.github.io/jsx/)
* `experimentalObjectRestSpread` - enable support for the experimental [object rest/spread properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (**IMPORTANT:** This is an experimental feature that may change significantly in the future. It's recommended that you do *not* write rules relying on this functionality unless you are willing to incur maintenance cost when it changes.)

@@ -777,6 +777,7 @@ module.exports = (function() {
scopeManager = escope.analyze(ast, {
ignoreEval: true,
nodejsScope: ecmaFeatures.globalReturn,
impliedStrict: ecmaFeatures.impliedStrict,
ecmaVersion: ecmaVersion,
sourceType: currentConfig.parserOptions.sourceType || "script"
});
@@ -25,6 +25,7 @@ var messages = {
never: "Strict mode is not permitted.",
unnecessary: "Unnecessary 'use strict' directive.",
module: "'use strict' is unnecessary inside of modules.",
implied: "'use strict' is unnecessary when implied strict mode is enabled.",
unnecessaryInClasses: "'use strict' is unnecessary inside of classes."
};

@@ -62,14 +63,15 @@ function getUseStrictDirectives(statements) {
module.exports = function(context) {

var mode = context.options[0] || "safe",
ecmaFeatures = context.parserOptions.ecmaFeatures || {},
scopes = [],
classScopes = [],
rule;

if (mode === "safe") {
mode = context.parserOptions.ecmaFeatures &&
context.parserOptions.ecmaFeatures.globalReturn ?
"global" : "function";
if (ecmaFeatures.impliedStrict) {
mode = "implied";
} else if (mode === "safe") {
mode = ecmaFeatures.globalReturn ? "global" : "function";
}

/**
@@ -41,7 +41,7 @@
"doctrine": "^1.1.0",
"es6-map": "^0.1.3",
"escape-string-regexp": "^1.0.2",
"escope": "^3.3.0",
"escope": "^3.4.0",
"espree": "^3.0.0",
"estraverse": "^4.1.1",
"estraverse-fb": "^1.3.1",
@@ -2736,6 +2736,40 @@ describe("eslint", function() {
assert.equal(messages[0].message, "Parsing error: 'return' outside of function");
});

it("should properly parse sloppy-mode code when impliedStrict is false", function() {

var messages = eslint.verify("var private;", {}, filename);

assert.equal(messages.length, 0);
});

it("should not parse sloppy-mode code when impliedStrict is true", function() {

var messages = eslint.verify("var private;", {
parserOptions: {
ecmaFeatures: {
impliedStrict: true
}
}
}, filename);

assert.equal(messages.length, 1);
assert.equal(messages[0].message, "Parsing error: The keyword 'private' is reserved");
});

it("should properly parse valid code when impliedStrict is true", function() {

var messages = eslint.verify("var foo;", {
parserOptions: {
ecmaFeatures: {
impliedStrict: true
}
}
}, filename);

assert.equal(messages.length, 0);
});

it("should properly parse JSX when passed ecmaFeatures", function() {

var messages = eslint.verify("var x = <div/>;", {
@@ -40,6 +40,7 @@ ruleTester.run("no-eval", rule, {
"this.noeval('foo');",
"function foo() { 'use strict'; this.eval('foo'); }",
{ code: "function foo() { this.eval('foo'); }", parserOptions: { sourceType: "module" } },
{ code: "function foo() { this.eval('foo'); }", parserOptions: { ecmaFeatures: { impliedStrict: true } } },
"var obj = {foo: function() { this.eval('foo'); }}",
"var obj = {}; obj.foo = function() { this.eval('foo'); }",
{ code: "class A { foo() { this.eval(); } }", parserOptions: { ecmaVersion: 6 } },
Oops, something went wrong.

0 comments on commit 0a59926

Please sign in to comment.
You can’t perform that action at this time.