1 | const fixingNodes = new Set();
|
2 | exports.fixingNodes = fixingNodes;
|
3 |
|
4 | const findPunctuator = (targetValue, nodeOrToken, nextFunc) => (
|
5 | nodeOrToken && (
|
6 | nodeOrToken.type === 'Punctuator' && nodeOrToken.value === targetValue ?
|
7 | nodeOrToken :
|
8 | findPunctuator(targetValue, nextFunc(nodeOrToken), nextFunc)
|
9 | )
|
10 | );
|
11 |
|
12 | const getFirstChild = childrenName => node => node[childrenName][0];
|
13 | const getLastChild = childrenName => node => node[childrenName][node[childrenName].length - 1];
|
14 |
|
15 | const findOpeningBrace = (sourceCode, childrenName) =>
|
16 | node => findPunctuator('{', getFirstChild(childrenName)(node), sourceCode.getTokenBefore);
|
17 |
|
18 | const findClosingBrace = (sourceCode, childrenName) =>
|
19 | node => findPunctuator('}', getLastChild(childrenName)(node), sourceCode.getTokenAfter);
|
20 |
|
21 | exports.multilineFixer = ({
|
22 | allowSingleLine = false,
|
23 | maxChildren = 0,
|
24 | maxLen = 0,
|
25 | context,
|
26 | sourceCode,
|
27 | childrenName,
|
28 | message,
|
29 | findOpeningToken = findOpeningBrace,
|
30 | findClosingToken = findClosingBrace,
|
31 | }) => (node) => {
|
32 | const children = node[childrenName];
|
33 |
|
34 | if (allowSingleLine &&
|
35 | node.loc.start.line === node.loc.end.line &&
|
36 | (!maxChildren || children.length <= maxChildren) &&
|
37 | (!maxLen || sourceCode.lines[node.loc.end.line - 1].length < maxLen)) {
|
38 |
|
39 | return;
|
40 | }
|
41 |
|
42 | if (allowSingleLine) {
|
43 | let parent = node.parent;
|
44 | while (parent && parent.loc.start.line === node.loc.start.line) {
|
45 | if (fixingNodes.has(parent)) {
|
46 |
|
47 | return;
|
48 | }
|
49 | parent = parent.parent;
|
50 | }
|
51 | }
|
52 |
|
53 | let fixed = false;
|
54 | let prev = null;
|
55 | children.forEach((curr) => {
|
56 | if (prev && prev.loc.end.line === curr.loc.start.line) {
|
57 | context.report({
|
58 | node,
|
59 | message,
|
60 | loc: curr.loc.start,
|
61 | fix: fixer => fixer.insertTextBefore(curr, '\n'),
|
62 | });
|
63 | fixed = true;
|
64 | }
|
65 | prev = curr;
|
66 | });
|
67 |
|
68 | if (children.length) {
|
69 | const firstChild = children[0];
|
70 | const lastChild = children[children.length - 1];
|
71 | const firstToken = findOpeningToken(sourceCode, childrenName)(node);
|
72 | const lastToken = findClosingToken(sourceCode, childrenName)(node);
|
73 | if (firstToken && firstToken.loc.end.line === firstChild.loc.start.line) {
|
74 | context.report({
|
75 | node,
|
76 | message,
|
77 | loc: firstChild.loc.start,
|
78 | fix: fixer => fixer.insertTextBefore(firstChild, '\n'),
|
79 | });
|
80 | fixed = true;
|
81 | }
|
82 | if (lastToken && lastToken.loc.start.line === lastChild.loc.end.line) {
|
83 | context.report({
|
84 | node,
|
85 | message,
|
86 | loc: lastToken.loc.start,
|
87 | fix: fixer => fixer.insertTextBefore(lastToken, '\n'),
|
88 | });
|
89 | fixed = true;
|
90 | }
|
91 | }
|
92 |
|
93 | if (fixed) fixingNodes.add(node);
|
94 | };
|