diff --git a/docs/rules/strict.md b/docs/rules/strict.md index 19817e767e1..d37c3792086 100644 --- a/docs/rules/strict.md +++ b/docs/rules/strict.md @@ -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 @@ -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. diff --git a/lib/rules/strict.js b/lib/rules/strict.js index 7d13a726c6b..954f7e6df4e 100644 --- a/lib/rules/strict.js +++ b/lib/rules/strict.js @@ -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. @@ -219,6 +225,6 @@ module.exports = function(context) { module.exports.schema = [ { - "enum": ["never", "global", "function"] + "enum": ["never", "global", "function", "safe"] } ]; diff --git a/tests/lib/rules/strict.js b/tests/lib/rules/strict.js index 649d74de535..2f6bf01b0cc 100644 --- a/tests/lib/rules/strict.js +++ b/tests/lib/rules/strict.js @@ -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: [ @@ -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" } + ] } ]