Skip to content

Commit 88c72ba

Browse files
authored
feat: add "quoteProps": "consistent" (#544)
1 parent 35b476d commit 88c72ba

File tree

9 files changed

+457
-171
lines changed

9 files changed

+457
-171
lines changed

deployment/schema.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,14 @@
6565
"type": "string",
6666
"default": "preserve",
6767
"oneOf": [{
68-
"const": "preserve",
69-
"description": "Preserve quotes around property names."
70-
}, {
7168
"const": "asNeeded",
7269
"description": "Remove unnecessary quotes around property names."
70+
}, {
71+
"const": "consistent",
72+
"description": "Same as 'asNeeded', but if one property requires quotes then quote them all."
73+
}, {
74+
"const": "preserve",
75+
"description": "Preserve quotes around property names."
7376
}]
7477
},
7578
"jsx.multiLineParens": {

dprint.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
22
"exec": {
3-
"associations": "**/*.rs",
4-
"rustfmt": "rustfmt"
3+
"commands": [{
4+
"command": "rustfmt",
5+
"exts": ["rs"]
6+
}]
57
},
6-
"includes": ["**/*.{ts,tsx,js,jsx,cjs,mjs,json,md,toml,rs}"],
78
"excludes": [
89
"**/node_modules",
910
"**/*-lock.json",
@@ -15,6 +16,6 @@
1516
"https://plugins.dprint.dev/json-0.16.0.wasm",
1617
"https://plugins.dprint.dev/markdown-0.14.3.wasm",
1718
"https://plugins.dprint.dev/toml-0.5.4.wasm",
18-
"https://plugins.dprint.dev/exec-0.3.2.json@8efbbb3fcfbdf84142c3c438fbdeaf1637152a020032127c837b2b14e23261c3"
19+
"https://plugins.dprint.dev/exec-0.4.3.json@42343548b8022c99b1d750be6b894fe6b6c7ee25f72ae9f9082226dd2e515072"
1920
]
2021
}

src/configuration/types.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,15 @@ generate_str_to_from![JsxQuoteStyle, [PreferDouble, "preferDouble"], [PreferSing
225225
#[derive(Clone, PartialEq, Copy, Serialize, Deserialize)]
226226
#[serde(rename_all = "camelCase")]
227227
pub enum QuoteProps {
228-
/// Preserve quotes around property names.
229-
Preserve,
230228
/// Remove unnecessary quotes around property names.
231229
AsNeeded,
230+
/// Same as `AsNeeded`, but if one property requires quotes then quote them all.
231+
Consistent,
232+
/// Preserve quotes around property names.
233+
Preserve,
232234
}
233235

234-
generate_str_to_from![QuoteProps, [Preserve, "preserve"], [AsNeeded, "asNeeded"]];
236+
generate_str_to_from![QuoteProps, [AsNeeded, "asNeeded"], [Consistent, "consistent"], [Preserve, "preserve"]];
235237

236238
/// Whether to surround a JSX element or fragment with parentheses
237239
/// when it's the top JSX node and it spans multiple lines.

src/generation/context.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub struct Context<'a> {
2626
pub token_finder: TokenFinder<'a>,
2727
pub current_node: Node<'a>,
2828
pub parent_stack: Stack<Node<'a>>,
29+
/// Stores whether the parent requires all properties have consistent quoting.
30+
consistent_quote_props_stack: Stack<bool>,
2931
handled_comments: FxHashSet<SourcePos>,
3032
stored_ln_ranges: FxHashMap<(SourcePos, SourcePos), (LineNumber, LineNumber)>,
3133
stored_lsil: FxHashMap<(SourcePos, SourcePos), LineStartIndentLevel>,
@@ -49,14 +51,15 @@ impl<'a> Context<'a> {
4951
comments: CommentTracker::new(program, tokens),
5052
token_finder: TokenFinder::new(program),
5153
current_node,
52-
parent_stack: Stack::new(),
54+
parent_stack: Default::default(),
55+
consistent_quote_props_stack: Default::default(),
5356
handled_comments: FxHashSet::default(),
5457
stored_ln_ranges: FxHashMap::default(),
5558
stored_lsil: FxHashMap::default(),
5659
stored_ln: FxHashMap::default(),
5760
stored_il: FxHashMap::default(),
58-
end_statement_or_member_lns: Stack::new(),
59-
before_comments_start_info_stack: Stack::new(),
61+
end_statement_or_member_lns: Default::default(),
62+
before_comments_start_info_stack: Default::default(),
6063
if_stmt_last_brace_condition_ref: None,
6164
expr_stmt_single_line_parent_brace_ref: None,
6265
#[cfg(debug_assertions)]
@@ -158,6 +161,26 @@ impl<'a> Context<'a> {
158161
}
159162
}
160163

164+
pub fn use_consistent_quote_props(&self) -> Option<bool> {
165+
self.consistent_quote_props_stack.peek().copied()
166+
}
167+
168+
pub fn with_maybe_consistent_props<TState, TReturn>(
169+
&mut self,
170+
state: TState,
171+
use_consistent_quotes: impl FnOnce(&TState) -> bool,
172+
action: impl FnOnce(&mut Self, TState) -> TReturn,
173+
) -> TReturn {
174+
if self.config.quote_props == QuoteProps::Consistent {
175+
self.consistent_quote_props_stack.push((use_consistent_quotes)(&state));
176+
}
177+
let is_consistent = self.consistent_quote_props_stack.peek().copied().unwrap_or(true);
178+
self.consistent_quote_props_stack.push(is_consistent);
179+
let result = action(self, state);
180+
self.consistent_quote_props_stack.pop();
181+
result
182+
}
183+
161184
// do any assertions for how the state of this context should be at the end of the file
162185
#[cfg(debug_assertions)]
163186
pub fn assert_end_of_file_state(&self) {

0 commit comments

Comments
 (0)