Skip to content

Commit 87dab58

Browse files
authored
Extract printClass and printTypeParameters (#9713)
1 parent b12e869 commit 87dab58

File tree

3 files changed

+288
-235
lines changed

3 files changed

+288
-235
lines changed

src/language-js/print/class.js

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"use strict";
2+
3+
const { printComments, printDanglingComments } = require("../../main/comments");
4+
const {
5+
builders: { concat, join, line, hardline, softline, group, indent, ifBreak },
6+
} = require("../../document");
7+
const { hasTrailingComment, hasTrailingLineComment } = require("../utils");
8+
const { getTypeParametersGroupId } = require("./type-parameters");
9+
10+
function printClass(path, options, print) {
11+
const n = path.getValue();
12+
const parts = [];
13+
14+
if (n.abstract) {
15+
parts.push("abstract ");
16+
}
17+
18+
parts.push("class");
19+
20+
// Keep old behaviour of extends in same line
21+
// If there is only on extends and there are not comments
22+
const groupMode =
23+
(n.id && hasTrailingComment(n.id)) ||
24+
(n.superClass &&
25+
n.superClass.comments &&
26+
n.superClass.comments.length !== 0) ||
27+
(n.extends && n.extends.length !== 0) || // DeclareClass
28+
(n.mixins && n.mixins.length !== 0) ||
29+
(n.implements && n.implements.length !== 0);
30+
31+
const partsGroup = [];
32+
const extendsParts = [];
33+
34+
if (n.id) {
35+
partsGroup.push(" ", path.call(print, "id"));
36+
}
37+
38+
partsGroup.push(path.call(print, "typeParameters"));
39+
40+
if (n.superClass) {
41+
const printed = concat([
42+
"extends ",
43+
printSuperClass(path, options, print),
44+
path.call(print, "superTypeParameters"),
45+
]);
46+
const printedWithComments = path.call(
47+
(superClass) => printComments(superClass, () => printed, options),
48+
"superClass"
49+
);
50+
if (groupMode) {
51+
extendsParts.push(line, group(printedWithComments));
52+
} else {
53+
extendsParts.push(" ", printedWithComments);
54+
}
55+
} else {
56+
extendsParts.push(printList(path, options, print, "extends"));
57+
}
58+
59+
extendsParts.push(printList(path, options, print, "mixins"));
60+
extendsParts.push(printList(path, options, print, "implements"));
61+
62+
if (groupMode) {
63+
const printedExtends = concat(extendsParts);
64+
if (shouldIndentOnlyHeritageClauses(n)) {
65+
parts.push(
66+
group(
67+
concat(
68+
partsGroup.concat(ifBreak(indent(printedExtends), printedExtends))
69+
)
70+
)
71+
);
72+
} else {
73+
parts.push(group(indent(concat(partsGroup.concat(printedExtends)))));
74+
}
75+
} else {
76+
parts.push(...partsGroup, ...extendsParts);
77+
}
78+
79+
parts.push(" ", path.call(print, "body"));
80+
81+
return concat(parts);
82+
}
83+
84+
function hasMultipleHeritage(node) {
85+
return (
86+
["superClass", "extends", "mixins", "implements"].filter(
87+
(key) => !!node[key]
88+
).length > 1
89+
);
90+
}
91+
92+
function shouldIndentOnlyHeritageClauses(node) {
93+
return (
94+
node.typeParameters &&
95+
!hasTrailingLineComment(node.typeParameters) &&
96+
!hasMultipleHeritage(node)
97+
);
98+
}
99+
100+
function printList(path, options, print, listName) {
101+
const n = path.getValue();
102+
if (!n[listName] || n[listName].length === 0) {
103+
return "";
104+
}
105+
106+
const printedLeadingComments = printDanglingComments(
107+
path,
108+
options,
109+
/* sameIndent */ true,
110+
({ marker }) => marker === listName
111+
);
112+
return concat([
113+
shouldIndentOnlyHeritageClauses(n)
114+
? ifBreak(" ", line, {
115+
groupId: getTypeParametersGroupId(n.typeParameters),
116+
})
117+
: line,
118+
printedLeadingComments,
119+
printedLeadingComments && hardline,
120+
listName,
121+
group(
122+
indent(
123+
concat([line, join(concat([",", line]), path.map(print, listName))])
124+
)
125+
),
126+
]);
127+
}
128+
129+
function printSuperClass(path, options, print) {
130+
const printed = path.call(print, "superClass");
131+
const parent = path.getParentNode();
132+
if (parent && parent.type === "AssignmentExpression") {
133+
return concat([
134+
ifBreak("("),
135+
indent(concat([softline, printed])),
136+
softline,
137+
ifBreak(")"),
138+
]);
139+
}
140+
return printed;
141+
}
142+
143+
module.exports = { printClass };
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"use strict";
2+
3+
const { printDanglingComments } = require("../../main/comments");
4+
const {
5+
builders: { concat, join, line, hardline, softline, group, indent, ifBreak },
6+
} = require("../../document");
7+
const {
8+
hasDanglingComments,
9+
isTestCall,
10+
isBlockComment,
11+
shouldPrintComma,
12+
} = require("../utils");
13+
const { shouldHugType } = require("./type-annotation");
14+
15+
const typeParametersGroupIds = new WeakMap();
16+
function getTypeParametersGroupId(node) {
17+
if (!typeParametersGroupIds.has(node)) {
18+
typeParametersGroupIds.set(node, Symbol("typeParameters"));
19+
}
20+
return typeParametersGroupIds.get(node);
21+
}
22+
23+
function printTypeParameters(path, options, print, paramsKey) {
24+
const n = path.getValue();
25+
26+
if (!n[paramsKey]) {
27+
return "";
28+
}
29+
30+
// for TypeParameterDeclaration typeParameters is a single node
31+
if (!Array.isArray(n[paramsKey])) {
32+
return path.call(print, paramsKey);
33+
}
34+
35+
const grandparent = path.getNode(2);
36+
const isParameterInTestCall = grandparent != null && isTestCall(grandparent);
37+
38+
const shouldInline =
39+
isParameterInTestCall ||
40+
n[paramsKey].length === 0 ||
41+
(n[paramsKey].length === 1 &&
42+
(shouldHugType(n[paramsKey][0]) ||
43+
(n[paramsKey][0].type === "GenericTypeAnnotation" &&
44+
shouldHugType(n[paramsKey][0].id)) ||
45+
(n[paramsKey][0].type === "TSTypeReference" &&
46+
shouldHugType(n[paramsKey][0].typeName)) ||
47+
n[paramsKey][0].type === "NullableTypeAnnotation"));
48+
49+
if (shouldInline) {
50+
return concat([
51+
"<",
52+
join(", ", path.map(print, paramsKey)),
53+
printDanglingCommentsForInline(path, options),
54+
">",
55+
]);
56+
}
57+
58+
return group(
59+
concat([
60+
"<",
61+
indent(
62+
concat([
63+
softline,
64+
join(concat([",", line]), path.map(print, paramsKey)),
65+
])
66+
),
67+
ifBreak(
68+
options.parser !== "typescript" &&
69+
options.parser !== "babel-ts" &&
70+
shouldPrintComma(options, "all")
71+
? ","
72+
: ""
73+
),
74+
softline,
75+
">",
76+
]),
77+
{ id: getTypeParametersGroupId(n) }
78+
);
79+
}
80+
81+
function printDanglingCommentsForInline(path, options) {
82+
const n = path.getValue();
83+
if (!hasDanglingComments(n)) {
84+
return "";
85+
}
86+
const hasOnlyBlockComments = n.comments.every((comment) =>
87+
isBlockComment(comment)
88+
);
89+
const printed = printDanglingComments(
90+
path,
91+
options,
92+
/* sameIndent */ hasOnlyBlockComments
93+
);
94+
if (hasOnlyBlockComments) {
95+
return printed;
96+
}
97+
return concat([printed, hardline]);
98+
}
99+
100+
module.exports = { printTypeParameters, getTypeParametersGroupId };

0 commit comments

Comments
 (0)