eslint-plugin-sonarjs
Version:
SonarJS rules for ESLint
78 lines (77 loc) • 3.33 kB
JavaScript
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2011-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Sonar Source-Available License for more details.
*
* You should have received a copy of the Sonar Source-Available License
* along with this program; if not, see https://sonarsource.com/license/ssal/
*/
// https://sonarsource.github.io/rspec/#/rspec/S2428
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = void 0;
const index_js_1 = require("../helpers/index.js");
const meta_js_1 = require("./meta.js");
exports.rule = {
meta: (0, index_js_1.generateMeta)(meta_js_1.meta, {
messages: {
declarePropertiesInsideObject: 'Declare one or more properties of this object inside of the object literal syntax instead of using separate statements.',
},
}),
create(context) {
return {
BlockStatement: (node) => checkObjectInitialization(node.body, context),
Program: (node) => {
checkObjectInitialization((0, index_js_1.getProgramStatements)(node), context);
},
};
},
};
function checkObjectInitialization(statements, context) {
let index = 0;
while (index < statements.length - 1) {
const objectDeclaration = getObjectDeclaration(statements[index]);
if (objectDeclaration && (0, index_js_1.isIdentifier)(objectDeclaration.id)) {
const nextStmt = statements[index + 1];
if (isPropertyAssignment(nextStmt, objectDeclaration.id, context.sourceCode)) {
context.report({ messageId: 'declarePropertiesInsideObject', node: objectDeclaration });
}
}
index++;
}
}
function getObjectDeclaration(statement) {
if (statement.type === 'VariableDeclaration') {
return statement.declarations.find(declaration => !!declaration.init && isEmptyObjectExpression(declaration.init));
}
return undefined;
}
function isEmptyObjectExpression(expression) {
return expression.type === 'ObjectExpression' && expression.properties.length === 0;
}
function isPropertyAssignment(statement, objectIdentifier, sourceCode) {
if (statement.type === 'ExpressionStatement' &&
statement.expression.type === 'AssignmentExpression') {
const { left, right } = statement.expression;
if (left.type === 'MemberExpression') {
return (!left.computed &&
isSingleLineExpression(right, sourceCode) &&
(0, index_js_1.areEquivalent)(left.object, objectIdentifier, sourceCode) &&
!(0, index_js_1.areEquivalent)(left.object, right, sourceCode));
}
}
return false;
function isSingleLineExpression(expression, sourceCode) {
const first = sourceCode.getFirstToken(expression).loc;
const last = sourceCode.getLastToken(expression).loc;
return first.start.line === last.end.line;
}
}
;