Skip to content

Commit

Permalink
Improve S104: report on file level (#2048)
Browse files Browse the repository at this point in the history
* Update ruling to report on file level

* Create own implementation of S104 (max-lines) to report on file level
  • Loading branch information
vilchik-elena committed Jul 31, 2020
1 parent 04177f9 commit 17074e6
Show file tree
Hide file tree
Showing 25 changed files with 255 additions and 140 deletions.
2 changes: 2 additions & 0 deletions eslint-bridge/src/rules/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ import { rule as sonarBlockScopedVar } from './sonar-block-scoped-var';
import { rule as sonarNoUnusedVars } from './sonar-no-unused-vars';
import { rule as sockets } from './sockets';
import { rule as sonarMaxLinesPerFunction } from './sonar-max-lines-per-function';
import { rule as sonarMaxLines } from './sonar-max-lines';
import { rule as sqlQueries } from './sql-queries';
import { rule as standardInput } from './standard-input';
import { rule as todoTag } from './todo-tag';
Expand Down Expand Up @@ -203,6 +204,7 @@ ruleModules['sonar-block-scoped-var'] = sonarBlockScopedVar;
ruleModules['sonar-no-unused-vars'] = sonarNoUnusedVars;
ruleModules['sockets'] = sockets;
ruleModules['sonar-max-lines-per-function'] = sonarMaxLinesPerFunction;
ruleModules['sonar-max-lines'] = sonarMaxLines;
ruleModules['sql-queries'] = sqlQueries;
ruleModules['standard-input'] = standardInput;
ruleModules['todo-tag'] = todoTag;
Expand Down
45 changes: 26 additions & 19 deletions eslint-bridge/src/rules/sonar-max-lines-per-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,7 @@ export const rule: Rule.RuleModule = {
return;
}

let lineCount = 0;

for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) {
const line = lines[i];

if (
commentLineNumbers.has(i + 1) &&
isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))
) {
continue;
}

if (line.match(/^\s*$/u)) {
continue;
}

lineCount++;
}
const lineCount = getLocsNumber(node.loc, lines, commentLineNumbers);

