UNPKG

@maniascript/mslint

Version:
92 lines (91 loc) 3.86 kB
import {} from '../linter/rule.js'; import { BlockStatement, Main, FunctionDeclaration, LabelDeclaration } from '@maniascript/parser'; const DEFAULT_MAXIMUM = 100; export const maxStatements = { meta: { id: 'max-statements', description: 'Enforce a maximum number of statements in three contexts: function, label and main', recommended: true, settings: { maximum: { function: DEFAULT_MAXIMUM, label: DEFAULT_MAXIMUM, main: DEFAULT_MAXIMUM } } }, create(context) { let functionMaxStatementsNb = DEFAULT_MAXIMUM; let labelMaxStatementsNb = DEFAULT_MAXIMUM; let mainMaxStatementsNb = DEFAULT_MAXIMUM; const stack = []; if (typeof context.settings['maximum'] === 'number') { functionMaxStatementsNb = context.settings['maximum']; labelMaxStatementsNb = context.settings['maximum']; mainMaxStatementsNb = context.settings['maximum']; } else if (typeof context.settings['maximum'] === 'object' && context.settings['maximum'] !== null) { const maximum = context.settings['maximum']; if ('function' in maximum && typeof maximum.function === 'number') functionMaxStatementsNb = maximum.function; if ('label' in maximum && typeof maximum.label === 'number') labelMaxStatementsNb = maximum.label; if ('main' in maximum && typeof maximum.main === 'number') mainMaxStatementsNb = maximum.main; } function enterFunction() { stack.push(0); } function exitFunction(node) { const count = stack.pop(); if (count !== undefined) { if (node instanceof Main && count > mainMaxStatementsNb) { context.report(node, `Function 'main()' contains too many statements (${count.toString()} > ${mainMaxStatementsNb.toString()})`); } else if (node instanceof FunctionDeclaration && count > functionMaxStatementsNb) { context.report(node, `Function '${node.name.name}()' contains too many statements (${count.toString()} > ${functionMaxStatementsNb.toString()})`); } else if (node instanceof LabelDeclaration && count > labelMaxStatementsNb) { context.report(node, `Label '***${node.name.name}***' contains too many statements (${count.toString()} > ${labelMaxStatementsNb.toString()})`); } } } function countStatements(block) { stack[stack.length - 1] += block.body.length; } return { 'Main:enter': () => { enterFunction(); }, 'Main:exit': (node) => { if (node instanceof Main) { exitFunction(node); } }, 'FunctionDeclaration:enter': () => { enterFunction(); }, 'FunctionDeclaration:exit': (node) => { if (node instanceof FunctionDeclaration) { exitFunction(node); } }, 'LabelDeclaration:enter': (node) => { if (node instanceof LabelDeclaration) { enterFunction(); countStatements(node); } }, 'LabelDeclaration:exit': (node) => { if (node instanceof LabelDeclaration) { exitFunction(node); } }, 'BlockStatement:enter': (node) => { if (node instanceof BlockStatement) { countStatements(node); } } }; } };