Skip to content
Permalink
Browse files

Breaking: Change `strict` default mode to "safe" (fixes #4961)

  • Loading branch information...
alberto committed Jan 18, 2016
1 parent 4bfa496 commit 3e6a24e65a5105584cd0c1b648d2f4972bd99cca
Showing with 30 additions and 15 deletions.
  1. +3 −3 docs/rules/strict.md
  2. +4 −0 docs/user-guide/migrating-to-2.0.0.md
  3. +2 −2 lib/rules/strict.js
  4. +21 −10 tests/lib/rules/strict.js
@@ -117,7 +117,7 @@ function foo() {
foo();
```

### "function" (default)
### "function"

This mode ensures that all function bodies are strict mode code, while global code is not. Particularly if a build step concatenates multiple scripts, a Use Strict Directive in global code of one script could unintentionally enable strict mode in another script that was not intended to be strict code. It forbids any occurrence of a Use Strict Directive in global code. It requires exactly one Use Strict Directive in each function declaration or expression whose parent is global code. Use Strict Directives inside nested functions are considered unnecessary. Multiple Use Strict Directives at any level also trigger warnings.

@@ -164,13 +164,13 @@ function foo() {
foo();
```

### "safe"
### "safe" (default)

Node.js and the CommonJS module system wrap modules inside a hidden function wrapper that defines each module's scope. The wrapper makes it safe to concatenate strict-mode modules while maintaining their original `"use strict"` directives. When the `node` or `commonjs` environments are enabled or `globalReturn` is enabled in `ecmaFeatures`, ESLint considers code to be inside the module wrapper, and `"safe"` mode corresponds to `"global"` mode and enforces global `"use strict"` directives. Everywhere else, `"safe"` mode corresponds to `"function"` mode and enforces `"use strict"` directives inside top-level functions.

### "deprecated" (Removed)

**Replacement notice**: This mode, previously enabled by turning on the rule without specifying a mode, has been removed in ESLint v1.0. `"function"` mode is most similar to the deprecated behavior, and has been made the default if no mode is specified.
**Replacement notice**: This mode, previously enabled by turning on the rule without specifying a mode, has been removed in ESLint v1.0. `"function"` mode is most similar to the deprecated behavior.

This mode ensures that all functions are executed in strict mode. A Use Strict Directive must be present in global code or in every top-level function declaration or expression. It does not concern itself with unnecessary Use Strict Directives in nested functions that are already strict, nor with multiple Use Strict Directives at the same level.

@@ -288,3 +288,7 @@ So the second argument `ast` also should be parsed from stripped text.
var ast = yourParser.parse(text.replace(/^\uFEFF/, ""), options);
var sourceCode = new SourceCode(text, ast);
```

## Rule Changes

* [strict](strict.md) - defaults to `"safe"`
@@ -57,7 +57,7 @@ module.exports = function(context) {

var mode = context.options[0];

if (mode === "safe") {
if (["never", "global", "function"].indexOf(mode) < 0) {
mode = context.parserOptions.ecmaFeatures &&
context.parserOptions.ecmaFeatures.globalReturn ?
"global" : "function";
@@ -157,7 +157,7 @@ module.exports = function(context) {
}

//--------------------------------------------------------------------------
// "function" mode (Default)
// "function" mode
//--------------------------------------------------------------------------

var scopes = [],
@@ -65,12 +65,14 @@ ruleTester.run("strict", rule, {
options: ["function"]
},

// defaults to "function" mode
{ code: "function foo() { 'use strict'; return; }" },

// "safe" mode corresponds to "global" if ecmaFeatures.globalReturn is true, otherwise "function"
{ code: "function foo() { 'use strict'; return; }", options: ["safe"] },
{ code: "'use strict'; function foo() { return; }", parserOptions: { ecmaFeatures: { globalReturn: true } }, options: ["safe"] }
{ code: "'use strict'; function foo() { return; }", parserOptions: { ecmaFeatures: { globalReturn: true } }, options: ["safe"] },

// defaults to "safe" mode
{ code: "function foo() { 'use strict'; return; }" },
{ code: "'use strict'; function foo() { return; }", parserOptions: { ecmaFeatures: { globalReturn: true } } }

],
invalid: [
@@ -296,31 +298,40 @@ ruleTester.run("strict", rule, {
},


// Default to "function" mode
// "safe" mode corresponds to "global" if ecmaFeatures.globalReturn is true, otherwise "function"
{
code: "'use strict'; function foo() { return; }",
options: ["safe"],
errors: [
{ message: "Use the function form of 'use strict'.", type: "ExpressionStatement" },
{ message: "Use the function form of 'use strict'.", type: "FunctionDeclaration" }
]
}, {
code: "function foo() { return; }",
errors: [{ message: "Use the function form of 'use strict'.", type: "FunctionDeclaration" }]
},
{
code: "function foo() { 'use strict'; return; }",
parserOptions: { ecmaFeatures: { globalReturn: true } },
options: ["safe"],
errors: [
{ message: "Use the global form of 'use strict'.", type: "Program" },
{ message: "Use the global form of 'use strict'.", type: "ExpressionStatement" }
]
},

// "safe" mode corresponds to "global" if ecmaFeatures.globalReturn is true, otherwise "function"
// Default to "safe" mode
{
code: "'use strict'; function foo() { return; }",
options: ["safe"],
errors: [
{ message: "Use the function form of 'use strict'.", type: "ExpressionStatement" },
{ message: "Use the function form of 'use strict'.", type: "FunctionDeclaration" }
]
},
{
code: "function foo() { return; }",
errors: [{ message: "Use the function form of 'use strict'.", type: "FunctionDeclaration" }]
},
{
code: "function foo() { 'use strict'; return; }",
parserOptions: { ecmaFeatures: { globalReturn: true } },
options: ["safe"],
errors: [
{ message: "Use the global form of 'use strict'.", type: "Program" },
{ message: "Use the global form of 'use strict'.", type: "ExpressionStatement" }

0 comments on commit 3e6a24e

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