feat: Add fieldChildren method to napi's SgNode and pyo3's PyNode#1655
Conversation
WalkthroughThe pull request introduces enhancements to the Changes
Possibly related PRs
Suggested reviewers
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
crates/napi/__test__/index.spec.ts (1)
323-330: LGTM: Test case is well-structured, but could be expandedThe test effectively verifies the basic functionality. Consider adding additional test cases for:
- Empty fields (no attributes)
- Nested JSX elements with multiple fields
- Fields with different names
Example additional test cases:
test('fieldChildren handles empty fields correctly', t => { const sg = tsx.parse('const el = <div />') const jsxElement = sg.root().find(tsx.kind('jsx_self_closing_element'))! const fields = jsxElement.fieldChildren('attribute') t.is(fields.length, 0) }) test('fieldChildren works with nested elements', t => { const sg = tsx.parse('const el = <div><span id="1" /><span id="2" /></div>') const jsxElement = sg.root().find(tsx.kind('jsx_element'))! const fields = jsxElement.fieldChildren('jsx_element') t.is(fields.length, 2) })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
crates/napi/__test__/index.spec.ts(1 hunks)crates/napi/index.d.ts(1 hunks)crates/napi/src/sg_node.rs(2 hunks)
🔇 Additional comments (3)
crates/napi/src/sg_node.rs (2)
261-261: LGTM: Documentation clarification is accurate
The updated documentation clearly specifies that the method returns the first child node, which helps distinguish it from the new fieldChildren method.
273-283: LGTM: Implementation is clean and consistent
The implementation follows the established patterns in the codebase:
- Uses consistent parameter types and naming
- Leverages existing helper methods
- Properly handles type conversions
crates/napi/index.d.ts (1)
134-134: LGTM: Type definitions are accurate and well-documented
The TypeScript declarations are consistent with the Rust implementation:
- Return types match the Rust signatures
- Documentation follows the established style
- Method naming follows JavaScript conventions
Also applies to: 136-137
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1655 +/- ##
==========================================
+ Coverage 87.06% 87.11% +0.05%
==========================================
Files 95 96 +1
Lines 15340 15458 +118
==========================================
+ Hits 13356 13467 +111
- Misses 1984 1991 +7 ☔ View full report in Codecov by Sentry. |
|
Thanks. Can you also port this change to Python API? |
|
Will do now. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (2)
crates/pyo3/src/py_node.rs (1)
171-180: LGTM! Consider adding docstring.The implementation follows the established pattern for node traversal methods and correctly maintains the root reference. Consider adding a docstring to document the method's purpose and return type.
Add a docstring similar to this:
+ /// Returns all child nodes that match the given field name. + /// + /// # Arguments + /// * `name` - The field name to match + /// + /// # Returns + /// A vector of matching child nodes fn field_children(&self, name: &str) -> Vec<SgNode> {crates/pyo3/tests/test_traversal.py (1)
47-57: LGTM! Consider adding more test cases.The test effectively verifies the basic functionality of
field_children. Consider adding these additional test cases:Add tests for:
- Empty case (node with no matching fields)
- Single field case
- Nested fields case
Example:
def test_field_children_edge_cases(): # Test empty case source = '<div></div>' sg = SgRoot(source, "tsx") node = sg.root().find(kind="jsx_element") assert node attributes = node.field_children("attribute") assert len(attributes) == 0 # Test single field source = '<div id="foo"></div>' sg = SgRoot(source, "tsx") node = sg.root().find(kind="jsx_element") assert node attributes = node.field_children("attribute") assert len(attributes) == 1 assert attributes[0].text() == 'id="foo"' # Test nested fields source = '<div><span id="nested">text</span></div>' sg = SgRoot(source, "tsx") node = sg.root().find(kind="jsx_element") assert node children = node.field_children("child") assert len(children) == 1 nested_attrs = children[0].field_children("attribute") assert len(nested_attrs) == 1 assert nested_attrs[0].text() == 'id="nested"'
done! |
78b7715 to
d8abcc5
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
crates/pyo3/ast_grep_py/ast_grep_py.pyi (1)
57-57: LGTM! Consider adding docstring type hints.The method signature follows Python naming conventions and aligns well with existing tree traversal methods. The return type is consistent with other plural methods in the class.
Consider adding docstring type hints for better IDE support:
- def field_children(self, name: str) -> List[SgNode]: ... + def field_children(self, name: str) -> List[SgNode]: + """Get all child nodes that match the given field name. + + Args: + name (str): The field name to match + + Returns: + List[SgNode]: List of child nodes matching the field name + """ + ...
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
crates/pyo3/ast_grep_py/ast_grep_py.pyi(1 hunks)crates/pyo3/src/py_node.rs(1 hunks)crates/pyo3/tests/test_traversal.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- crates/pyo3/src/py_node.rs
- crates/pyo3/tests/test_traversal.py
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [ast-grep/ast-grep](https://github.com/ast-grep/ast-grep) | minor | `0.31.1` -> `0.32.2` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>ast-grep/ast-grep (ast-grep/ast-grep)</summary> ### [`v0.32.2`](https://github.com/ast-grep/ast-grep/blob/HEAD/CHANGELOG.md#0322) [Compare Source](ast-grep/ast-grep@0.32.1...0.32.2) - fix: linting [`10f3e74`](ast-grep/ast-grep@10f3e74) - feat: distinguish manual type annotation [`4558c48`](ast-grep/ast-grep@4558c48) - feat: add ChildTypes helper [`0d477e9`](ast-grep/ast-grep@0d477e9) ### [`v0.32.1`](https://github.com/ast-grep/ast-grep/blob/HEAD/CHANGELOG.md#0321) [Compare Source](ast-grep/ast-grep@0.32.0...0.32.1) > 17 December 2024 - fix(deps): update rust crate clap_complete to v4.5.39 [`6ad3c7b`](ast-grep/ast-grep@6ad3c7b) - fix: add npmignore to suppress gitignore [`11bb8e4`](ast-grep/ast-grep@11bb8e4) ### [`v0.32.0`](https://github.com/ast-grep/ast-grep/blob/HEAD/CHANGELOG.md#0320) [Compare Source](ast-grep/ast-grep@0.31.1...0.32.0) > 17 December 2024 - feat: Add fieldChildren method to napi's SgNode and pyo3's PyNode [`#1655`](ast-grep/ast-grep#1655) - **Breaking change:** fix: rename range rule's row to line [`#1663`](ast-grep/ast-grep#1663) - fix: add biome formatting [`5a41f13`](ast-grep/ast-grep@5a41f13) - feat(napi): Typed SgNode and SgRoot [`55e65f3`](ast-grep/ast-grep@55e65f3) - fix: Use ts-node and versioned node-types URLs instead of heads [`dcb7916`](ast-grep/ast-grep@dcb7916) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS43Ny4wIiwidXBkYXRlZEluVmVyIjoiMzkuNzcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
napi's SgNode currently only exposes afieldmethod that returns the first node matching the given field name. However, there are some cases where a node can have multiple children with the same field. For example, ajsx_elementin TSX has multipleattributefields.This new
fieldChildrenreturns an array of all the matching nodes.Summary by CodeRabbit