mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(formatter): handle this.b and super.b like foo.b (#28200)
For consistency.
This commit is contained in:
1 parent
72a54cf447
commit
9ead5c42df
5 files changed
+179
-11
No files matched your search
@@ -1200,3 +1200,39 @@ Prettier moves it before the object for `.b`, and after the `.` for `.#b`; both
|
||||
A binary-like or conditional object of a member breaks its parens the same way for `.c`, `[c]` and `?.[c]`.
|
||||
Prettier does so for `.c` only, while an `await` / `as` object breaks them for `[c]` too.
|
||||
The computed property (`a[b + c]`) keeps its own layout.
|
||||
|
||||
## single-level-member-no-break
|
||||
|
||||
- Why: uniform-rule (same construct, same output: `foo.b`)
|
||||
- Pin: `tests/fixtures/js/member-expression/single-level-member-no-break.mjs`
|
||||
|
||||
```js
|
||||
// input (printWidth: 80)
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
call(super.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
|
||||
// ours: the same as `foo.sql`
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
call(
|
||||
super.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
|
||||
// prettier
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this
|
||||
.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
call(
|
||||
super
|
||||
.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
```
|
||||
|
||||
A single-level member is not split after its object when the object is a single word: an identifier, `this` or `super`.
|
||||
The break would leave the word alone on its line for a single property, which rarely fits either.
|
||||
A longer path (`a.b.c`) still breaks into a list of properties.
|
||||
|
||||
Prettier keeps it only for an identifier object (prettier/prettier#1036, which has no case for `this` or `super`).
|
||||
Elsewhere it groups them with an identifier: all three count as a single word for a simple call argument,
|
||||
and `this` stays attached as a member chain head like a short identifier (`this.foo()` + break + `.bar()`, prettier/prettier#782).
|
||||
@@ -139,7 +139,18 @@ fn layout<'a>(
|
||||
_ => parent.is_member_expression(),
|
||||
};
|
||||
|
||||
if !is_nested && !object_is_cast_target && matches!(object, Expression::Identifier(_)) {
|
||||
// A single-level member is not split when its object is a single word (an identifier, `this` or `super`):
|
||||
// the break would leave the word alone on its line for a single property.
|
||||
// A longer path (`a.b.c`) can break into a list of properties instead.
|
||||
// NOTE: `import.meta` and `new.target` cannot break inside either, so the same reasoning applies to them.
|
||||
// They are not included yet, and break like Prettier (`import.meta` + break + `.resolve(...)`).
|
||||
if !is_nested
|
||||
&& !object_is_cast_target
|
||||
&& matches!(
|
||||
object,
|
||||
Expression::Identifier(_) | Expression::ThisExpression(_) | Expression::Super(_)
|
||||
)
|
||||
{
|
||||
return StaticMemberLayout::NoBreak;
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// DIVERGENCES.md#single-level-member-no-break
|
||||
class A extends B {
|
||||
#sql;
|
||||
m() {
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.#sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierKey}`;
|
||||
call(foo.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
call(this.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
call(super.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// Not a single word, breaks like Prettier for now
|
||||
call(new.target.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXX);
|
||||
import.meta.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// A longer path still breaks into a list of properties
|
||||
call(this.someVeryLongPropertyNameXXXXXXXXXXXXXXXXXXXXXXXXXXXX.anotherVeryLongPropertyNameXXXXXXXXXXXXX);
|
||||
}
|
||||
}
|
||||
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
---
|
||||
source: crates/oxc_formatter/tests/fixtures/mod.rs
|
||||
---
|
||||
==================== Input ====================
|
||||
// DIVERGENCES.md#single-level-member-no-break
|
||||
class A extends B {
|
||||
#sql;
|
||||
m() {
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.#sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierKey}`;
|
||||
call(foo.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
call(this.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
call(super.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX);
|
||||
require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// Not a single word, breaks like Prettier for now
|
||||
call(new.target.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXX);
|
||||
import.meta.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// A longer path still breaks into a list of properties
|
||||
call(this.someVeryLongPropertyNameXXXXXXXXXXXXXXXXXXXXXXXXXXXX.anotherVeryLongPropertyNameXXXXXXXXXXXXX);
|
||||
}
|
||||
}
|
||||
|
||||
==================== Output ====================
|
||||
------------------
|
||||
{ printWidth: 80 }
|
||||
------------------
|
||||
// DIVERGENCES.md#single-level-member-no-break
|
||||
class A extends B {
|
||||
#sql;
|
||||
m() {
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.#sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierKey}`;
|
||||
call(
|
||||
foo.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
call(
|
||||
this.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
call(
|
||||
super.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// Not a single word, breaks like Prettier for now
|
||||
call(
|
||||
new.target
|
||||
.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
import.meta
|
||||
.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// A longer path still breaks into a list of properties
|
||||
call(
|
||||
this.someVeryLongPropertyNameXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
.anotherVeryLongPropertyNameXXXXXXXXXXXXX,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
-------------------
|
||||
{ printWidth: 100 }
|
||||
-------------------
|
||||
// DIVERGENCES.md#single-level-member-no-break
|
||||
class A extends B {
|
||||
#sql;
|
||||
m() {
|
||||
foo.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierName}`;
|
||||
this.#sql`DELETE FROM some_table_with_a_long_name WHERE some_column_name = ${someIdentifierKey}`;
|
||||
call(
|
||||
foo.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
call(
|
||||
this.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
call(
|
||||
super.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
require.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// Not a single word, breaks like Prettier for now
|
||||
call(
|
||||
new.target
|
||||
.someVeryLongPropertyNameThatDoesNotFitOnTheLineEvenAfterBreakingXXXXXXXXXXXXXXXXXXXX,
|
||||
);
|
||||
import.meta
|
||||
.resolve("./a/long/long/long/long/long/long/long/long/long/long/long/long/path/to/module");
|
||||
|
||||
// A longer path still breaks into a list of properties
|
||||
call(
|
||||
this.someVeryLongPropertyNameXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
.anotherVeryLongPropertyNameXXXXXXXXXXXXX,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
===================== End =====================
|
||||
@@ -16,9 +16,9 @@ App.tsx:
|
||||
sys deallocs: 5176
|
||||
sys alloc bytes: 1130046 # 1.13 MB
|
||||
sys peak growth: 435478 # 435.48 kB
|
||||
arena allocs: 11512
|
||||
arena reallocs: 364
|
||||
arena size: 7117368 # 7.12 MB
|
||||
arena allocs: 11511
|
||||
arena reallocs: 362
|
||||
arena size: 7086616 # 7.09 MB
|
||||
|
||||
RadixUIAdoptionSection.jsx:
|
||||
file size: 2520 # 2.52 kB
|
||||
@@ -38,9 +38,9 @@ pdf.mjs:
|
||||
sys deallocs: 9754
|
||||
sys alloc bytes: 2384856 # 2.38 MB
|
||||
sys peak growth: 1156488 # 1.16 MB
|
||||
arena allocs: 21673
|
||||
arena reallocs: 446
|
||||
arena size: 11090656 # 11.09 MB
|
||||
arena allocs: 21652
|
||||
arena reallocs: 402
|
||||
arena size: 11048480 # 11.05 MB
|
||||
|
||||
antd.js:
|
||||
file size: 6686316 # 6.69 MB
|
||||
@@ -51,7 +51,7 @@ antd.js:
|
||||
sys peak growth: 13710144 # 13.71 MB
|
||||
arena allocs: 120676
|
||||
arena reallocs: 1889
|
||||
arena size: 114800840 # 114.80 MB
|
||||
arena size: 114754760 # 114.75 MB
|
||||
|
||||
binder.ts:
|
||||
file size: 193077 # 193.08 kB
|
||||
@@ -71,6 +71,6 @@ kitchen-sink.tsx:
|
||||
sys deallocs: 12609
|
||||
sys alloc bytes: 3737938 # 3.74 MB
|
||||
sys peak growth: 1491884 # 1.49 MB
|
||||
arena allocs: 30688
|
||||
arena reallocs: 1043
|
||||
arena size: 14615800 # 14.62 MB
|
||||
arena allocs: 30654
|
||||
arena reallocs: 975
|
||||
arena size: 14595272 # 14.60 MB
|
||||
Reference in new issue
Block a user