Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions crates/oxc_formatter/src/write/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,13 +469,30 @@ impl<'a> Format<'a> for FormatClass<'a, '_> {
///
/// Heritage clauses are grouped when:
/// 1. Superclass and/or implements are more than one
/// 2. There are comments in the heritage clause area
/// 3. There are trailing line comments after type parameters
/// 2. The superclass is a member expression without type arguments, or the implements clause is a qualified name without type arguments
/// 3. There are comments in the heritage clause area
/// 4. There are trailing line comments after type parameters
fn should_group<'a>(class: &Class<'a>, f: &Formatter<'_, 'a>) -> bool {
if usize::from(class.super_class.is_some()) + class.implements.len() > 1 {
return true;
}

if !class.is_expression()
&& ((class.super_type_arguments.is_none()
&& class
.super_class
.as_ref()
.is_some_and(|super_class|
super_class.is_member_expression() ||
matches!(&super_class, Expression::ChainExpression(chain) if chain.expression.is_member_expression())
))
|| class.implements.first().is_some_and(|implements| {
implements.type_arguments.is_none() && implements.expression.is_qualified_name()
}))
{
return true;
}

let comments = f.comments();

let id_span = class.id.as_ref().map(GetSpan::span);
Expand Down
10 changes: 8 additions & 2 deletions crates/oxc_formatter/src/write/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1301,10 +1301,16 @@ impl<'a> FormatWrite<'a> for AstNode<'a, TSInterfaceDeclaration<'a>> {
let extends = self.extends();
let body = self.body();

// Determines whether to use group mode for formatting the `extends` clause.
// 1. If there are multiple `extends`, we always use group mode.
// 2. If there is a single `extends` that is a member expression without type arguments, we use group mode.
// 3. If there are comments between the `id` and the `extends`, we use group mode.
let group_mode = extends.len() > 1
|| extends.as_ref().first().is_some_and(|first| {
let prev_span = type_parameters.as_ref().map_or(id.span(), GetSpan::span);
f.comments().has_comment_in_range(prev_span.end, first.span().start)
(first.expression.is_member_expression() && first.type_arguments.is_none()) || {
let prev_span = type_parameters.as_ref().map_or(id.span(), GetSpan::span);
f.comments().has_comment_in_range(prev_span.end, first.span().start)
}
});

let format_id = format_with(|f| {
Expand Down
6 changes: 6 additions & 0 deletions crates/oxc_formatter/tests/fixtures/ts/class/issue-16259.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

export interface longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
source: crates/oxc_formatter/tests/fixtures/mod.rs
---
==================== Input ====================
export class longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

export interface longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

==================== Output ====================
------------------
{ printWidth: 80 }
------------------
export class longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

export interface longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

-------------------
{ printWidth: 100 }
-------------------
export class longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

export interface longlonglonglonglonglonglonglonglonglonglongclassname
extends someobjectsomepropertysomeotherproperty.SomeClass {}

===================== End =====================
3 changes: 1 addition & 2 deletions tasks/prettier_conformance/snapshots/prettier.ts.snap.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ts compatibility: 574/604 (95.03%)
ts compatibility: 575/604 (95.20%)

# Failed

Expand All @@ -17,7 +17,6 @@ ts compatibility: 574/604 (95.03%)
| typescript/chain-expression/test.ts | 💥 | 0.00% |
| typescript/class/empty-method-body.ts | 💥 | 80.00% |
| typescript/class/quoted-property.ts | 💥 | 66.67% |
| typescript/class-and-interface/heritage-break/member-expression-like.ts | 💥 | 54.55% |
| typescript/comments/mapped_types.ts | 💥 | 96.77% |
| typescript/comments/method_types.ts | 💥 | 82.05% |
| typescript/decorators-ts/angular.ts | 💥 | 87.50% |
Expand Down
Loading