Skip to content

Commit d96a09e

Browse files
authored
Chain behaviour closer to prettier core (#560)
* new chain behaviour is decoupled from the format of the first element of the chain * a nicer way to do this filter * documentation changes * removing extra 'and'
1 parent b488f73 commit d96a09e

6 files changed

Lines changed: 128 additions & 191 deletions

File tree

src/nodes/FunctionCall.js

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,41 @@
11
const {
22
doc: {
3-
builders: { label, line, softline }
3+
builders: { line, softline }
44
}
55
} = require('prettier');
66

77
const printSeparatedList = require('./print-separated-list');
88

9-
let functionCallId = 0;
10-
11-
const printObject = (node, path, print, options, groupId) => [
9+
const printObject = (node, path, print, options) => [
1210
'{',
1311
printSeparatedList(
1412
path
1513
.map(print, 'arguments')
1614
.map((arg, index) => [node.names[index], ': ', arg]),
1715
{
18-
groupId,
1916
firstSeparator: options.bracketSpacing ? line : softline,
2017
lastSeparator: [options.bracketSpacing ? line : softline, '})']
2118
}
2219
)
2320
];
2421

25-
const printArguments = (path, print, groupId) =>
22+
const printArguments = (path, print) =>
2623
printSeparatedList(path.map(print, 'arguments'), {
27-
groupId,
2824
lastSeparator: [softline, ')']
2925
});
3026

3127
const FunctionCall = {
3228
print: ({ node, path, print, options }) => {
3329
let argumentsDoc = ')';
34-
const functionCallLabel = { type: 'FunctionCall', groupId: null };
3530
if (node.arguments && node.arguments.length > 0) {
36-
functionCallLabel.groupId = `FunctionCall-${functionCallId}`;
37-
functionCallId += 1;
3831
if (node.names && node.names.length > 0) {
39-
argumentsDoc = printObject(
40-
node,
41-
path,
42-
print,
43-
options,
44-
functionCallLabel.groupId
45-
);
32+
argumentsDoc = printObject(node, path, print, options);
4633
} else {
47-
argumentsDoc = printArguments(path, print, functionCallLabel.groupId);
34+
argumentsDoc = printArguments(path, print);
4835
}
4936
}
5037

51-
return label(JSON.stringify(functionCallLabel), [
52-
path.call(print, 'expression'),
53-
'(',
54-
argumentsDoc
55-
]);
38+
return [path.call(print, 'expression'), '(', argumentsDoc];
5639
}
5740
};
5841

src/nodes/IndexAccess.js

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
11
const {
22
doc: {
3-
builders: { group, indent, label, softline }
3+
builders: { group, indent, softline }
44
}
55
} = require('prettier');
66

7-
let indexAccessId = 0;
8-
97
const IndexAccess = {
10-
print: ({ path, print }) => {
11-
const indexAccessLabel = {
12-
type: 'IndexAccess',
13-
groupId: `IndexAccess-${indexAccessId}`
14-
};
15-
indexAccessId += 1;
16-
17-
return label(JSON.stringify(indexAccessLabel), [
18-
path.call(print, 'base'),
19-
'[',
20-
group([indent([softline, path.call(print, 'index')]), softline], {
21-
id: indexAccessLabel.groupId
22-
}),
23-
']'
24-
]);
25-
}
8+
print: ({ path, print }) => [
9+
path.call(print, 'base'),
10+
'[',
11+
group([indent([softline, path.call(print, 'index')]), softline, ']'])
12+
]
2613
};
2714

2815
module.exports = IndexAccess;

src/nodes/MemberAccess.js

Lines changed: 22 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const {
22
doc: {
3-
builders: { group, ifBreak, indent, label, softline }
3+
builders: { group, indent, label, softline }
44
}
55
} = require('prettier');
66

@@ -55,15 +55,22 @@ const isEndOfChain = (node, path) => {
5555
* first separator.
5656
* The second array contains the rest of the chain.
5757
*
58-
* The indentation of the whole chain depends on the result of the first
59-
* element.
58+
* The second array is grouped and indented, while the first element's
59+
* formatting logic remains separated.
6060
*
61-
* If the first element breaks into multiple lines, we won't indent the rest of
62-
* the chain as the last line (most likely a closing parentheses) won't be
63-
* indented.
61+
* That way the first element can safely split into multiple lines and the rest
62+
* of the chain will continue its formatting rules as normal.
6463
*
6564
* i.e.
6665
* ```
66+
* functionCall(arg1, arg2).rest.of.chain
67+
*
68+
* functionCall(arg1, arg2)
69+
* .long
70+
* .rest
71+
* .of
72+
* .chain
73+
*
6774
* functionCall(
6875
* arg1,
6976
* arg2
@@ -73,21 +80,6 @@ const isEndOfChain = (node, path) => {
7380
* arg1,
7481
* arg2
7582
* )
76-
* .long
77-
* .rest
78-
* .of
79-
* .chain
80-
* ```
81-
*
82-
* If the first element doesn't break into multiple lines we treat the rest of
83-
* the chain as a normal chain and proceed to indent it.
84-
*
85-
*
86-
* i.e.
87-
* ```
88-
* a = functionCall(arg1, arg2).rest.of.chain
89-
*
90-
* b = functionCall(arg1, arg2)
9183
* .long
9284
* .rest
9385
* .of
@@ -102,51 +94,31 @@ const isEndOfChain = (node, path) => {
10294
* be printed.
10395
*/
10496
const processChain = (chain) => {
105-
const firstSeparatorIndex = chain.findIndex((element) => {
106-
if (element.label) {
107-
return JSON.parse(element.label).type === 'separator';
108-
}
109-
return false;
110-
});
111-
// We fetch the groupId from the firstSeparator
112-
const { groupId } = JSON.parse(chain[firstSeparatorIndex].label);
97+
const firstSeparatorIndex = chain.findIndex(
98+
(element) => element.label === 'separator'
99+
);
113100
// The doc[] before the first separator
114101
const firstExpression = chain.slice(0, firstSeparatorIndex);
115102
// The doc[] containing the rest of the chain
116-
const restOfChain = group(chain.slice(firstSeparatorIndex));
103+
const restOfChain = group(indent(chain.slice(firstSeparatorIndex)));
117104

118-
return groupId
119-
? [
120-
...firstExpression,
121-
ifBreak(restOfChain, indent(restOfChain), { groupId })
122-
]
123-
: [...firstExpression, indent(restOfChain)];
105+
return group([firstExpression, restOfChain]);
124106
};
125107

126108
const MemberAccess = {
127109
print: ({ node, path, print }) => {
128110
let expressionDoc = path.call(print, 'expression');
129-
const separatorLabel = {
130-
type: 'separator'
131-
};
132-
133-
if (expressionDoc.label) {
134-
const labelData = JSON.parse(expressionDoc.label);
135-
if (labelData && labelData.groupId) {
136-
// if there's a groupId in the data, we pass it to the separator as
137-
// this doc[] is going to be stripped of it's metadata
138-
separatorLabel.groupId = labelData.groupId;
139-
}
140-
expressionDoc = expressionDoc.contents.flat();
111+
if (Array.isArray(expressionDoc)) {
112+
expressionDoc = expressionDoc.flat();
141113
}
142114

143115
const doc = [
144116
expressionDoc,
145-
label(JSON.stringify(separatorLabel), [softline, '.']),
117+
label('separator', [softline, '.']),
146118
node.memberName
147119
].flat();
148120

149-
return isEndOfChain(node, path) ? group(processChain(doc)) : doc;
121+
return isEndOfChain(node, path) ? processChain(doc) : doc;
150122
}
151123
};
152124

src/nodes/print-comments.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const printComments = (node, path, options, filter = () => true) =>
2020
comment.printed = true;
2121
return options.printer.printComment(commentPath);
2222
}, 'comments')
23-
.filter((element) => element)
23+
.filter(Boolean)
2424
)
2525
: '';
2626

src/nodes/print-separated-list.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,9 @@ const {
1414
const printSeparatedList = (
1515
list,
1616
{
17-
groupId,
1817
firstSeparator = softline,
1918
separator = [',', line],
2019
lastSeparator = firstSeparator
2120
} = {}
22-
) =>
23-
group(
24-
[indent([firstSeparator, join(separator, list)]), lastSeparator],
25-
groupId ? { id: groupId } : {}
26-
);
21+
) => group([indent([firstSeparator, join(separator, list)]), lastSeparator]);
2722
module.exports = printSeparatedList;

0 commit comments

Comments
 (0)