Skip to content

Commit 47fc963

Browse files
authored
Merge branch 'main' into 03-14-ci_correct_if_condition_of_type-check_job
2 parents 58a056c + ae6b599 commit 47fc963

File tree

9 files changed

+179
-211
lines changed

9 files changed

+179
-211
lines changed

crates/rolldown_binding/src/options/plugin/binding_plugin_options.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use itertools::Itertools;
21
use napi::bindgen_prelude::{Either, FnArgs};
32
use rolldown_utils::filter_expression::{self, FilterExprKind};
43
use std::fmt::Debug;
@@ -217,45 +216,43 @@ pub struct FilterExprCache {
217216
pub render_chunk: Option<Vec<FilterExprKind>>,
218217
}
219218
impl BindingPluginOptions {
220-
pub fn pre_compile_filter_expr(&self) -> FilterExprCache {
219+
pub fn pre_compile_filter_expr(&self) -> napi::Result<FilterExprCache> {
220+
let plugin_name = &self.name;
221+
let make_err = |err: anyhow::Error| {
222+
napi::Error::new(
223+
napi::Status::InvalidArg,
224+
format!("Invalid filter expression in plugin '{plugin_name}': {err}"),
225+
)
226+
};
227+
let compile = |tokenss: &[Vec<_>]| -> napi::Result<Vec<FilterExprKind>> {
228+
tokenss
229+
.iter()
230+
.cloned()
231+
.map(|tokens| {
232+
let normalized = normalized_tokens(tokens).map_err(&make_err)?;
233+
filter_expression::parse(normalized).map_err(&make_err)
234+
})
235+
.collect()
236+
};
237+
221238
let mut cache = FilterExprCache::default();
222239
if let Some(tokenss) = self.resolve_id_filter.as_ref().and_then(|item| item.value.as_ref()) {
223-
let filter_kind = tokenss
224-
.clone()
225-
.into_iter()
226-
.map(|tokens| filter_expression::parse(normalized_tokens(tokens)))
227-
.collect_vec();
228-
cache.resolve_id = Some(filter_kind);
240+
cache.resolve_id = Some(compile(tokenss)?);
229241
}
230242

231243
if let Some(filter) = self.load_filter.as_ref().and_then(|item| item.value.as_ref()) {
232-
let filter_kind = filter
233-
.clone()
234-
.into_iter()
235-
.map(|tokens| filter_expression::parse(normalized_tokens(tokens)))
236-
.collect_vec();
237-
cache.load = Some(filter_kind);
244+
cache.load = Some(compile(filter)?);
238245
}
239246

240247
if let Some(filter) = self.transform_filter.as_ref().and_then(|item| item.value.as_ref()) {
241-
let filter_kind = filter
242-
.clone()
243-
.into_iter()
244-
.map(|tokens| filter_expression::parse(normalized_tokens(tokens)))
245-
.collect_vec();
246-
cache.transform = Some(filter_kind);
248+
cache.transform = Some(compile(filter)?);
247249
}
248250

249251
if let Some(filter) = self.render_chunk_filter.as_ref().and_then(|item| item.value.as_ref()) {
250-
let filter_kind = filter
251-
.clone()
252-
.into_iter()
253-
.map(|tokens| filter_expression::parse(normalized_tokens(tokens)))
254-
.collect_vec();
255-
cache.render_chunk = Some(filter_kind);
252+
cache.render_chunk = Some(compile(filter)?);
256253
}
257254

258-
cache
255+
Ok(cache)
259256
}
260257
}
261258

crates/rolldown_binding/src/options/plugin/js_plugin.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ impl Deref for JsPlugin {
4747

4848
impl JsPlugin {
4949
#[cfg_attr(target_family = "wasm", allow(unused))]
50-
pub(super) fn new(inner: BindingPluginOptions) -> Self {
51-
let filter_expr_cache = inner.pre_compile_filter_expr();
52-
Self { inner, filter_expr_cache }
50+
pub(super) fn new(inner: BindingPluginOptions) -> napi::Result<Self> {
51+
let filter_expr_cache = inner.pre_compile_filter_expr()?;
52+
Ok(Self { inner, filter_expr_cache })
5353
}
5454

55-
pub(crate) fn new_shared(inner: BindingPluginOptions) -> SharedPluginable {
56-
let filter_expr_cache = inner.pre_compile_filter_expr();
57-
Arc::new(Self { inner, filter_expr_cache })
55+
pub(crate) fn new_shared(inner: BindingPluginOptions) -> napi::Result<SharedPluginable> {
56+
let filter_expr_cache = inner.pre_compile_filter_expr()?;
57+
Ok(Arc::new(Self { inner, filter_expr_cache }))
5858
}
5959
}
6060

crates/rolldown_binding/src/options/plugin/parallel_js_plugin.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,19 @@ impl ParallelJsPlugin {
3030
pub fn new_boxed(
3131
plugins: Vec<BindingPluginOptions>,
3232
worker_manager: Arc<WorkerManager>,
33-
) -> Box<dyn Pluginable> {
34-
let plugins = plugins.into_iter().map(JsPlugin::new).collect::<Vec<_>>().into_boxed_slice();
35-
Box::new(Self { plugins, worker_manager })
33+
) -> napi::Result<Box<dyn Pluginable>> {
34+
let plugins =
35+
plugins.into_iter().map(JsPlugin::new).collect::<napi::Result<Vec<_>>>()?.into_boxed_slice();
36+
Ok(Box::new(Self { plugins, worker_manager }))
3637
}
3738

3839
pub fn new_shared(
3940
plugins: Vec<BindingPluginOptions>,
4041
worker_manager: Arc<WorkerManager>,
41-
) -> Arc<dyn Pluginable> {
42-
let plugins = plugins.into_iter().map(JsPlugin::new).collect::<Vec<_>>().into_boxed_slice();
43-
Arc::new(Self { plugins, worker_manager })
42+
) -> napi::Result<Arc<dyn Pluginable>> {
43+
let plugins =
44+
plugins.into_iter().map(JsPlugin::new).collect::<napi::Result<Vec<_>>>()?.into_boxed_slice();
45+
Ok(Arc::new(Self { plugins, worker_manager }))
4446
}
4547

4648
fn first_plugin(&self) -> &JsPlugin {

crates/rolldown_binding/src/options/plugin/types/binding_filter_expression.rs

Lines changed: 49 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,31 @@ pub enum BindingFilterTokenPayloadInner {
1717
}
1818

1919
impl BindingFilterTokenPayloadInner {
20-
pub fn expect_string(self) -> String {
20+
pub fn try_into_string(self) -> anyhow::Result<String> {
2121
match self {
22-
BindingFilterTokenPayloadInner::StringOrRegex(inner) => inner.expect_string(),
23-
BindingFilterTokenPayloadInner::Number(_) | BindingFilterTokenPayloadInner::Boolean(_) => {
24-
unreachable!()
25-
}
22+
BindingFilterTokenPayloadInner::StringOrRegex(inner) => inner.try_into_string(),
23+
other => anyhow::bail!("expected a string payload, but got {other:?}"),
2624
}
2725
}
2826

29-
pub fn expect_string_or_regex(self) -> StringOrRegex {
27+
pub fn try_into_string_or_regex(self) -> anyhow::Result<StringOrRegex> {
3028
match self {
31-
BindingFilterTokenPayloadInner::StringOrRegex(inner) => inner,
32-
BindingFilterTokenPayloadInner::Number(_) | BindingFilterTokenPayloadInner::Boolean(_) => {
33-
unreachable!()
34-
}
29+
BindingFilterTokenPayloadInner::StringOrRegex(inner) => Ok(inner),
30+
other => anyhow::bail!("expected a string or regex payload, but got {other:?}"),
3531
}
3632
}
3733

38-
pub fn expect_number(self) -> u32 {
34+
pub fn try_into_number(self) -> anyhow::Result<u32> {
3935
match self {
40-
BindingFilterTokenPayloadInner::Number(v) => v,
41-
BindingFilterTokenPayloadInner::StringOrRegex(_)
42-
| BindingFilterTokenPayloadInner::Boolean(_) => unreachable!(),
36+
BindingFilterTokenPayloadInner::Number(v) => Ok(v),
37+
other => anyhow::bail!("expected a number payload, but got {other:?}"),
4338
}
4439
}
4540

46-
pub fn expect_regex(self) -> HybridRegex {
41+
pub fn try_into_regex(self) -> anyhow::Result<HybridRegex> {
4742
match self {
48-
BindingFilterTokenPayloadInner::StringOrRegex(inner) => inner.expect_regex(),
49-
BindingFilterTokenPayloadInner::Number(_) | BindingFilterTokenPayloadInner::Boolean(_) => {
50-
unreachable!()
51-
}
43+
BindingFilterTokenPayloadInner::StringOrRegex(inner) => inner.try_into_regex(),
44+
other => anyhow::bail!("expected a regex payload, but got {other:?}"),
5245
}
5346
}
5447
}
@@ -107,64 +100,42 @@ pub enum FilterTokenKind {
107100
QueryValue,
108101
}
109102

110-
pub fn normalized_tokens(tokens: Vec<BindingFilterToken>) -> Vec<Token> {
103+
pub fn normalized_tokens(tokens: Vec<BindingFilterToken>) -> anyhow::Result<Vec<Token>> {
104+
fn take_payload(
105+
token: &mut BindingFilterToken,
106+
) -> anyhow::Result<BindingFilterTokenPayloadInner> {
107+
token
108+
.payload
109+
.take()
110+
.ok_or_else(|| anyhow::anyhow!("`{:?}` token should have a payload", token.kind))
111+
.map(BindingFilterTokenPayload::into_inner)
112+
}
113+
111114
let mut ret: Vec<Token> = Vec::with_capacity(tokens.len());
112115
let mut iter = tokens.into_iter().peekable();
113116
while let Some(value) = iter.peek_mut() {
114117
match value.kind {
115118
FilterTokenKind::Id => {
116-
ret.push(Token::from(
117-
value
118-
.payload
119-
.take()
120-
.expect("`Id` should have payload")
121-
.into_inner()
122-
.expect_string_or_regex(),
123-
));
119+
ret.push(Token::from(take_payload(value)?.try_into_string_or_regex()?));
124120
ret.push(Token::Id);
125121
}
126122
FilterTokenKind::ImporterId => {
127-
ret.push(Token::from(
128-
value
129-
.payload
130-
.take()
131-
.expect("`ImporterId` should have payload")
132-
.into_inner()
133-
.expect_string_or_regex(),
134-
));
123+
ret.push(Token::from(take_payload(value)?.try_into_string_or_regex()?));
135124
ret.push(Token::ImporterId);
136125
}
137126
FilterTokenKind::Code => {
138-
ret.push(Token::from(
139-
value
140-
.payload
141-
.take()
142-
.expect("`Code` should have payload")
143-
.into_inner()
144-
.expect_string_or_regex(),
145-
));
127+
ret.push(Token::from(take_payload(value)?.try_into_string_or_regex()?));
146128
ret.push(Token::Code);
147129
}
148130
FilterTokenKind::ModuleType => {
149-
ret.push(Token::String(
150-
value
151-
.payload
152-
.take()
153-
.expect("`ModuleType` should have payload")
154-
.into_inner()
155-
.expect_string(),
156-
));
131+
ret.push(Token::String(take_payload(value)?.try_into_string()?));
157132
ret.push(Token::ModuleType);
158133
}
159134
FilterTokenKind::And => {
160-
ret.push(Token::And(
161-
value.payload.take().expect("And should have payload").into_inner().expect_number(),
162-
));
135+
ret.push(Token::And(take_payload(value)?.try_into_number()?));
163136
}
164137
FilterTokenKind::Or => {
165-
ret.push(Token::Or(
166-
value.payload.take().expect("`Or` should have payload").into_inner().expect_number(),
167-
));
138+
ret.push(Token::Or(take_payload(value)?.try_into_number()?));
168139
}
169140
FilterTokenKind::Not => {
170141
ret.push(Token::Not);
@@ -173,40 +144,38 @@ pub fn normalized_tokens(tokens: Vec<BindingFilterToken>) -> Vec<Token> {
173144
FilterTokenKind::Exclude => ret.push(Token::Exclude),
174145
FilterTokenKind::CleanUrl => ret.push(Token::CleanUrl),
175146
FilterTokenKind::QueryKey => {
176-
let query_key = value
177-
.payload
178-
.take()
179-
.expect("`QueryKey` should have payload")
180-
.into_inner()
181-
.expect_string();
147+
let query_key = take_payload(value)?.try_into_string()?;
182148
iter.next();
183-
let Some(next_token) = iter.peek_mut() else {
184-
unreachable!("`QueryKey` should be followed by one Token");
185-
};
149+
let next_token = iter.peek_mut().ok_or_else(|| {
150+
anyhow::anyhow!("`QueryKey` should be followed by a `QueryValue` token")
151+
})?;
186152
if next_token.kind != FilterTokenKind::QueryValue {
187-
unreachable!("`QueryKey` should be followed by `QueryValue`");
153+
anyhow::bail!(
154+
"`QueryKey` should be followed by `QueryValue`, but got `{:?}`",
155+
next_token.kind
156+
);
188157
}
189-
let query_value =
190-
match next_token.payload.take().expect("`QueryValue` should have payload").into_inner() {
191-
BindingFilterTokenPayloadInner::StringOrRegex(string_or_regex) => match string_or_regex
192-
{
193-
StringOrRegex::String(str) => Token::String(str),
194-
StringOrRegex::Regex(regexp) => Token::Regex(regexp),
195-
},
196-
BindingFilterTokenPayloadInner::Boolean(v) => Token::Boolean(v),
197-
BindingFilterTokenPayloadInner::Number(_) => todo!(),
198-
};
158+
let query_value = match take_payload(next_token)? {
159+
BindingFilterTokenPayloadInner::StringOrRegex(string_or_regex) => match string_or_regex {
160+
StringOrRegex::String(str) => Token::String(str),
161+
StringOrRegex::Regex(regexp) => Token::Regex(regexp),
162+
},
163+
BindingFilterTokenPayloadInner::Boolean(v) => Token::Boolean(v),
164+
BindingFilterTokenPayloadInner::Number(_) => {
165+
anyhow::bail!("number values are not supported for query filter values");
166+
}
167+
};
199168
ret.push(query_value);
200169
ret.push(Token::String(query_key));
201170
ret.push(Token::Query);
202171
iter.next();
203172
continue;
204173
}
205174
FilterTokenKind::QueryValue => {
206-
unreachable!("`QueryValue` is not expected");
175+
anyhow::bail!("`QueryValue` token should not appear without a preceding `QueryKey`");
207176
}
208177
}
209178
iter.next();
210179
}
211-
ret
180+
Ok(ret)
212181
}

crates/rolldown_binding/src/utils/normalize_binding_options.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,10 +602,10 @@ pub fn normalize_binding_options(
602602
.and_then(|plugin| plugin.remove(&index))
603603
.unwrap_or_default();
604604
let worker_manager = worker_manager.as_ref().unwrap();
605-
Ok(ParallelJsPlugin::new_shared(plugins, Arc::clone(worker_manager)))
605+
ParallelJsPlugin::new_shared(plugins, Arc::clone(worker_manager))
606606
},
607607
|plugin| match plugin {
608-
Either::A(plugin_options) => Ok(JsPlugin::new_shared(plugin_options)),
608+
Either::A(plugin_options) => JsPlugin::new_shared(plugin_options),
609609
Either::B(builtin) => {
610610
// Needs to save the name, since `try_into` will consume the ownership
611611
let name = format!("{:?}", builtin.__name);
@@ -628,7 +628,7 @@ pub fn normalize_binding_options(
628628
.chain(output_options.plugins)
629629
.filter_map(|plugin| {
630630
plugin.map(|plugin| match plugin {
631-
Either::A(plugin_options) => Ok(JsPlugin::new_shared(plugin_options)),
631+
Either::A(plugin_options) => JsPlugin::new_shared(plugin_options),
632632
Either::B(builtin) => {
633633
// Needs to save the name, since `try_into` will consume the ownership
634634
let name = format!("{:?}", builtin.__name);

0 commit comments

Comments
 (0)