UNPKG

@maniascript/mslint

Version:
83 lines (82 loc) 3.24 kB
import {} from '../linter/rule.js'; import { Scope, ScopeType, Variable } from '@maniascript/parser'; const DEFAULT_EXCEPTIONS = []; export const noUnusedVariables = { meta: { id: 'no-unused-variables', description: 'Forbid unused variables', recommended: true, settings: { exceptions: DEFAULT_EXCEPTIONS } }, create(context) { const exceptions = Array.isArray(context.settings['exceptions']) ? context.settings['exceptions'] : DEFAULT_EXCEPTIONS; function getReportMessage(name, variable, isWrite) { let type = ''; if (variable.isFunctionParameter) { type = 'Function parameter'; } else if (variable.isGlobal) { type = 'Global variable'; } else if (variable.isForValue) { type = 'For value'; } else if (variable.isForeachKey) { type = 'Foreach key'; } else if (variable.isForeachValue) { type = 'Foreach value'; } else { type = 'Variable'; } let action = ''; if (isWrite) { action = 'never read'; } else { action = 'never used'; } return `${type} '${name}' is ${action}`; } function findUnusedVariables(context, scope) { if (scope.type !== ScopeType.LabelDeclaration && !scope.couldReferenceVariableInLabel) { let hasForeachKey = false; let useForeachKey = true; for (const [name, variable] of scope.variables) { if (variable.isForeachKey) { hasForeachKey = true; } if (!variable.isForValue && // Allow unused for value (!variable.isForeachValue || !hasForeachKey || !useForeachKey) && // Allow unused foreach value if the key is used !exceptions.includes(name)) { if (variable.references.length === 0) { if (variable.isForeachKey) { useForeachKey = false; } context.report(variable.node, getReportMessage(name, variable, false)); } else if (!variable.isTrait && variable.references.every((reference) => reference.isWrite())) { if (variable.isForeachKey) { useForeachKey = false; } context.report(variable.node, getReportMessage(name, variable, true)); } } } } for (const child of scope.children) { findUnusedVariables(context, child); } } return { 'Program:exit': () => { const scope = context.getScope(); if (scope !== null) findUnusedVariables(context, scope); } }; } };