Improve super class (or single heritage) breaking (#18325)
This commit is contained in:
1 parent
bbdec54a41
commit
6ba133e80c
10 files changed
+337
-12
No files matched your search
@@ -0,0 +1,15 @@
|
||||
#### Improve super class format (#18325 by @fisker)
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
class EnsureNoDisposablesAreLeakedInTestSuiteSuite extends eslint.Rule.RuleModule {};
|
||||
|
||||
// Prettier stable
|
||||
class EnsureNoDisposablesAreLeakedInTestSuiteSuite extends eslint.Rule
|
||||
.RuleModule {}
|
||||
|
||||
// Prettier main
|
||||
class EnsureNoDisposablesAreLeakedInTestSuiteSuite
|
||||
extends eslint.Rule.RuleModule {}
|
||||
```
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
CommentCheckFlags,
|
||||
createTypeCheckFunction,
|
||||
hasComment,
|
||||
isMemberExpression,
|
||||
} from "../utils/index.js";
|
||||
import { printAssignment } from "./assignment.js";
|
||||
import { printClassMemberDecorators } from "./decorators.js";
|
||||
@@ -67,11 +68,7 @@ function printClass(path, options, print) {
|
||||
|
||||
// Keep old behaviour of extends in same line
|
||||
// If there is only on extends and there are not comments
|
||||
const groupMode =
|
||||
hasComment(node.id, CommentCheckFlags.Trailing) ||
|
||||
hasComment(node.typeParameters, CommentCheckFlags.Trailing) ||
|
||||
hasComment(node.superClass) ||
|
||||
hasMultipleHeritage(node);
|
||||
const groupMode = shouldPrintClassInGroupMode(path);
|
||||
|
||||
const partsGroup = [];
|
||||
const extendsParts = [];
|
||||
@@ -110,14 +107,12 @@ function printClass(path, options, print) {
|
||||
extendsParts.push(" ", printedWithComments);
|
||||
}
|
||||
} else {
|
||||
extendsParts.push(
|
||||
printHeritageClauses(path, options, print, "extends", groupMode),
|
||||
);
|
||||
extendsParts.push(printHeritageClauses(path, options, print, "extends"));
|
||||
}
|
||||
|
||||
extendsParts.push(
|
||||
printHeritageClauses(path, options, print, "mixins", groupMode),
|
||||
printHeritageClauses(path, options, print, "implements", groupMode),
|
||||
printHeritageClauses(path, options, print, "mixins"),
|
||||
printHeritageClauses(path, options, print, "implements"),
|
||||
);
|
||||
|
||||
let heritageGroupId;
|
||||
@@ -170,7 +165,65 @@ function hasMultipleHeritage(node) {
|
||||
return count > 1;
|
||||
}
|
||||
|
||||
function printHeritageClauses(path, options, print, listName, groupMode) {
|
||||
/**
|
||||
@returns {boolean}
|
||||
*/
|
||||
function shouldPrintClassInGroupModeWithoutCache(path) {
|
||||
const { node } = path;
|
||||
if (
|
||||
hasComment(node.id, CommentCheckFlags.Trailing) ||
|
||||
hasComment(node.typeParameters, CommentCheckFlags.Trailing) ||
|
||||
hasComment(node.superClass) ||
|
||||
hasMultipleHeritage(node)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node.superClass) {
|
||||
if (path.parent.type === "AssignmentExpression") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const superTypeArguments =
|
||||
node.superTypeArguments ?? node.superTypeParameters;
|
||||
|
||||
return !superTypeArguments && isMemberExpression(node.superClass);
|
||||
}
|
||||
|
||||
const heritage =
|
||||
node.extends?.[0] ?? node.mixins?.[0] ?? node.implements?.[0];
|
||||
|
||||
if (!heritage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const groupMode =
|
||||
// `ClassImplements` seem not allow `QualifiedTypeIdentifier`
|
||||
(heritage.type === "InterfaceExtends" &&
|
||||
heritage.id.type === "QualifiedTypeIdentifier" &&
|
||||
!heritage.typeParameters) ||
|
||||
((heritage.type === "TSClassImplements" ||
|
||||
heritage.type === "TSInterfaceHeritage") &&
|
||||
isMemberExpression(heritage.expression) &&
|
||||
!heritage.typeArguments);
|
||||
|
||||
return groupMode;
|
||||
}
|
||||
|
||||
const shouldPrintClassInGroupModeCache = new WeakMap();
|
||||
function shouldPrintClassInGroupMode(path) {
|
||||
const { node } = path;
|
||||
if (!shouldPrintClassInGroupModeCache.has(node)) {
|
||||
shouldPrintClassInGroupModeCache.set(
|
||||
node,
|
||||
shouldPrintClassInGroupModeWithoutCache(path),
|
||||
);
|
||||
}
|
||||
|
||||
return shouldPrintClassInGroupModeCache.get(node);
|
||||
}
|
||||
|
||||
function printHeritageClauses(path, options, print, listName) {
|
||||
const { node } = path;
|
||||
if (!isNonEmptyArray(node[listName])) {
|
||||
return "";
|
||||
@@ -189,7 +242,7 @@ function printHeritageClauses(path, options, print, listName, groupMode) {
|
||||
printedLeadingComments,
|
||||
heritageClausesDoc,
|
||||
];
|
||||
if (groupMode) {
|
||||
if (shouldPrintClassInGroupMode(path)) {
|
||||
return [line, group(printed)];
|
||||
}
|
||||
return [" ", printed];
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`member-expression-like.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
class A_long_long_long_long_long_long_long_long_name1
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class Short
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name12
|
||||
extends eslint.Rule?.RuleModule {}
|
||||
|
||||
interface A_long_long_long_long_long_long_long_long_name2
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
declare class A_long_long_long_long_long_long_long_long_name2
|
||||
mixins eslint.Rule.RuleModule {}
|
||||
|
||||
declare class A_long_long_long_long_long_long_long_long_name3
|
||||
extends eslint.Rule.RuleModule
|
||||
mixins eslint.Rule.RuleModule {}
|
||||
|
||||
=====================================output=====================================
|
||||
class A_long_long_long_long_long_long_long_long_name1
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class Short extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name12
|
||||
extends eslint.Rule?.RuleModule {}
|
||||
|
||||
interface A_long_long_long_long_long_long_long_long_name2
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
declare class A_long_long_long_long_long_long_long_long_name2
|
||||
mixins eslint.Rule.RuleModule {}
|
||||
|
||||
declare class A_long_long_long_long_long_long_long_long_name3
|
||||
extends eslint.Rule.RuleModule
|
||||
mixins eslint.Rule.RuleModule {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`type-arguments.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["flow"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
interface CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox mixins React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
=====================================output=====================================
|
||||
class CommentBox extends React.Component<
|
||||
{ url: string, pollInterval: number },
|
||||
CommentData,
|
||||
> {}
|
||||
|
||||
interface CommentBox extends React.Component<
|
||||
{ url: string, pollInterval: number },
|
||||
CommentData,
|
||||
> {}
|
||||
|
||||
declare class CommentBox extends React.Component<
|
||||
{ url: string, pollInterval: number },
|
||||
CommentData,
|
||||
> {}
|
||||
|
||||
declare class CommentBox mixins React.Component<
|
||||
{ url: string, pollInterval: number },
|
||||
CommentData,
|
||||
> {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1 @@
|
||||
runFormatTest(import.meta, ["flow"]);
|
||||
@@ -0,0 +1,18 @@
|
||||
class A_long_long_long_long_long_long_long_long_name1
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class Short
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name12
|
||||
extends eslint.Rule?.RuleModule {}
|
||||
|
||||
interface A_long_long_long_long_long_long_long_long_name2
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
declare class A_long_long_long_long_long_long_long_long_name2
|
||||
mixins eslint.Rule.RuleModule {}
|
||||
|
||||
declare class A_long_long_long_long_long_long_long_long_name3
|
||||
extends eslint.Rule.RuleModule
|
||||
mixins eslint.Rule.RuleModule {}
|
||||
@@ -0,0 +1,19 @@
|
||||
class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
interface CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox mixins React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`member-expression-like.ts format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
class A_long_long_long_long_long_long_long_long_name1
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class Short
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name12
|
||||
extends eslint.Rule?.RuleModule {}
|
||||
|
||||
interface A_long_long_long_long_long_long_long_long_name2
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name2
|
||||
implements eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name3
|
||||
extends eslint.Rule.RuleModule
|
||||
implements eslint.Rule.RuleModule {}
|
||||
|
||||
=====================================output=====================================
|
||||
class A_long_long_long_long_long_long_long_long_name1
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class Short extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name12
|
||||
extends eslint.Rule?.RuleModule {}
|
||||
|
||||
interface A_long_long_long_long_long_long_long_long_name2
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name2
|
||||
implements eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name3
|
||||
extends eslint.Rule.RuleModule
|
||||
implements eslint.Rule.RuleModule {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`type-arguments.ts format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
interface CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox implements React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
=====================================output=====================================
|
||||
class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
interface CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox implements React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1 @@
|
||||
runFormatTest(import.meta, ["typescript"]);
|
||||
@@ -0,0 +1,18 @@
|
||||
class A_long_long_long_long_long_long_long_long_name1
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class Short
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name12
|
||||
extends eslint.Rule?.RuleModule {}
|
||||
|
||||
interface A_long_long_long_long_long_long_long_long_name2
|
||||
extends eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name2
|
||||
implements eslint.Rule.RuleModule {}
|
||||
|
||||
class A_long_long_long_long_long_long_long_long_name3
|
||||
extends eslint.Rule.RuleModule
|
||||
implements eslint.Rule.RuleModule {}
|
||||
@@ -0,0 +1,14 @@
|
||||
class CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
interface CommentBox extends React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
|
||||
declare class CommentBox implements React.Component<
|
||||
{ url: string; pollInterval: number },
|
||||
CommentData
|
||||
> {}
|
||||
Reference in new issue
Block a user