if (lineCount > threshold) {
context.report({
Expand All @@ -77,7 +60,31 @@ export const rule: Rule.RuleModule = {
},
};

function getCommentLineNumbers(comments: estree.Comment[]) {
export function getLocsNumber(
loc: estree.SourceLocation,
lines: string[],
commentLineNumbers: Map<number, estree.Comment>,
) {
let lineCount = 0;

for (let i = loc.start.line - 1; i < loc.end.line; ++i) {
const line = lines[i];
const comment = commentLineNumbers.get(i + 1);
if (comment && isFullLineComment(line, i + 1, comment)) {
continue;
}

if (line.match(/^\s*$/u)) {
continue;
}

lineCount++;
}

return lineCount;
}

export function getCommentLineNumbers(comments: estree.Comment[]): Map<number, estree.Comment> {
const map = new Map();

comments.forEach(comment => {
Expand Down
56 changes: 56 additions & 0 deletions eslint-bridge/src/rules/sonar-max-lines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2011-2020 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 GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

// https://jira.sonarsource.com/browse/RSPEC-104

import { Rule } from 'eslint';
import * as estree from 'estree';
import { getLocsNumber, getCommentLineNumbers } from './sonar-max-lines-per-function';

export const rule: Rule.RuleModule = {
meta: {
schema: [{ type: 'integer' }],
},
create(context: Rule.RuleContext) {
const [threshold] = context.options;

const sourceCode = context.getSourceCode();
const lines = sourceCode.lines;

const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments());

return {
'Program:exit': (node: estree.Node) => {
if (!node.loc) {
return;
}

const lineCount = getLocsNumber(node.loc, lines, commentLineNumbers);

if (lineCount > threshold) {
context.report({
message: `This file has ${lineCount} lines, which is greater than ${threshold} authorized. Split it into smaller files.`,
loc: { line: 0, column: 0 },
});
}
},
};
},
};
60 changes: 60 additions & 0 deletions eslint-bridge/tests/rules/sonar-max-lines.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2011-2020 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 GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* 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 GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { RuleTester } from 'eslint';

const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
import { rule } from '../../src/rules/sonar-max-lines';

ruleTester.run('Too many lines in file', rule, {
valid: [
{
code: `a;
b;
c;`,
options: [3],
},
{
code: `a;
b;
// comment
c;`,
options: [3],
},
],
invalid: [
{
code: `a;
b;
c;
// comment
d;`,
options: [3],
errors: [
{
message: `This file has 4 lines, which is greater than 3 authorized. Split it into smaller files.`,
line: 0,
column: 1,
},
],
},
],
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
'amplify:test/request/unit.js':[
1,
0,
],
}
48 changes: 24 additions & 24 deletions its/ruling/src/test/expected/js/angular.js/javascript-S104.json
Original file line number Diff line number Diff line change
@@ -1,74 +1,74 @@
{
'angular.js:src/ng/compile.js':[
1,
0,
],
'angular.js:src/ng/parse.js':[
1,
0,
],
'angular.js:src/ngMock/angular-mocks.js':[
1,
0,
],
'angular.js:src/ngParseExt/ucd.js':[
1,
0,
],
'angular.js:test/AngularSpec.js':[
1,
0,
],
'angular.js:test/auto/injectorSpec.js':[
1,
0,
],
'angular.js:test/jqLiteSpec.js':[
1,
0,
],
'angular.js:test/ng/compileSpec.js':[
1,
0,
],
'angular.js:test/ng/directive/formSpec.js':[
1,
0,
],
'angular.js:test/ng/directive/inputSpec.js':[
1,
0,
],
'angular.js:test/ng/directive/ngModelSpec.js':[
1,
0,
],
'angular.js:test/ng/directive/ngOptionsSpec.js':[
1,
0,
],
'angular.js:test/ng/directive/ngRepeatSpec.js':[
1,
0,
],
'angular.js:test/ng/directive/selectSpec.js':[
1,
0,
],
'angular.js:test/ng/httpSpec.js':[
1,
0,
],
'angular.js:test/ng/locationSpec.js':[
1,
0,
],
'angular.js:test/ng/parseSpec.js':[
1,
0,
],
'angular.js:test/ng/qSpec.js':[
1,
0,
],
'angular.js:test/ng/rootScopeSpec.js':[
1,
0,
],
'angular.js:test/ngAnimate/animateCssSpec.js':[
1,
0,
],
'angular.js:test/ngAnimate/animateSpec.js':[
1,
0,
],
'angular.js:test/ngMock/angular-mocksSpec.js':[
1,
0,
],
'angular.js:test/ngResource/resourceSpec.js':[
1,
0,
],
'angular.js:test/ngRoute/routeSpec.js':[
1,
0,
],
}
14 changes: 7 additions & 7 deletions its/ruling/src/test/expected/js/backbone/javascript-S104.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
'backbone:backbone.js':[
1,
0,
],
'backbone:test/collection.js':[
1,
0,
],
'backbone:test/model.js':[
1,
0,
],
'backbone:test/vendor/jquery.js':[
1,
0,
],
'backbone:test/vendor/qunit.js':[
1,
0,
],
'backbone:test/vendor/require.js':[
1,
0,
],
'backbone:test/vendor/underscore.js':[
1,
0,
],
}
6 changes: 3 additions & 3 deletions its/ruling/src/test/expected/js/es5-shim/javascript-S104.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
'es5-shim:es5-shim.js':[
1,
0,
],
'es5-shim:tests/lib/jasmine.js':[
1,
0,
],
'es5-shim:tests/spec/s-array.js':[
1,
0,
],
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
'javascript-test-sources:src/ecmascript6/Ghost/core/test/integration/api/api_users_spec.js':[
1,
0,
],
'javascript-test-sources:src/ecmascript6/Ghost/core/test/integration/import_spec.js':[
1,
0,
],
'javascript-test-sources:src/ecmascript6/router/third_party/brick/brick-1.0.1.byob.js':[
1,
0,
],
'javascript-test-sources:src/ecmascript6/snoode/src/endpoints/v1.es6.js':[
1,
0,
],
}

0 comments on commit 17074e6

Please sign in to comment.