mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
fix(oxfmt): expand Fill parts in tsx-in-vue (#26427)
Fixes #26398, closes #26399. --- Our Rust printer knows how to expand `Fill` with `Interned`, but Prettier printer does not.
This commit is contained in:
@@ -371,21 +371,32 @@ fn convert_elements(
|
||||
}
|
||||
printer.pending_space = false;
|
||||
}
|
||||
let key = interned_cache_key(interned);
|
||||
let id = if let Some(&id) = state.interned_to_ref.get(&key) {
|
||||
id
|
||||
} else {
|
||||
// Reserve the slot index now:
|
||||
// the recursive `convert_elements` call below may push more refs,
|
||||
// so `state.refs.len()` would no longer equal this Interned's slot when we go to fill it.
|
||||
let id = state.refs.len();
|
||||
state.refs.push(Value::Null);
|
||||
state.interned_to_ref.insert(key, id);
|
||||
// `fill` parts must stay a flat `[item, separator, ...]` list,
|
||||
// but the formatter may wrap all entries in one `Interned` (e.g. JSX children).
|
||||
// Splice them like the printer does, instead of emitting one opaque `_REF` part.
|
||||
if matches!(
|
||||
stack.last().and_then(|entry| entry.start_info.as_ref()),
|
||||
Some(StartTagInfo::Fill)
|
||||
) {
|
||||
let converted = convert_shared_elements(interned, state)?;
|
||||
state.refs[id] = normalize_array(converted);
|
||||
id
|
||||
};
|
||||
current_children_mut(&mut stack)?.push(json!({ "_REF": id }));
|
||||
current_children_mut(&mut stack)?.extend(converted);
|
||||
} else {
|
||||
let key = interned_cache_key(interned);
|
||||
let id = if let Some(&id) = state.interned_to_ref.get(&key) {
|
||||
id
|
||||
} else {
|
||||
// Reserve the slot index now:
|
||||
// the recursive `convert_elements` call below may push more refs,
|
||||
// so `state.refs.len()` would no longer equal this Interned's slot when we go to fill it.
|
||||
let id = state.refs.len();
|
||||
state.refs.push(Value::Null);
|
||||
state.interned_to_ref.insert(key, id);
|
||||
let converted = convert_shared_elements(interned, state)?;
|
||||
state.refs[id] = normalize_array(converted);
|
||||
id
|
||||
};
|
||||
current_children_mut(&mut stack)?.push(json!({ "_REF": id }));
|
||||
}
|
||||
printer.line = LineState::Content;
|
||||
}
|
||||
FormatElement::BestFitting(best_fitting) => {
|
||||
|
||||
@@ -149,6 +149,40 @@ export default {
|
||||
expect(result.errors).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should fill JSX text in <script lang="tsx"> blocks, not all-or-nothing', async () => {
|
||||
const input = `
|
||||
<script setup lang="tsx">
|
||||
const short = (
|
||||
<div>
|
||||
<label for="d" class={[c]}>
|
||||
Please enter the scheduled payment date below
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
const long = <div>Please enter the scheduled payment date below aaa bbb ccc ddd eee fff ggg hhh</div>;
|
||||
</script>
|
||||
`;
|
||||
const result = await format("a.vue", input, { printWidth: 80 });
|
||||
|
||||
expect(result.code).toBe(`<script setup lang="tsx">
|
||||
const short = (
|
||||
<div>
|
||||
<label for="d" class={[c]}>
|
||||
Please enter the scheduled payment date below
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
const long = (
|
||||
<div>
|
||||
Please enter the scheduled payment date below aaa bbb ccc ddd eee fff ggg
|
||||
hhh
|
||||
</div>
|
||||
);
|
||||
</script>
|
||||
`);
|
||||
expect(result.errors).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should format generic arrows in <script lang="ts"> blocks', async () => {
|
||||
const input = `
|
||||
<script lang="ts">
|
||||
|
||||
Reference in New Issue
Block a user