UNPKG

@sap/eslint-plugin-cds

Version:

ESLint plugin including recommended SAP Cloud Application Programming model and environment rules

65 lines (56 loc) 1.91 kB
'use strict' const { forEachXprInDefinition } = require('../utils/csnTraversal') const invalidComparisonOperators = [ '=', '<>' ] module.exports = { meta: { schema: [{/* to avoid deprecation warning for ESLint 9 */}], docs: { description: 'Ensure SQL comparisons with \'null\' are valid', category: 'Model Validation', recommended: false, url: 'https://cap.cloud.sap/docs/tools/cds-lint/rules/sql-null-comparison', }, type: 'problem', model: 'parsed', messages: { nullComparison: `Comparisons against 'null' using '=' and '<>' are always null. Did you mean 'is null'/'is not null'?`, } }, create(context) { const model = context.getModel() if (!model?.definitions) return return function checkSqlNullComparisonsInModel() { for (const defName in model.definitions) { const def = model.definitions[defName] if (def.query || def.projection) forEachXprInDefinition(def, checkExpression) } } function checkExpression(xpr, ctx) { if (!xpr || !Array.isArray(xpr)) return for (let i = 0; i < xpr.length; i++) { if (typeof xpr[i] !== 'object') continue // scalar value, etc. if (xpr[i]?.val === null) { const prev = i > 0 && typeof xpr[i-1] === 'string' ? xpr[i-1] : null if (prev && invalidComparisonOperators.includes(prev)) { reportComparison(xpr, ctx) continue } const next = i+1 < xpr.length && typeof xpr[i+1] === 'string' ? xpr[i+1] : null if (next && invalidComparisonOperators.includes(next)) reportComparison(xpr, ctx) } } } function reportComparison(xpr, ctx) { context.report({ messageId: 'nullComparison', loc: context.getLocation('', ctx), file: ctx.$location?.file, }) } } }