Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support optional chaining in environment variable #1730

Merged
merged 2 commits into from
Dec 24, 2024

Conversation

yezaoshu
Copy link
Contributor

@yezaoshu yezaoshu commented Dec 22, 2024

Close #1729
Close #788

Summary by CodeRabbit

  • 新功能
    • 增加了对可选链表达式的支持,改进了环境变量替换逻辑。
    • 新增方法用于提取属性名称和处理链式表达式。
  • 测试
    • 扩展了测试套件,增加了多个可选链场景的测试,确保新功能的正确性。

Copy link
Contributor

coderabbitai bot commented Dec 22, 2024

概述

遍历

env_replacer.rs 文件中,对 EnvReplacer 结构体进行了增强,新增了两个方法 extract_prop_nameprocess_chain_expr。这些方法旨在处理可选链表达式,提取属性名称并递归遍历表达式树。visit_mut_expr 方法也被更新,以支持可选链表达式的环境变量替换逻辑。此外,测试套件也扩展了多个针对可选链场景的测试。

变更

文件 变更摘要
crates/mako/src/visitors/env_replacer.rs 新增 extract_prop_name 方法,用于提取属性名称
新增 process_chain_expr 方法,处理成员表达式和可选链表达式
更新 visit_mut_expr 方法,支持可选链表达式替换

诗歌

🐰 代码如链,属性飞翔
环境变量,悄然替换
可选链接,智慧闪亮
兔子编程,魔法绽放
代码之美,无限延伸


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Walkthrough

This pull request introduces support for optional chaining in environment variables within the EnvReplacer module. It adds functionality to handle optional chaining expressions and updates the environment variable replacement logic accordingly.

Changes

File Summary
crates/mako/src/visitors/env_replacer.rs Added support for optional chaining in environment variables, including new methods extract_prop_name and process_chain_expr. Implemented tests for various optional chaining scenarios.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/mako/src/visitors/env_replacer.rs (2)

37-50: extract_prop_name 函数逻辑良好,但需注意解释性注释

此函数抽取成员属性名时,兼容 Ident 和 Computed 两种情况,能正确处理字符串、数字等多种类型。不过建议补充更多注释,说明遇到其他表达式时返回 None 的原因,方便维护。


52-76: process_chain_expr 函数由于递归逻辑较复杂,建议考虑更清晰的代码结构

此函数采用递归的方式遍历可选链,能正确收集成员表达式中的属性名,并与 extract_prop_name 配合。但是逻辑嵌套较深,结构可适当拆分,使维护更容易。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd4f76 and 8095ee6.

📒 Files selected for processing (1)
  • crates/mako/src/visitors/env_replacer.rs (4 hunks)
🔇 Additional comments (8)
crates/mako/src/visitors/env_replacer.rs (8)

10-11: 可选链表达式的导入看起来正确

这里新增了对可选链表达式相关类型的导入,例如 OptChainBase 和 OptChainExpr,满足了处理可选链的需求,整体实现合理。


90-107: 对可选链的处理逻辑

在 visit_mut_expr 中对可选链表达式的处理相当完备,先收集所有属性名后再用 get_define_env 查找对应的环境变量,能够实现正确的替换逻辑。请确保对找不到定义的情况保持原表达式不变,避免引入潜在错误。


548-559: test_optional_chaining_basic 测试用例有效

此测试用例验证了最基本的 A?.B 场景,能够覆盖到可选链的基本替换逻辑,测试充分且符合需求。


561-572: test_optional_chaining_nested 测试用例确保可选链的多层嵌套

用于检测 A?.B?.C 这种更深层可选链的场景,验证了多次递归调用时的表现。该测试对于全面性很有帮助。


574-585: test_optional_chaining_with_computed 测试正确处理 A?.["B"]?.C

验证可选链与计算属性结合时的替换逻辑,有助于确保 Computed 类型属性的准确捕获。


587-598: test_optional_chaining_with_number_computed 测试数字类型索引

测试像 A?.[1]?.B 这样的场景,可覆盖数字索引的可选链处理,为特殊字符索引的正确性提供保证。


600-611: test_optional_chaining_mixed 测试混合形式可选链场景

该测试覆盖了 A?.B?.["C"]?.D 等更复杂场景,验证了多种性质组合在一起时能否正确替换。此类测试极具价值。


613-624: test_optional_chaining_not_defined 测试未定义的可选链路径

此测试用例能有效验证当查找不到对应的 key 时,是否正确保持原表达式不变,符合预期需求。

@@ -484,6 +545,84 @@ mod tests {
);
}

