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]`.
|
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.
|
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.
|
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(),
|
_ => 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;
|
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 deallocs: 5176
|
||||||
sys alloc bytes: 1130046 # 1.13 MB
|
sys alloc bytes: 1130046 # 1.13 MB
|
||||||
sys peak growth: 435478 # 435.48 kB
|
sys peak growth: 435478 # 435.48 kB
|
||||||
arena allocs: 11512
|
arena allocs: 11511
|
||||||
arena reallocs: 364
|
arena reallocs: 362
|
||||||
arena size: 7117368 # 7.12 MB
|
arena size: 7086616 # 7.09 MB
|
||||||
|
|
||||||
RadixUIAdoptionSection.jsx:
|
RadixUIAdoptionSection.jsx:
|
||||||
file size: 2520 # 2.52 kB
|
file size: 2520 # 2.52 kB
|
||||||
@@ -38,9 +38,9 @@ pdf.mjs:
|
|||||||
sys deallocs: 9754
|
sys deallocs: 9754
|
||||||
sys alloc bytes: 2384856 # 2.38 MB
|
sys alloc bytes: 2384856 # 2.38 MB
|
||||||
sys peak growth: 1156488 # 1.16 MB
|
sys peak growth: 1156488 # 1.16 MB
|
||||||
arena allocs: 21673
|
arena allocs: 21652
|
||||||
arena reallocs: 446
|
arena reallocs: 402
|
||||||
arena size: 11090656 # 11.09 MB
|
arena size: 11048480 # 11.05 MB
|
||||||
|
|
||||||
antd.js:
|
antd.js:
|
||||||
file size: 6686316 # 6.69 MB
|
file size: 6686316 # 6.69 MB
|
||||||
@@ -51,7 +51,7 @@ antd.js:
|
|||||||
sys peak growth: 13710144 # 13.71 MB
|
sys peak growth: 13710144 # 13.71 MB
|
||||||
arena allocs: 120676
|
arena allocs: 120676
|
||||||
arena reallocs: 1889
|
arena reallocs: 1889
|
||||||
arena size: 114800840 # 114.80 MB
|
arena size: 114754760 # 114.75 MB
|
||||||
|
|
||||||
binder.ts:
|
binder.ts:
|
||||||
file size: 193077 # 193.08 kB
|
file size: 193077 # 193.08 kB
|
||||||
@@ -71,6 +71,6 @@ kitchen-sink.tsx:
|
|||||||
sys deallocs: 12609
|
sys deallocs: 12609
|
||||||
sys alloc bytes: 3737938 # 3.74 MB
|
sys alloc bytes: 3737938 # 3.74 MB
|
||||||
sys peak growth: 1491884 # 1.49 MB
|
sys peak growth: 1491884 # 1.49 MB
|
||||||
arena allocs: 30688
|
arena allocs: 30654
|
||||||
arena reallocs: 1043
|
arena reallocs: 975
|
||||||
arena size: 14615800 # 14.62 MB
|
arena size: 14595272 # 14.60 MB
|
||||||
Reference in new issue
Block a user