123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- module.exports = {
- rules: {
- // auto fixable
- 'no-spaces-in-control-flow-statements': {
- meta: {
- docs: {
- description: 'Disallow spaces in control flow statements',
- category: 'Z8 Stylistic Issues',
- recommended: true,
- },
- fixable: 'code',
- schema: [],
- },
- create: function (context) {
- return {
- IfStatement: function (node) {
- const tokens = context.getSourceCode().getTokens(node);
- const firstToken = tokens[0];
- const secondToken = tokens[1];
- if (firstToken.type === 'Keyword' &&
- firstToken.value === 'if' &&
- secondToken.type === 'Punctuator' &&
- secondToken.value === '(' &&
- secondToken.range[0] - firstToken.range[1] > 0
- ) {
- context.report({
- node: node,
- message: 'Do not use spaces between \'if\' and its condition',
- fix: function(fixer) {
- return fixer.replaceTextRange([firstToken.range[1], secondToken.range[0]], '');
- }
- });
- }
- },
- ForStatement: function (node) {
- const tokens = context.getSourceCode().getTokens(node);
- const firstToken = tokens[0];
- const secondToken = tokens[1];
- if (
- firstToken.type === 'Keyword' &&
- firstToken.value === 'for' &&
- secondToken.type === 'Punctuator' &&
- secondToken.value === '(' &&
- secondToken.range[0] - firstToken.range[1] > 0
- ) {
- context.report({
- node: node,
- message: 'Do not use spaces between \'for\' and its condition',
- fix: function(fixer) {
- return fixer.replaceTextRange([firstToken.range[1], secondToken.range[0]], '');
- }
- });
- }
- },
- WhileStatement: function (node) {
- const tokens = context.getSourceCode().getTokens(node);
- const firstToken = tokens[0];
- const secondToken = tokens[1];
- if (
- firstToken.type === 'Keyword' &&
- firstToken.value === 'while' &&
- secondToken.type === 'Punctuator' &&
- secondToken.value === '(' &&
- secondToken.range[0] - firstToken.range[1] > 0
- ) {
- context.report({
- node: node,
- message: 'Do not use spaces between \'while\' and its condition',
- fix: function(fixer) {
- return fixer.replaceTextRange([firstToken.range[1], secondToken.range[0]], '');
- }
- });
- }
- },
- SwitchStatement: function (node) {
- const tokens = context.getSourceCode().getTokens(node);
- const firstToken = tokens[0];
- const secondToken = tokens[1];
- if (
- firstToken.type === 'Keyword' &&
- firstToken.value === 'switch' &&
- secondToken.type === 'Punctuator' &&
- secondToken.value === '(' &&
- secondToken.range[0] - firstToken.range[1] > 0
- ) {
- context.report({
- node: node,
- message: 'Do not use spaces between \'switch\' and its expression',
- fix: function(fixer) {
- return fixer.replaceTextRange([firstToken.range[1], secondToken.range[0]], '');
- }
- });
- }
- },
- };
- },
- },
- 'no-strict-equality': {
- meta: {
- docs: {
- description: 'Disallow strict equality operator',
- category: 'Z8 Stylistic Issues',
- recommended: true,
- },
- fixable: 'code',
- schema: [],
- },
- create: function (context) {
- return {
- BinaryExpression: function (node) {
- if (
- (node.operator === '===' || node.operator === '!==') && (
- (node.right.type === 'Literal' && node.left.type === 'Literal') ||
- (node.right.type === 'Literal' && ![true, false].includes(node.right.value)) ||
- (node.left.type === 'Literal' && ![true, false].includes(node.left.value)) ||
- (node.right.type === 'Identifier' && node.left.type === 'Identifier' && !(node.right.name === "undefined" || node.left.name === "undefined"))
- )
- ) {
- context.report({
- node: node,
- message: 'Avoid using strict equality operator \''+node.operator+'\' (use loose equality operator \''+node.operator.substring(0, 2)+'\' instead)',
- });
- }
- },
- };
- },
- },
- // auto fixable
- 'no-double-quotes': {
- meta: {
- docs: {
- description: 'Disallow double quotes',
- category: 'Z8 Stylistic Issues',
- recommended: true,
- },
- fixable: 'code',
- schema: [],
- },
- create: function (context) {
- return {
- Literal: function (node) {
- if (typeof node.value === 'string' && node.raw[0] === '"') {
- context.report({
- node: node,
- message: 'Avoid using double quotes (use single quotes instead)',
- fix: function(fixer) {
- return fixer.replaceTextRange([node.start, node.end], "'" + node.value.replace(/'/g, '\\\'') + "'");
- }
- });
- }
- },
- };
- },
- },
- 'no-arrow-functions': {
- meta: {
- docs: {
- description: 'Disallow arrow functions',
- category: 'Z8 Stylistic Issues',
- recommended: true,
- },
- schema: [],
- },
- create: function (context) {
- return {
- ArrowFunctionExpression: function (node) {
- context.report({
- node: node,
- message: 'Avoid using arrow functions',
- });
- },
- };
- },
- },
- 'no-function-declaration': {
- meta: {
- docs: {
- description: 'Disallow function declaration',
- category: 'Z8 Stylistic Issues',
- recommended: true,
- },
- schema: [],
- },
- create: function (context) {
- return {
- FunctionDeclaration: function (node) {
- context.report({
- node: node,
- message: 'Use function expression instead of function declaration',
- });
- },
- VariableDeclarator: function (node) {
- if (
- node.init &&
- node.init.type === 'FunctionExpression' &&
- node.init.id &&
- node.init.id.type === 'Identifier' &&
- node.id &&
- node.id.type === 'Identifier' &&
- node.init.id.name === node.id.name
- ) {
- context.report({
- node: node,
- message: 'Use function expression instead of function declaration',
- });
- }
- },
- };
- },
- },
- 'todo': {
- meta: {
- type: 'suggestion',
- docs: {
- description: 'TODO tracking',
- category: 'Other',
- recommended: true
- },
- schema: []
- },
- create: function (context) {
- const sourceCode = context.getSourceCode();
- const comments = sourceCode.getAllComments();
- return {
- Program: function(node) {
- comments.forEach(comment => {
- if (comment.value.toLowerCase().includes('todo')) {
- context.report({
- node,
- loc: comment.loc,
- message: comment.value.trim(),
- });
- }
- });
- },
- };
- }
- },
- // auto fixable
- 'whitespace-only-lines': {
- meta: {
- type: 'suggestion',
- docs: {
- description: 'Disallow empty lines with only whitespace',
- category: 'Z8 Stylistic Issues',
- recommended: true
- },
- fixable: 'code',
- schema: []
- },
- create: function (context) {
- const sourceCode = context.getSourceCode();
- return {
- Program: function (node) {
- const lines = sourceCode.lines;
- lines.forEach((line, index) => {
- if (/^\s+$/.test(line)) {
- context.report({
- node: node,
- loc: {line: index + 1, column: 0},
- message: 'Empty line with only whitespace',
- fix: function(fixer) {
- return fixer.replaceTextRange([sourceCode.getIndexFromLoc({line: index + 1, column: 0}), sourceCode.getIndexFromLoc({line: index + 1, column: line.length})], '');
- }
- });
- }
- });
- }
- };
- }
- },
- // auto fixable
- 'prefer-var': {
- meta: {
- docs: {
- description: 'Disallow let/const usage',
- category: 'Z8 Stylistic Issues',
- recommended: true,
- },
- fixable: 'code',
- schema: [],
- },
- create: function(context) {
- return {
- VariableDeclaration(node) {
- if (node.kind !== 'var') {
- context.report({
- node: node,
- message: 'Prefer using `var` instead of `let` or `const`.',
- fix: function(fixer) {
- return fixer.replaceTextRange([node.start, node.start + node.kind.length], 'var');
- }
- });
- }
- }
- };
- }
- }
- },
- };
- /**
- * Preferable .eslintrc.js:
- *
- * module.exports = {
- * 'plugins': [
- * 'z8'
- * ],
- * 'rules': {
- * 'z8/no-spaces-in-control-flow-statements': ['error'],
- * 'z8/no-strict-equality': ['error'],
- * 'z8/no-double-quotes': ['error'],
- * 'z8/no-arrow-functions': ['error'],
- * 'z8/no-function-declaration': ['error'],
- * 'object-shorthand': ['error', 'never'],
- * 'object-curly-spacing': ['error', 'always'],
- * 'space-before-blocks': ['error', 'always'],
- * 'func-call-spacing': ['error', 'never'],
- * 'space-before-function-paren': ['error', 'never'],
- * 'semi': ['error', 'always'],
- * 'space-infix-ops': ['error'],
- * 'indent': ['error', 'tab'],
- * 'no-console': ['warn'],
- * 'z8/todo': ['warn'],
- * 'z8/whitespace-only-lines': ['error']
- * },
- * 'parserOptions': {
- * 'ecmaVersion': 2022,
- * 'sourceType': 'module'
- * }
- * }
- *
- */
|