Skip to content

Commit

Permalink
Update: Add "safe" mode to strict (fixes #3306)
Browse files Browse the repository at this point in the history
  • Loading branch information
btmills committed Dec 12, 2015
1 parent 3663eeb commit 17c7624
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
7 changes: 6 additions & 1 deletion docs/rules/strict.md
Expand Up @@ -26,11 +26,12 @@ This rule is aimed at using strict directives effectively, and as such, will fla

### Options

There are three options for this rule:
There are four options for this rule:

1. `never` - don't use `"use strict"` at all
1. `global` - require `"use strict"` in the global scope
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.

### "never" mode

Expand Down Expand Up @@ -163,6 +164,10 @@ function foo() {
foo();
```

### "safe" mode

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 mode (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.
Expand Down
8 changes: 7 additions & 1 deletion lib/rules/strict.js
Expand Up @@ -57,6 +57,12 @@ module.exports = function(context) {

var mode = context.options[0];

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

/**
* Report a node or array of nodes with a given message.
* @param {(ASTNode|ASTNode[])} nodes Node or nodes to report.
Expand Down Expand Up @@ -219,6 +225,6 @@ module.exports = function(context) {

module.exports.schema = [
{
"enum": ["never", "global", "function"]
"enum": ["never", "global", "function", "safe"]
}
];
25 changes: 24 additions & 1 deletion tests/lib/rules/strict.js
Expand Up @@ -66,7 +66,11 @@ ruleTester.run("strict", rule, {
},

// defaults to "function" mode
{ code: "function foo() { 'use strict'; return; }" }
{ 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"] }

],
invalid: [
Expand Down Expand Up @@ -302,6 +306,25 @@ ruleTester.run("strict", rule, {
}, {
code: "function foo() { return; }",
errors: [{ message: "Use the function form of \"use strict\".", type: "FunctionDeclaration" }]
},

// "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() { '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" }
]
}

]
Expand Down

0 comments on commit 17c7624

Please sign in to comment.