Skip to content

Commit 417068c

Browse files
ab-angelicaAngelica Bocanegra
andauthored
feat: add new rule enforce-line-break (#484)
* feat: add new rule enforce-line-break * feat: edit new rule enforce line break - don't add line if comments above type declaration is on the 1st line, update tests * fix: clean up code * fix: change message - enforceLineBreak Co-authored-by: Angelica Bocanegra <[email protected]>
1 parent d2f6d9b commit 417068c

File tree

7 files changed

+231
-0
lines changed

7 files changed

+231
-0
lines changed

.README/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ When `true`, only checks files with a [`@flow` annotation](http://flowtype.org/d
160160
{"gitdown": "include", "file": "./rules/boolean-style.md"}
161161
{"gitdown": "include", "file": "./rules/define-flow-type.md"}
162162
{"gitdown": "include", "file": "./rules/delimiter-dangle.md"}
163+
{"gitdown": "include", "file": "./rules/enforce-line-break.md"}
163164
{"gitdown": "include", "file": "./rules/generic-spacing.md"}
164165
{"gitdown": "include", "file": "./rules/newline-after-flow-annotation.md"}
165166
{"gitdown": "include", "file": "./rules/no-dupe-keys.md"}

.README/rules/enforce-line-break.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
### `enforce-line-break`
2+
3+
This rule enforces line breaks between type definitions.
4+
5+
<!-- assertions enforceLineBreak -->

README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* [`boolean-style`](#eslint-plugin-flowtype-rules-boolean-style)
2323
* [`define-flow-type`](#eslint-plugin-flowtype-rules-define-flow-type)
2424
* [`delimiter-dangle`](#eslint-plugin-flowtype-rules-delimiter-dangle)
25+
* [`enforce-line-break`](#eslint-plugin-flowtype-rules-enforce-line-break)
2526
* [`generic-spacing`](#eslint-plugin-flowtype-rules-generic-spacing)
2627
* [`newline-after-flow-annotation`](#eslint-plugin-flowtype-rules-newline-after-flow-annotation)
2728
* [`no-dupe-keys`](#eslint-plugin-flowtype-rules-no-dupe-keys)
@@ -1662,6 +1663,83 @@ type X = []
16621663
16631664
16641665
1666+
<a name="eslint-plugin-flowtype-rules-enforce-line-break"></a>
1667+
### <code>enforce-line-break</code>
1668+
1669+
This rule enforces line breaks between type definitions.
1670+
1671+
The following patterns are considered problems:
1672+
1673+
```js
1674+
type baz = 6;
1675+
const hi = 2;
1676+
// Message: New line required below type declaration
1677+
1678+
const foo = 6;
1679+
type hi = 2;
1680+
1681+
// Message: New line required above type declaration
1682+
1683+
const som = "jes";
1684+
// a comment
1685+
type fed = "hed";
1686+
1687+
// Message: New line required above type declaration
1688+
1689+
type som = "jes";
1690+
// a comment
1691+
const fed = "hed";
1692+
1693+
// Message: New line required below type declaration
1694+
1695+
type hello = 34;
1696+
const som = "jes";
1697+
type fed = "hed";
1698+
1699+
// Message: New line required below type declaration
1700+
// Message: New line required above type declaration
1701+
```
1702+
1703+
The following patterns are not considered problems:
1704+
1705+
```js
1706+
type gjs = 6;
1707+
1708+
type gjs = 6;
1709+
1710+
type hi = 2;
1711+
1712+
1713+
type X = 4;
1714+
1715+
const red = "serpent";
1716+
console.log("hello");
1717+
1718+
// number or string
1719+
type Y = string | number;
1720+
1721+
// resting + sleep
1722+
type snooze = "dreaming" | "";
1723+
1724+
type Props = {
1725+
accountBalance: string | number,
1726+
accountNumber: string | number,
1727+
};
1728+
1729+
const x = 4;
1730+
const y = 489;
1731+
1732+
// Some Comment
1733+
type Props = {
1734+
accountBalance: string | number,
1735+
accountNumber: string | number,
1736+
};
1737+
1738+
type RoadT = "grass" | "gravel" | "cement";
1739+
```
1740+
1741+
1742+
16651743
<a name="eslint-plugin-flowtype-rules-generic-spacing"></a>
16661744
### <code>generic-spacing</code>
16671745

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import arrayStyleSimpleType from './rules/arrayStyleSimpleType';
66
import booleanStyle from './rules/booleanStyle';
77
import defineFlowType from './rules/defineFlowType';
88
import delimiterDangle from './rules/delimiterDangle';
9+
import enforceLineBreak from './rules/enforceLineBreak';
910
import genericSpacing from './rules/genericSpacing';
1011
import newlineAfterFlowAnnotation from './rules/newlineAfterFlowAnnotation';
1112
import noDupeKeys from './rules/noDupeKeys';
@@ -53,6 +54,7 @@ const rules = {
5354
'boolean-style': booleanStyle,
5455
'define-flow-type': defineFlowType,
5556
'delimiter-dangle': delimiterDangle,
57+
'enforce-line-break': enforceLineBreak,
5658
'generic-spacing': genericSpacing,
5759
'newline-after-flow-annotation': newlineAfterFlowAnnotation,
5860
'no-dupe-keys': noDupeKeys,

src/rules/enforceLineBreak.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const schema = [];
2+
3+
const breakLineMessage = (direction) => {
4+
return `New line required ${direction} type declaration`;
5+
};
6+
7+
const create = (context) => {
8+
return {
9+
TypeAlias (node) {
10+
const sourceCode = context.getSourceCode();
11+
if (sourceCode.lines.length === 1) {
12+
return;
13+
}
14+
15+
if (node.loc.start.line !== 1) {
16+
if (node.leadingComments && node.leadingComments[0].loc.start.line !== 1) {
17+
const lineAboveComment = sourceCode.lines[node.leadingComments[0].loc.start.line - 2];
18+
if (lineAboveComment !== '') {
19+
context.report({
20+
fix (fixer) {
21+
return fixer.insertTextBeforeRange(node.leadingComments[0].range, '\n');
22+
},
23+
message: breakLineMessage('above'),
24+
node,
25+
});
26+
}
27+
} else if (!node.leadingComments) {
28+
const isLineAbove = sourceCode.lines[node.loc.start.line - 2];
29+
if (isLineAbove !== '') {
30+
context.report({
31+
fix (fixer) {
32+
return fixer.insertTextBefore(node, '\n');
33+
},
34+
message: breakLineMessage('above'),
35+
node,
36+
});
37+
}
38+
}
39+
}
40+
41+
if (sourceCode.lines.length !== node.loc.end.line) {
42+
const isLineBelow = sourceCode.lines[node.loc.end.line];
43+
if (isLineBelow !== '') {
44+
context.report({
45+
fix (fixer) {
46+
return fixer.insertTextAfter(node, '\n');
47+
},
48+
message: breakLineMessage('below'),
49+
node,
50+
});
51+
}
52+
}
53+
},
54+
};
55+
};
56+
57+
export default {
58+
create,
59+
meta: {
60+
fixable: 'code',
61+
},
62+
schema,
63+
};
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
export default {
2+
invalid: [
3+
{
4+
code: 'type baz = 6;\nconst hi = 2;',
5+
errors: [{
6+
message: 'New line required below type declaration',
7+
}],
8+
output: 'type baz = 6;\n\nconst hi = 2;',
9+
},
10+
{
11+
code: 'const foo = 6;\ntype hi = 2;\n',
12+
errors: [
13+
{message: 'New line required above type declaration'},
14+
],
15+
output: 'const foo = 6;\n\ntype hi = 2;\n',
16+
},
17+
{
18+
code: 'const som = "jes";\n// a comment\ntype fed = "hed";\n',
19+
errors: [
20+
{message: 'New line required above type declaration'},
21+
],
22+
output: 'const som = "jes";\n\n// a comment\ntype fed = "hed";\n',
23+
},
24+
{
25+
code: 'type som = "jes";\n// a comment\nconst fed = "hed";\n',
26+
errors: [
27+
{message: 'New line required below type declaration'},
28+
],
29+
output: 'type som = "jes";\n\n// a comment\nconst fed = "hed";\n',
30+
},
31+
{
32+
code: 'type hello = 34;\nconst som = "jes";\ntype fed = "hed";\n',
33+
errors: [
34+
{message: 'New line required below type declaration'},
35+
{message: 'New line required above type declaration'},
36+
],
37+
output: 'type hello = 34;\n\nconst som = "jes";\n\ntype fed = "hed";\n',
38+
},
39+
],
40+
valid: [
41+
{
42+
code: 'type gjs = 6;',
43+
},
44+
{
45+
code: 'type gjs = 6;\n\ntype hi = 2;\n',
46+
},
47+
{
48+
code:
49+
`type X = 4;
50+
51+
const red = "serpent";
52+
console.log("hello");
53+
54+
// number or string
55+
type Y = string | number;
56+
57+
// resting + sleep
58+
type snooze = "dreaming" | "";`,
59+
},
60+
{
61+
code:
62+
`type Props = {
63+
accountBalance: string | number,
64+
accountNumber: string | number,
65+
};`,
66+
},
67+
{
68+
code:
69+
`const x = 4;
70+
const y = 489;
71+
72+
// Some Comment
73+
type Props = {
74+
accountBalance: string | number,
75+
accountNumber: string | number,
76+
};
77+
78+
type RoadT = "grass" | "gravel" | "cement";`,
79+
},
80+
],
81+
};

tests/rules/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const reportingRules = [
1717
'boolean-style',
1818
'define-flow-type',
1919
'delimiter-dangle',
20+
'enforce-line-break',
2021
'generic-spacing',
2122
'newline-after-flow-annotation',
2223
'no-dupe-keys',

0 commit comments

Comments
 (0)