#[test]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要补充两类用例:

  1. optional chain 和 非 optional chain 混用的情况,入 A.B?.C;
  2. optional chain 作为 computed prop 的情况,入 A[x?.y]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已更新

Copy link

codecov bot commented Dec 23, 2024

Codecov Report

Attention: Patch coverage is 93.97590% with 5 lines in your changes missing coverage. Please review.

Project coverage is 54.79%. Comparing base (5fd4f76) to head (fe17abb).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
crates/mako/src/visitors/env_replacer.rs 93.97% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1730      +/-   ##
==========================================
+ Coverage   54.58%   54.79%   +0.20%     
==========================================
  Files         180      180              
  Lines       17958    18041      +83     
==========================================
+ Hits         9803     9885      +82     
- Misses       8155     8156       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
crates/mako/src/visitors/env_replacer.rs (3)

38-50: 需要考虑处理私有字段的情况

extract_prop_name 方法目前只处理了标识符和计算属性的情况。建议添加对私有字段(Private Fields)的支持。

 fn extract_prop_name(&self, prop: &MemberProp) -> Option<String> {
     match prop {
         MemberProp::Ident(ident) => Some(ident.sym.to_string()),
         MemberProp::Computed(computed) => match computed.expr.as_ref() {
             Expr::Lit(Lit::Str(str_lit)) => Some(str_lit.value.to_string()),
             Expr::Lit(Lit::Num(num_lit)) => Some(num_lit.value.to_string()),
             _ => None,
         },
+        MemberProp::PrivateName(private) => Some(format!("#{}", private.id.sym.to_string())),
         _ => None,
     }
 }

90-107: 建议优化错误处理和日志记录

当前的可选链处理逻辑已经实现得很好,但建议添加以下改进:

  1. 添加调试日志,便于追踪属性解析过程
  2. 在环境变量不存在时添加警告日志
 Expr::OptChain(OptChainExpr { base, .. }) => {
     if let OptChainBase::Member(member) = base.as_ref() {
         let mut parts = Vec::new();
+        tracing::debug!("Processing optional chain expression");

         if let Some(prop_name) = self.extract_prop_name(&member.prop) {
             parts.push(prop_name);

             if self.process_chain_expr(&member.obj, &mut parts) {
                 parts.reverse();
                 let full_path = parts.join(".");
+                tracing::debug!("Resolved environment path: {}", full_path);

                 if let Some(env) = self.get_define_env(&full_path) {
                     *expr = env
+                } else {
+                    tracing::warn!("Environment variable not found: {}", full_path);
                 }
             }
         }
     }
 }

548-665: 建议添加边缘情况的测试用例

当前的测试覆盖了基本场景,但建议添加以下边缘情况的测试:

  1. 深度嵌套的可选链(超过5层)
  2. 包含表达式的计算属性,如:A?.[1 + 2]?.B
  3. 空字符串作为属性名的情况
#[test]
fn test_deep_optional_chaining() {
    assert_eq!(
        run(
            r#"log(A?.B?.C?.D?.E?.F)"#,
            hashmap! {
                "A.B.C.D.E.F".to_string() => json!(42)
            }
        ),
        "log(42);"
    );
}

#[test]
fn test_optional_chaining_with_expression() {
    assert_eq!(
        run(
            r#"log(A?.[1 + 2]?.B)"#,
            hashmap! {
                "A.3.B".to_string() => json!(true)
            }
        ),
        "log(A?.[1 + 2]?.B);"
    );
}

#[test]
fn test_empty_string_property() {
    assert_eq!(
        run(
            r#"log(A?.[""]?.B)"#,
            hashmap! {
                "A..B".to_string() => json!(42)
            }
        ),
        "log(42);"
    );
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8095ee6 and fe17abb.

📒 Files selected for processing (1)
  • crates/mako/src/visitors/env_replacer.rs (4 hunks)
🔇 Additional comments (1)
crates/mako/src/visitors/env_replacer.rs (1)

69-69: 验证 unresolved_mark 的比较逻辑

需要确保 ident.ctxt.outer()self.unresolved_mark 的比较是正确的。如果 unresolved_mark 设置不当,可能导致标识符处理出现问题。

#!/bin/bash
# 描述:验证 unresolved_mark 的使用情况

# 搜索其他可能影响 unresolved_mark 设置的代码
rg -A 3 "unresolved_mark\s*=|set_unresolved_mark"

# 搜索其他使用 ctxt.outer() 进行比较的地方
ast-grep --pattern 'ctxt.outer() == $_'

@sorrycc sorrycc merged commit ab465e2 into umijs:master Dec 24, 2024
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants