@maniascript/mslint
Version:
ManiaScript linter
92 lines (91 loc) • 3.86 kB
JavaScript
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);
}
}
};
}
};