From 02f93c318cd9d6672c3e9020464de3362441e0ad Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Wed, 4 Nov 2015 11:57:15 -0500 Subject: [PATCH] Add rule for const outside of module scope. Good: ``` const FOO = 'FOO'; export const BAR = 'BAR'; ``` Bad: ``` function derp() { const FOO = 'FOO'; } if (false) { const BLAH = 'BLAH'; } ``` --- I did not add configuration for this rule in the default preset (but I can if we want it)... --- lib/jscsrc.json | 1 + .../disallow-const-outside-module-scope.js | 38 +++++++++++++++++++ .../bad/inside-function.js | 3 ++ .../bad/inside-if.js | 3 ++ .../good/example.js | 6 +++ 5 files changed, 51 insertions(+) create mode 100644 lib/rules/disallow-const-outside-module-scope.js create mode 100644 tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-function.js create mode 100644 tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-if.js create mode 100644 tests/fixtures/rules/disallow-const-outside-module-scope/good/example.js diff --git a/lib/jscsrc.json b/lib/jscsrc.json index 0a6af07..abb1fee 100644 --- a/lib/jscsrc.json +++ b/lib/jscsrc.json @@ -6,6 +6,7 @@ "./rules/*.js" ], + "disallowConstOutsideModuleScope": true, "disallowEmptyBlocks": true, "disallowKeywordsOnNewLine": ["else"], "disallowMultipleLineBreaks": true, diff --git a/lib/rules/disallow-const-outside-module-scope.js b/lib/rules/disallow-const-outside-module-scope.js new file mode 100644 index 0000000..32c2045 --- /dev/null +++ b/lib/rules/disallow-const-outside-module-scope.js @@ -0,0 +1,38 @@ +var assert = require('assert'); + +module.exports = function() { }; + +module.exports.prototype = { + configure: function(option) { + assert(option === true, this.getOptionName() + ' requires a true value'); + }, + + getOptionName: function() { + return 'disallowConstOutsideModuleScope'; + }, + + check: function(file, errors) { + file.iterateNodesByType('VariableDeclaration', function(node) { + if (node.parentNode.type === 'Program') { + // declaration is in root of module + return; + } + + if (node.parentNode.type === 'ExportNamedDeclaration' && node.parentNode.parentNode.type === 'Program') { + // declaration is a `export const foo = 'asdf'` in root of the module + return; + } + + for (var i = 0; i < node.declarations.length; i++) { + var thisDeclaration = node.declarations[i]; + + if (thisDeclaration.parentNode.kind === 'const') { + errors.add( + '`const` should only be used in module scope (not inside functions/blocks).', + node.loc.start + ); + } + } + }); + } +}; diff --git a/tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-function.js b/tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-function.js new file mode 100644 index 0000000..7f3ad39 --- /dev/null +++ b/tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-function.js @@ -0,0 +1,3 @@ +function something() { + const foo = 'bar'; +} diff --git a/tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-if.js b/tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-if.js new file mode 100644 index 0000000..965f99a --- /dev/null +++ b/tests/fixtures/rules/disallow-const-outside-module-scope/bad/inside-if.js @@ -0,0 +1,3 @@ +if (true) { + const foo = 'bar'; +} diff --git a/tests/fixtures/rules/disallow-const-outside-module-scope/good/example.js b/tests/fixtures/rules/disallow-const-outside-module-scope/good/example.js new file mode 100644 index 0000000..d370a64 --- /dev/null +++ b/tests/fixtures/rules/disallow-const-outside-module-scope/good/example.js @@ -0,0 +1,6 @@ +const foo = 'blah'; +export const bar = 'derp'; + +function something() { + let hey = 'you!'; +}