Skip to content

Commit

Permalink
improve 'no-identical-functions': add option for min function size (S…
Browse files Browse the repository at this point in the history
…onarSource#325)

* Add min lines configuration for no-identical-functions rule

* Improve options schema

* Bring back classic options schema

Co-authored-by: raspopov.iv <[email protected]>
  • Loading branch information
vilchik-elena and raspopov.iv authored Feb 15, 2022
1 parent 033e87e commit 792914a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
13 changes: 10 additions & 3 deletions docs/rules/no-identical-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@ function calculateCode() {
doOtherThing();
return code;
}

function getName() {
return calculateCode();
}
```

## Exceptions
## Configuration

This rule has a numeric option (defaulted to 3) to specify the minimum number of lines to trigger an issue. Lines between curly braces are taken into consideration.

Functions with fewer than 3 lines are ignored.
```json
{
"no-identical-functions": "error",
"no-identical-functions": ["error", 5]
}
```
13 changes: 10 additions & 3 deletions src/rules/no-identical-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { areEquivalent } from '../utils/equivalence';
import { getMainFunctionTokenLocation, report, issueLocation } from '../utils/locations';
import docsUrl from '../utils/docs-url';

const DEFAULT_MIN_LINES = 3;

type FunctionNode =
| TSESTree.FunctionDeclaration
| TSESTree.FunctionExpression
Expand All @@ -32,7 +34,9 @@ type FunctionNode =
const message =
'Update this function so that its implementation is not identical to the one on line {{line}}.';

const rule: TSESLint.RuleModule<string, string[]> = {
type Options = (number | 'sonar-runtime')[];

const rule: TSESLint.RuleModule<string, Options> = {
meta: {
messages: {
identicalFunctions: message,
Expand All @@ -45,13 +49,16 @@ const rule: TSESLint.RuleModule<string, string[]> = {
url: docsUrl(__filename),
},
schema: [
{ type: 'integer', minimum: 3 },
{
enum: ['sonar-runtime'],
},
],
},
create(context: TSESLint.RuleContext<string, string[]>) {
create(context) {
const functions: Array<{ function: FunctionNode; parent: TSESTree.Node | undefined }> = [];
const minLines: number =
typeof context.options[0] === 'number' ? context.options[0] : DEFAULT_MIN_LINES;

return {
FunctionDeclaration(node: TSESTree.Node) {
Expand Down Expand Up @@ -136,7 +143,7 @@ const rule: TSESLint.RuleModule<string, string[]> = {
const firstLine = tokens[0].loc.start.line;
const lastLine = tokens[tokens.length - 1].loc.end.line;

return lastLine - firstLine > 1;
return lastLine - firstLine + 1 >= minLines;
}

return false;
Expand Down
25 changes: 22 additions & 3 deletions tests/rules/no-identical-functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ ruleTester.run('no-identical-functions', rule, {
)
`,
},
{
code: `
const x = {
foo() {
console.log("Hello");
console.log("World");
return 42;
},
bar() {
console.log("Hello");
console.log("World");
return 42;
},
};`,
options: [4],
},
],
invalid: [
{
Expand Down Expand Up @@ -300,7 +317,7 @@ ruleTester.run('no-identical-functions', rule, {
return 42;
},
};`,
options: ['sonar-runtime'],
options: [3, 'sonar-runtime'],
errors: [
encodedMessage(3, 10, [
{ line: 3, column: 8, endLine: 3, endColumn: 11, message: 'Original implementation' },
Expand All @@ -314,17 +331,19 @@ ruleTester.run('no-identical-functions', rule, {
// ^^^^>
return [
1,
2,
];
}
function bar1() {
// ^^^^
return [
1,
2,
];
}`,
options: ['sonar-runtime'],
options: [4, 'sonar-runtime'],
errors: [
encodedMessage(2, 8, [
encodedMessage(2, 9, [
{ line: 2, column: 15, endLine: 2, endColumn: 19, message: 'Original implementation' },
]),
],
Expand Down

0 comments on commit 792914a

Please sign in to comment.