UNPKG

2.76 kBJavaScriptView Raw
1const fixingNodes = new Set();
2exports.fixingNodes = fixingNodes;
3
4const findPunctuator = (targetValue, nodeOrToken, nextFunc) => (
5 nodeOrToken && (
6 nodeOrToken.type === 'Punctuator' && nodeOrToken.value === targetValue ?
7 nodeOrToken :
8 findPunctuator(targetValue, nextFunc(nodeOrToken), nextFunc)
9 )
10);
11
12const getFirstChild = childrenName => node => node[childrenName][0];
13const getLastChild = childrenName => node => node[childrenName][node[childrenName].length - 1];
14
15const findOpeningBrace = (sourceCode, childrenName) =>
16 node => findPunctuator('{', getFirstChild(childrenName)(node), sourceCode.getTokenBefore);
17
18const findClosingBrace = (sourceCode, childrenName) =>
19 node => findPunctuator('}', getLastChild(childrenName)(node), sourceCode.getTokenAfter);
20
21exports.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 // we accept one line
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 // we ignore this time as we are still in the process
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};