eslint-plugin-jest-formatting 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +2 -2
- package/.eslintrc +15 -4
- package/CHANGELOG.md +28 -6
- package/README.md +21 -13
- package/docs/rules/padding-around-all.md +13 -0
- package/lib/ast-utils.js +41 -0
- package/lib/index.js +159 -76
- package/lib/rules/padding.js +131 -158
- package/package.json +20 -19
- package/src/ast-utils.ts +80 -0
- package/src/index.ts +166 -81
- package/src/rules/padding.ts +263 -252
- package/tests/catfood.js +41 -0
- package/tests/dogfood.spec.js +2 -0
- package/tests/lib/ast-utils.spec.ts +94 -0
- package/tests/lib/rules/padding-around-after-all-blocks.spec.js +3 -8
- package/tests/lib/rules/padding-around-after-each-blocks.spec.js +3 -8
- package/tests/lib/rules/padding-around-before-all-blocks.spec.js +3 -8
- package/tests/lib/rules/padding-around-before-each-blocks.spec.js +3 -8
- package/tests/lib/rules/padding-around-describe-blocks.spec.js +7 -12
- package/tests/lib/rules/padding-around-expect-groups.spec.js +3 -8
- package/tests/lib/rules/padding-around-test-blocks.spec.js +15 -12
- package/tsconfig.json +1 -1
- package/lib/utils.js +0 -15
- package/src/utils.ts +0 -40
- package/tests/lib/rules/padding-before-after-all-blocks.spec.js +0 -104
- package/tests/lib/rules/padding-before-after-each-blocks.spec.js +0 -104
- package/tests/lib/rules/padding-before-before-all-blocks.spec.js +0 -104
- package/tests/lib/rules/padding-before-before-each-blocks.spec.js +0 -104
- package/tests/lib/rules/padding-before-describe-blocks.spec.js +0 -150
- package/tests/lib/rules/padding-before-expect-statements.spec.js +0 -144
- package/tests/lib/rules/padding-before-test-blocks.spec.js +0 -159
- package/yarn.lock +0 -4232
package/lib/rules/padding.js
CHANGED
|
@@ -1,190 +1,163 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
exports.createRule = exports.PaddingType = exports.StatementType = void 0;
|
|
4
|
+
const astUtils = require("../ast-utils");
|
|
5
|
+
var StatementType;
|
|
6
|
+
(function (StatementType) {
|
|
7
|
+
StatementType[StatementType["Any"] = 0] = "Any";
|
|
8
|
+
StatementType[StatementType["AfterAllToken"] = 1] = "AfterAllToken";
|
|
9
|
+
StatementType[StatementType["AfterEachToken"] = 2] = "AfterEachToken";
|
|
10
|
+
StatementType[StatementType["BeforeAllToken"] = 3] = "BeforeAllToken";
|
|
11
|
+
StatementType[StatementType["BeforeEachToken"] = 4] = "BeforeEachToken";
|
|
12
|
+
StatementType[StatementType["DescribeToken"] = 5] = "DescribeToken";
|
|
13
|
+
StatementType[StatementType["ExpectToken"] = 6] = "ExpectToken";
|
|
14
|
+
StatementType[StatementType["FdescribeToken"] = 7] = "FdescribeToken";
|
|
15
|
+
StatementType[StatementType["FitToken"] = 8] = "FitToken";
|
|
16
|
+
StatementType[StatementType["ItToken"] = 9] = "ItToken";
|
|
17
|
+
StatementType[StatementType["TestToken"] = 10] = "TestToken";
|
|
18
|
+
StatementType[StatementType["XdescribeToken"] = 11] = "XdescribeToken";
|
|
19
|
+
StatementType[StatementType["XitToken"] = 12] = "XitToken";
|
|
20
|
+
StatementType[StatementType["XtestToken"] = 13] = "XtestToken";
|
|
21
|
+
})(StatementType = exports.StatementType || (exports.StatementType = {}));
|
|
22
|
+
var PaddingType;
|
|
23
|
+
(function (PaddingType) {
|
|
24
|
+
PaddingType[PaddingType["Any"] = 0] = "Any";
|
|
25
|
+
PaddingType[PaddingType["Always"] = 1] = "Always";
|
|
26
|
+
})(PaddingType = exports.PaddingType || (exports.PaddingType = {}));
|
|
27
|
+
const createTokenTester = (tokenName) => {
|
|
28
|
+
return (node, sourceCode) => {
|
|
29
|
+
const token = sourceCode.getFirstToken(node);
|
|
30
|
+
return (node.type === 'ExpressionStatement' &&
|
|
31
|
+
token.type === 'Identifier' &&
|
|
32
|
+
token.value === tokenName);
|
|
20
33
|
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
};
|
|
35
|
+
const statementTesters = {
|
|
36
|
+
[0]: () => true,
|
|
37
|
+
[1]: createTokenTester('afterAll'),
|
|
38
|
+
[2]: createTokenTester('afterEach'),
|
|
39
|
+
[3]: createTokenTester('beforeAll'),
|
|
40
|
+
[4]: createTokenTester('beforeEach'),
|
|
41
|
+
[5]: createTokenTester('describe'),
|
|
42
|
+
[6]: createTokenTester('expect'),
|
|
43
|
+
[7]: createTokenTester('fdescribe'),
|
|
44
|
+
[8]: createTokenTester('fit'),
|
|
45
|
+
[9]: createTokenTester('it'),
|
|
46
|
+
[10]: createTokenTester('test'),
|
|
47
|
+
[11]: createTokenTester('xdescribe'),
|
|
48
|
+
[12]: createTokenTester('xit'),
|
|
49
|
+
[13]: createTokenTester('xtest'),
|
|
50
|
+
};
|
|
51
|
+
const paddingAlwaysTester = (prevNode, nextNode, paddingContext) => {
|
|
52
|
+
const { sourceCode, ruleContext } = paddingContext;
|
|
53
|
+
const paddingLines = astUtils.getPaddingLineSequences(prevNode, nextNode, sourceCode);
|
|
35
54
|
if (paddingLines.length > 0) {
|
|
36
55
|
return;
|
|
37
56
|
}
|
|
38
|
-
|
|
57
|
+
ruleContext.report({
|
|
39
58
|
node: nextNode,
|
|
40
59
|
message: 'Expected blank line before this statement.',
|
|
41
60
|
fix(fixer) {
|
|
42
|
-
|
|
43
|
-
let prevToken = getActualLastToken(sourceCode, prevNode);
|
|
61
|
+
let prevToken = astUtils.getActualLastToken(sourceCode, prevNode);
|
|
44
62
|
const nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, {
|
|
45
63
|
includeComments: true,
|
|
46
64
|
filter(token) {
|
|
47
|
-
if (
|
|
65
|
+
if (astUtils.areTokensOnSameLine(prevToken, token)) {
|
|
48
66
|
prevToken = token;
|
|
49
67
|
return false;
|
|
50
68
|
}
|
|
51
69
|
return true;
|
|
52
70
|
},
|
|
53
71
|
}) || nextNode;
|
|
54
|
-
const insertText =
|
|
72
|
+
const insertText = astUtils.areTokensOnSameLine(prevToken, nextToken)
|
|
55
73
|
? '\n\n'
|
|
56
74
|
: '\n';
|
|
57
75
|
return fixer.insertTextAfter(prevToken, insertText);
|
|
58
76
|
},
|
|
59
77
|
});
|
|
60
|
-
}
|
|
61
|
-
const PaddingTypes = {
|
|
62
|
-
any: { verify: () => { } },
|
|
63
|
-
always: { verify: verifyForAlways },
|
|
64
78
|
};
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
afterEach: newJestTokenTester('afterEach'),
|
|
69
|
-
beforeAll: newJestTokenTester('beforeAll'),
|
|
70
|
-
beforeEach: newJestTokenTester('beforeEach'),
|
|
71
|
-
describe: newJestTokenTester('describe'),
|
|
72
|
-
expect: newJestTokenTester('expect'),
|
|
73
|
-
it: newJestTokenTester('it'),
|
|
74
|
-
test: newJestTokenTester('test'),
|
|
79
|
+
const paddingTesters = {
|
|
80
|
+
[0]: () => true,
|
|
81
|
+
[1]: paddingAlwaysTester,
|
|
75
82
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
enum: Object.keys(PaddingTypes),
|
|
83
|
-
},
|
|
84
|
-
statementType: {
|
|
85
|
-
anyOf: [
|
|
86
|
-
{ enum: Object.keys(StatementTypes) },
|
|
87
|
-
{
|
|
88
|
-
type: 'array',
|
|
89
|
-
items: { enum: Object.keys(StatementTypes) },
|
|
90
|
-
minItems: 1,
|
|
91
|
-
uniqueItems: true,
|
|
92
|
-
additionalItems: false,
|
|
93
|
-
},
|
|
94
|
-
],
|
|
95
|
-
},
|
|
83
|
+
const createScopeInfo = () => {
|
|
84
|
+
return (() => {
|
|
85
|
+
let scope = null;
|
|
86
|
+
return {
|
|
87
|
+
get prevNode() {
|
|
88
|
+
return scope.prevNode;
|
|
96
89
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
type: 'object',
|
|
100
|
-
properties: {
|
|
101
|
-
blankLine: { $ref: '#/definitions/paddingType' },
|
|
102
|
-
prev: { $ref: '#/definitions/statementType' },
|
|
103
|
-
next: { $ref: '#/definitions/statementType' },
|
|
104
|
-
},
|
|
105
|
-
additionalProperties: false,
|
|
106
|
-
required: ['blankLine', 'prev', 'next'],
|
|
90
|
+
set prevNode(node) {
|
|
91
|
+
scope.prevNode = node;
|
|
107
92
|
},
|
|
108
|
-
|
|
109
|
-
|
|
93
|
+
enter() {
|
|
94
|
+
scope = { upper: scope, prevNode: null };
|
|
95
|
+
},
|
|
96
|
+
exit() {
|
|
97
|
+
scope = scope.upper;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
})();
|
|
101
|
+
};
|
|
102
|
+
const nodeMatchesType = (node, statementType, paddingContext) => {
|
|
103
|
+
let innerStatementNode = node;
|
|
104
|
+
const { sourceCode } = paddingContext;
|
|
105
|
+
while (innerStatementNode.type === 'LabeledStatement') {
|
|
106
|
+
innerStatementNode = innerStatementNode.body;
|
|
107
|
+
}
|
|
108
|
+
if (Array.isArray(statementType)) {
|
|
109
|
+
return statementType.some((type) => nodeMatchesType(innerStatementNode, type, paddingContext));
|
|
110
|
+
}
|
|
111
|
+
return statementTesters[statementType](innerStatementNode, sourceCode);
|
|
112
|
+
};
|
|
113
|
+
const testPadding = (prevNode, nextNode, paddingContext) => {
|
|
114
|
+
const { configs } = paddingContext;
|
|
115
|
+
const testType = (type) => paddingTesters[type](prevNode, nextNode, paddingContext);
|
|
116
|
+
for (let i = configs.length - 1; i >= 0; --i) {
|
|
117
|
+
const { prevStatementType: prevType, nextStatementType: nextType, paddingType, } = configs[i];
|
|
118
|
+
if (nodeMatchesType(prevNode, prevType, paddingContext) &&
|
|
119
|
+
nodeMatchesType(nextNode, nextType, paddingContext)) {
|
|
120
|
+
return testType(paddingType);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return testType(0);
|
|
124
|
+
};
|
|
125
|
+
const verifyNode = (node, paddingContext) => {
|
|
126
|
+
const { scopeInfo } = paddingContext;
|
|
127
|
+
if (!astUtils.isValidParent(node.parent.type)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (scopeInfo.prevNode) {
|
|
131
|
+
testPadding(scopeInfo.prevNode, node, paddingContext);
|
|
132
|
+
}
|
|
133
|
+
scopeInfo.prevNode = node;
|
|
134
|
+
};
|
|
135
|
+
exports.createRule = (configs, deprecated = false) => ({
|
|
136
|
+
meta: {
|
|
137
|
+
fixable: 'whitespace',
|
|
138
|
+
deprecated,
|
|
110
139
|
},
|
|
111
140
|
create(context) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function enterScope() {
|
|
120
|
-
scopeInfo = { upper: scopeInfo, prevNode: null };
|
|
121
|
-
}
|
|
122
|
-
function exitScope() {
|
|
123
|
-
scopeInfo = scopeInfo.upper;
|
|
124
|
-
}
|
|
125
|
-
function match(node, type) {
|
|
126
|
-
let innerStatementNode = node;
|
|
127
|
-
while (innerStatementNode.type === 'LabeledStatement') {
|
|
128
|
-
innerStatementNode = innerStatementNode.body;
|
|
129
|
-
}
|
|
130
|
-
if (Array.isArray(type)) {
|
|
131
|
-
return type.some(match.bind(null, innerStatementNode));
|
|
132
|
-
}
|
|
133
|
-
return StatementTypes[type].test(innerStatementNode, sourceCode);
|
|
134
|
-
}
|
|
135
|
-
function getPaddingType(prevNode, nextNode) {
|
|
136
|
-
for (let i = configureList.length - 1; i >= 0; --i) {
|
|
137
|
-
const { prev, next, blankLine } = configureList[i];
|
|
138
|
-
if (match(prevNode, prev) && match(nextNode, next)) {
|
|
139
|
-
return PaddingTypes[blankLine];
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return PaddingTypes.any;
|
|
143
|
-
}
|
|
144
|
-
function getPaddingLineSequences(prevNode, nextNode) {
|
|
145
|
-
const pairs = [];
|
|
146
|
-
let prevToken = getActualLastToken(sourceCode, prevNode);
|
|
147
|
-
if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
|
|
148
|
-
do {
|
|
149
|
-
const token = sourceCode.getTokenAfter(prevToken, {
|
|
150
|
-
includeComments: true,
|
|
151
|
-
});
|
|
152
|
-
if (token.loc.start.line - prevToken.loc.end.line >= 2) {
|
|
153
|
-
pairs.push([prevToken, token]);
|
|
154
|
-
}
|
|
155
|
-
prevToken = token;
|
|
156
|
-
} while (prevToken.range[0] < nextNode.range[0]);
|
|
157
|
-
}
|
|
158
|
-
return pairs;
|
|
159
|
-
}
|
|
160
|
-
function verify(node) {
|
|
161
|
-
const parentType = node.parent.type;
|
|
162
|
-
const validParent = STATEMENT_LIST_PARENTS.has(parentType);
|
|
163
|
-
if (!validParent) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
const { prevNode } = scopeInfo;
|
|
167
|
-
if (prevNode) {
|
|
168
|
-
const type = getPaddingType(prevNode, node);
|
|
169
|
-
const paddingLines = getPaddingLineSequences(prevNode, node);
|
|
170
|
-
type.verify(context, prevNode, node, paddingLines);
|
|
171
|
-
}
|
|
172
|
-
scopeInfo.prevNode = node;
|
|
173
|
-
}
|
|
174
|
-
function verifyThenEnterScope(node) {
|
|
175
|
-
verify(node);
|
|
176
|
-
enterScope();
|
|
177
|
-
}
|
|
141
|
+
const paddingContext = {
|
|
142
|
+
ruleContext: context,
|
|
143
|
+
sourceCode: context.getSourceCode(),
|
|
144
|
+
scopeInfo: createScopeInfo(),
|
|
145
|
+
configs,
|
|
146
|
+
};
|
|
147
|
+
const { scopeInfo } = paddingContext;
|
|
178
148
|
return {
|
|
179
|
-
Program:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
'
|
|
183
|
-
|
|
184
|
-
'SwitchStatement:exit':
|
|
185
|
-
':statement':
|
|
186
|
-
SwitchCase:
|
|
187
|
-
|
|
149
|
+
Program: scopeInfo.enter,
|
|
150
|
+
'Program:exit': scopeInfo.enter,
|
|
151
|
+
BlockStatement: scopeInfo.enter,
|
|
152
|
+
'BlockStatement:exit': scopeInfo.exit,
|
|
153
|
+
SwitchStatement: scopeInfo.enter,
|
|
154
|
+
'SwitchStatement:exit': scopeInfo.exit,
|
|
155
|
+
':statement': (node) => verifyNode(node, paddingContext),
|
|
156
|
+
SwitchCase: (node) => {
|
|
157
|
+
verifyNode(node, paddingContext);
|
|
158
|
+
scopeInfo.enter();
|
|
159
|
+
},
|
|
160
|
+
'SwitchCase:exit': scopeInfo.exit,
|
|
188
161
|
};
|
|
189
162
|
},
|
|
190
|
-
};
|
|
163
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-jest-formatting",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Formatting rules for jest tests",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"module": "src/index.ts",
|
|
21
21
|
"scripts": {
|
|
22
22
|
"pretty": "yarn prettier '**/*.*'",
|
|
23
|
-
"lint": "yarn build && yarn link-plugin && yarn pretty --check && yarn eslint .",
|
|
24
|
-
"format": "yarn build && yarn link-plugin && yarn pretty --write && yarn eslint --fix .",
|
|
23
|
+
"lint": "yarn build && yarn link-plugin && yarn pretty --check && yarn eslint --ext .ts,.js .",
|
|
24
|
+
"format": "yarn build && yarn link-plugin && yarn pretty --write && yarn eslint --fix --ext .ts,.js .",
|
|
25
25
|
"build": "tsc",
|
|
26
26
|
"test": "yarn build && jest",
|
|
27
27
|
"link-plugin": "yarn link && yarn link eslint-plugin-jest-formatting"
|
|
@@ -30,25 +30,26 @@
|
|
|
30
30
|
"eslint": ">=0.8.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@types/eslint": "
|
|
34
|
-
"@types/
|
|
35
|
-
"@types/
|
|
36
|
-
"@
|
|
37
|
-
"@typescript-eslint/parser": "
|
|
38
|
-
"eslint": "
|
|
39
|
-
"eslint-config-airbnb-base": "
|
|
40
|
-
"eslint-config-prettier": "
|
|
41
|
-
"eslint-
|
|
42
|
-
"eslint-plugin-
|
|
33
|
+
"@types/eslint": "^7.2.0",
|
|
34
|
+
"@types/jest": "^26.0.0",
|
|
35
|
+
"@types/node": "^14.0.13",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^3.4.0",
|
|
37
|
+
"@typescript-eslint/parser": "^3.4.0",
|
|
38
|
+
"eslint": "^7.3.1",
|
|
39
|
+
"eslint-config-airbnb-base": "^14.2.0",
|
|
40
|
+
"eslint-config-prettier": "^6.11.0",
|
|
41
|
+
"eslint-import-resolver-typescript": "^2.0.0",
|
|
42
|
+
"eslint-plugin-import": "^2.21.2",
|
|
43
|
+
"eslint-plugin-jest": "^23.17.1",
|
|
43
44
|
"eslint-plugin-jest-formatting": "file:.",
|
|
44
|
-
"eslint-plugin-prettier": "3.1.
|
|
45
|
-
"jest": "
|
|
46
|
-
"prettier": "
|
|
47
|
-
"typescript": "3.
|
|
48
|
-
"ts-jest": "
|
|
45
|
+
"eslint-plugin-prettier": "^3.1.4",
|
|
46
|
+
"jest": "^26.1.0",
|
|
47
|
+
"prettier": "2.0.5",
|
|
48
|
+
"typescript": "^3.9.5",
|
|
49
|
+
"ts-jest": "^26.1.1"
|
|
49
50
|
},
|
|
50
51
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
52
|
+
"node": "^10.12.0 || >=12.0.0"
|
|
52
53
|
},
|
|
53
54
|
"license": "MIT"
|
|
54
55
|
}
|
package/src/ast-utils.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { AST, SourceCode } from 'eslint';
|
|
2
|
+
// This is because we are using @types/estree that are brought in with eslint
|
|
3
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
4
|
+
import { Node } from 'estree';
|
|
5
|
+
|
|
6
|
+
export const isTokenASemicolon = (token: AST.Token): boolean =>
|
|
7
|
+
token.value === ';' && token.type === 'Punctuator';
|
|
8
|
+
|
|
9
|
+
export const areTokensOnSameLine = (
|
|
10
|
+
left: Node | AST.Token,
|
|
11
|
+
right: Node | AST.Token,
|
|
12
|
+
): boolean => left.loc.end.line === right.loc.start.line;
|
|
13
|
+
|
|
14
|
+
// We'll only verify nodes with these parent types
|
|
15
|
+
const STATEMENT_LIST_PARENTS = new Set([
|
|
16
|
+
'Program',
|
|
17
|
+
'BlockStatement',
|
|
18
|
+
'SwitchCase',
|
|
19
|
+
'SwitchStatement',
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
export const isValidParent = (parentType: string): boolean => {
|
|
23
|
+
return STATEMENT_LIST_PARENTS.has(parentType);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Gets the actual last token.
|
|
28
|
+
*
|
|
29
|
+
* If a semicolon is semicolon-less style's semicolon, this ignores it.
|
|
30
|
+
* For example:
|
|
31
|
+
*
|
|
32
|
+
* foo()
|
|
33
|
+
* ;[1, 2, 3].forEach(bar)
|
|
34
|
+
*/
|
|
35
|
+
export const getActualLastToken = (
|
|
36
|
+
sourceCode: SourceCode,
|
|
37
|
+
node: Node,
|
|
38
|
+
): AST.Token => {
|
|
39
|
+
const semiToken = sourceCode.getLastToken(node);
|
|
40
|
+
const prevToken = sourceCode.getTokenBefore(semiToken);
|
|
41
|
+
const nextToken = sourceCode.getTokenAfter(semiToken);
|
|
42
|
+
const isSemicolonLessStyle = Boolean(
|
|
43
|
+
prevToken &&
|
|
44
|
+
nextToken &&
|
|
45
|
+
prevToken.range[0] >= node.range[0] &&
|
|
46
|
+
isTokenASemicolon(semiToken) &&
|
|
47
|
+
semiToken.loc.start.line !== prevToken.loc.end.line &&
|
|
48
|
+
semiToken.loc.end.line === nextToken.loc.start.line,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return isSemicolonLessStyle ? prevToken : semiToken;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets padding line sequences between the given 2 statements.
|
|
56
|
+
* Comments are separators of the padding line sequences.
|
|
57
|
+
*/
|
|
58
|
+
export const getPaddingLineSequences = (
|
|
59
|
+
prevNode: Node,
|
|
60
|
+
nextNode: Node,
|
|
61
|
+
sourceCode: SourceCode,
|
|
62
|
+
): AST.Token[][] => {
|
|
63
|
+
const pairs: AST.Token[][] = [];
|
|
64
|
+
const includeComments = true;
|
|
65
|
+
let prevToken = getActualLastToken(sourceCode, prevNode);
|
|
66
|
+
|
|
67
|
+
if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
|
|
68
|
+
do {
|
|
69
|
+
const token = sourceCode.getTokenAfter(prevToken, { includeComments });
|
|
70
|
+
|
|
71
|
+
if (token.loc.start.line - prevToken.loc.end.line >= 2) {
|
|
72
|
+
pairs.push([prevToken, token]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
prevToken = token;
|
|
76
|
+
} while (prevToken.range[0] < nextNode.range[0]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return pairs;
|
|
80
|
+
};
|