Skip to content

Commit b9a962d

Browse files
LingyuCoderCopilot
andauthored
fix: compile-time evaluation of optional chaining (#12494)
* feat: support compile-time evaluation of optional chaining * Update crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 3a59c3d commit b9a962d

File tree

7 files changed

+39
-41
lines changed

7 files changed

+39
-41
lines changed

crates/rspack_plugin_javascript/src/parser_plugin/import_meta_plugin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl JavascriptParserPlugin for ImportMetaPlugin {
346346
ExportedVariableInfo::Name(root) => {
347347
if root == expr_name::IMPORT_META {
348348
let members = parser
349-
.get_member_expression_info(expr, AllowedMemberTypes::Expression)
349+
.get_member_expression_info(Expr::Member(expr.clone()), AllowedMemberTypes::Expression)
350350
.and_then(|info| match info {
351351
MemberExpressionInfo::Expression(res) => Some(res),
352352
_ => None,

crates/rspack_plugin_javascript/src/parser_plugin/url_plugin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Visit for NestedNewUrlVisitor {
3838
}
3939

4040
pub fn is_meta_url(parser: &mut JavascriptParser, expr: &MemberExpr) -> bool {
41-
let chain = parser.extract_member_expression_chain(expr);
41+
let chain = parser.extract_member_expression_chain(Expr::Member(expr.clone()));
4242
chain.object.as_meta_prop().is_some_and(|meta| {
4343
meta.kind == MetaPropKind::ImportMeta
4444
&& chain.members.len() == 1

crates/rspack_plugin_javascript/src/utils/eval/eval_member_expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn eval_member_expression<'a>(
1313
expr: &'a Expr,
1414
) -> Option<BasicEvaluatedExpression<'a>> {
1515
let ret = if let Some(MemberExpressionInfo::Expression(info)) =
16-
parser.get_member_expression_info(member, AllowedMemberTypes::Expression)
16+
parser.get_member_expression_info(Expr::Member(member.clone()), AllowedMemberTypes::Expression)
1717
{
1818
parser
1919
.plugin_drive

crates/rspack_plugin_javascript/src/visitors/dependency/parser/call_hooks_name.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl CallHooksName for MemberExpr {
7070
F: Fn(&mut JavascriptParser, &str) -> Option<T>,
7171
{
7272
let Some(MemberExpressionInfo::Expression(expr_name)) =
73-
parser.get_member_expression_info(self, AllowedMemberTypes::Expression)
73+
parser.get_member_expression_info(Expr::Member(self.clone()), AllowedMemberTypes::Expression)
7474
else {
7575
return None;
7676
};

crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ impl<'parser> JavascriptParser<'parser> {
884884
}
885885
let callee = expr.callee.as_expr()?;
886886
let (root_name, mut root_members) = if let Some(member) = callee.as_member() {
887-
let extracted = self.extract_member_expression_chain(member);
887+
let extracted = self.extract_member_expression_chain(Expr::Member(member.clone()));
888888
let root_name = extracted.object.get_root_name()?;
889889
(root_name, extracted.members)
890890
} else {
@@ -943,17 +943,17 @@ impl<'parser> JavascriptParser<'parser> {
943943
expr: &Expr,
944944
allowed_types: AllowedMemberTypes,
945945
) -> Option<MemberExpressionInfo> {
946-
expr
947-
.as_member()
948-
.and_then(|member| self.get_member_expression_info(member, allowed_types))
949-
.or_else(|| {
950-
self._get_member_expression_info(expr.clone(), vec![], vec![], vec![], allowed_types)
951-
})
946+
match expr {
947+
Expr::Member(_) | Expr::OptChain(_) => {
948+
self.get_member_expression_info(expr.clone(), allowed_types)
949+
}
950+
_ => self._get_member_expression_info(expr.clone(), vec![], vec![], vec![], allowed_types),
951+
}
952952
}
953953

954954
pub fn get_member_expression_info(
955955
&mut self,
956-
expr: &MemberExpr,
956+
expr: Expr,
957957
allowed_types: AllowedMemberTypes,
958958
) -> Option<MemberExpressionInfo> {
959959
let ExtractedMemberExpressionChainData {
@@ -971,11 +971,8 @@ impl<'parser> JavascriptParser<'parser> {
971971
)
972972
}
973973

974-
pub fn extract_member_expression_chain(
975-
&self,
976-
expr: &MemberExpr,
977-
) -> ExtractedMemberExpressionChainData {
978-
let mut object = Expr::Member(expr.clone());
974+
pub fn extract_member_expression_chain(&self, expr: Expr) -> ExtractedMemberExpressionChainData {
975+
let mut object = expr;
979976
let mut members = Vec::new();
980977
let mut members_optionals = Vec::new();
981978
let mut member_ranges = Vec::new();

crates/rspack_plugin_javascript/src/visitors/dependency/parser/walk.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,9 @@ impl JavascriptParser<'_> {
802802

803803
fn walk_member_expression(&mut self, expr: &MemberExpr) {
804804
// println!("{:#?}", expr);
805-
if let Some(expr_info) = self.get_member_expression_info(expr, AllowedMemberTypes::all()) {
805+
if let Some(expr_info) =
806+
self.get_member_expression_info(Expr::Member(expr.clone()), AllowedMemberTypes::all())
807+
{
806808
match expr_info {
807809
MemberExpressionInfo::Expression(expr_info) => {
808810
let drive = self.plugin_drive.clone();
@@ -1079,25 +1081,26 @@ impl JavascriptParser<'_> {
10791081
self._walk_iife(callee, expr.args.iter().map(|arg| &*arg.expr), None)
10801082
} else {
10811083
if let Expr::Member(member) = &**callee {
1082-
if let Some(MemberExpressionInfo::Call(expr_info)) =
1083-
self.get_member_expression_info(member, AllowedMemberTypes::CallExpression)
1084-
&& expr_info
1085-
.root_info
1086-
.call_hooks_name(self, |this, for_name| {
1087-
this
1088-
.plugin_drive
1089-
.clone()
1090-
.call_member_chain_of_call_member_chain(
1091-
this,
1092-
expr,
1093-
&expr_info.callee_members,
1094-
&expr_info.call,
1095-
&expr_info.members,
1096-
&expr_info.member_ranges,
1097-
for_name,
1098-
)
1099-
})
1100-
.unwrap_or_default()
1084+
if let Some(MemberExpressionInfo::Call(expr_info)) = self.get_member_expression_info(
1085+
Expr::Member(member.clone()),
1086+
AllowedMemberTypes::CallExpression,
1087+
) && expr_info
1088+
.root_info
1089+
.call_hooks_name(self, |this, for_name| {
1090+
this
1091+
.plugin_drive
1092+
.clone()
1093+
.call_member_chain_of_call_member_chain(
1094+
this,
1095+
expr,
1096+
&expr_info.callee_members,
1097+
&expr_info.call,
1098+
&expr_info.members,
1099+
&expr_info.member_ranges,
1100+
for_name,
1101+
)
1102+
})
1103+
.unwrap_or_default()
11011104
{
11021105
return;
11031106
}
@@ -1305,8 +1308,8 @@ impl JavascriptParser<'_> {
13051308
);
13061309
self.walk_assign_target_pattern(pat);
13071310
} else if let Some(SimpleAssignTarget::Member(member)) = expr.left.as_simple() {
1308-
if let Some(MemberExpressionInfo::Expression(expr_name)) =
1309-
self.get_member_expression_info(member, AllowedMemberTypes::Expression)
1311+
if let Some(MemberExpressionInfo::Expression(expr_name)) = self
1312+
.get_member_expression_info(Expr::Member(member.clone()), AllowedMemberTypes::Expression)
13101313
&& expr_name
13111314
.root_info
13121315
.call_hooks_name(self, |parser, for_name| {

tests/rspack-test/configCases/parsing/optional-chaining/test.filter.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)