Skip to content

[PoC] feat: PoC for supertype matcher #1784

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

Closed
wants to merge 1 commit into from

Conversation

mohebifar
Copy link
Member

@mohebifar mohebifar commented Feb 3, 2025

Tree-sitter recently added APIs for getting supertype info. Currently, if you want to match all expressions, you need to use an any rule for each of the expression types.

any:
  - kind: call_expression
  -  kind: assignment_expression
  - ...

With supertypes, you can simply do:

supertype: expression

which will match all expressions.

Also, currently, ast-grep accepts super types as kinds, but it never matches any nodes. Meaning that,

kind: expression

doesn't produce an invalid_kind error, yet it doesn't match anything.

🚫 NOTE

  • This change, requires updates in the facade crate to upgrade tree-sitter to the latest version and expose these nodes.
  • It also requires all the language parsers to be rebuilt and regenerated using the latest version of tree-sitter-cli

Summary by CodeRabbit

  • New Features

    • Enhanced rule matching now allows for specifying node supertypes, providing users with more expressive criteria for pattern detection.
  • Chores

    • Upgraded core dependencies, including updates to tree-sitter and tree-sitter-typescript, to bolster overall stability and performance.

tree-sitter-typescript = { package = "tree-sitter-typescript-codemod", version = "0.25.0-codemod.1"}
Copy link
Member Author

Choose a reason for hiding this comment

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

I just manually rebuilt tree-sitter-typescript with the latest version of the ts cli.

@@ -33,7 +33,7 @@ ignore = { version = "0.4.22" }
regex = { version = "1.10.4" }
serde = { version = "1.0.200", features = ["derive"] }
serde_yaml = "0.9.33"
tree-sitter = { version = "0.24.5", package = "tree-sitter-facade-sg" }
tree-sitter = { version = "0.25.0-codemod.2", package = "tree-sitter-facade-sg-codemod" }
Copy link
Member Author

Choose a reason for hiding this comment

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

Just a copy of the facade package with the new methods node_kind_is_supertype and supertypes exposed.

@mohebifar mohebifar marked this pull request as ready for review February 3, 2025 05:52
Copy link
Contributor

coderabbitai bot commented Feb 3, 2025

Walkthrough

This pull request updates several tree-sitter dependency versions and package names in multiple Cargo.toml files. It replaces function calls with constant references for obtaining the TypeScript language in both configuration and core modules. Additionally, new matcher functionality for handling supertypes is introduced, including modifications to rule structures, a new Rule variant, and the implementation of a SupertypeMatcher with corresponding tests.

Changes

File(s) Change Summary
Cargo.toml, crates/config/Cargo.toml, crates/core/Cargo.toml, crates/dynamic/Cargo.toml Updated dependency definitions: tree-sitter upgraded from 0.24.5 to 0.25.0-codemod.2, tree-sitter-typescript from "0.21.1" to { package: "tree-sitter-typescript-codemod", version: "0.25.0-codemod.1" }, and tree-sitter-native from 0.24.4 to 0.25.1.
crates/config/src/lib.rs, crates/core/src/language.rs Replaced function calls (language_tsx()) with constant references (LANGUAGE_TSX) for retrieving the TypeScript language.
crates/config/src/rule/mod.rs Added a new public supertype field to rule structs, along with a new Rule enum variant Supertype(SupertypeMatcher<L>) to support supertype-based matching.
crates/core/src/matcher.rs, crates/core/src/matcher/kind.rs, crates/core/src/matcher/supertype.rs Introduced a new module for supertype matching: added SupertypeMatcher (with methods new, try_new, from_id, and is_invalid) and SupertypeMatcherError; updated KindMatcher to reset node kind if identified as a supertype and augmented tests accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant R as Rule Engine
    participant SM as SupertypeMatcher
    participant L as Language
    participant N as Node

    R->>SM: match_node_with_env(Node, env)
    SM->>L: Retrieve supertype & subtype info
    L-->>SM: Return language constants and node kind details
    SM->>N: Compare node kind against subtype set
    SM-->>R: Return matched node (or null)
Loading

Possibly related PRs

Poem

I hopped through lines of code so bright,
Upgrading deps with all my might.
Supertypes bloom in fields of green,
New matchers dance, crisp and keen.
A rabbit's joy in every mod,
Coding paths where dreams are trod! 🐇


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

codecov bot commented Feb 3, 2025

Codecov Report

Attention: Patch coverage is 73.07692% with 28 lines in your changes missing coverage. Please review.

Project coverage is 87.27%. Comparing base (ec147d3) to head (312c47f).
Report is 121 commits behind head on main.

Files with missing lines Patch % Lines
crates/core/src/matcher/supertype.rs 77.38% 19 Missing ⚠️
crates/config/src/rule/mod.rs 27.27% 8 Missing ⚠️
crates/core/src/matcher/kind.rs 85.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1784      +/-   ##
==========================================
- Coverage   87.38%   87.27%   -0.12%     
==========================================
  Files          96       97       +1     
  Lines       15521    15620      +99     
==========================================
+ Hits        13563    13632      +69     
- Misses       1958     1988      +30     

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

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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: 3

🧹 Nitpick comments (1)
crates/core/src/matcher/supertype.rs (1)

89-141: Consider adding edge case tests.

While the current tests cover the basic functionality, consider adding tests for:

  • Invalid supertype names
  • Empty subtypes list
  • Multiple levels of inheritance
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 107-109: crates/core/src/matcher/supertype.rs#L107-L109
Added lines #L107 - L109 were not covered by tests


[warning] 125-127: crates/core/src/matcher/supertype.rs#L125-L127
Added lines #L125 - L127 were not covered by tests

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ec147d3 and d512c17.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • Cargo.toml (1 hunks)
  • crates/config/Cargo.toml (1 hunks)
  • crates/config/src/lib.rs (1 hunks)
  • crates/config/src/rule/mod.rs (10 hunks)
  • crates/core/Cargo.toml (1 hunks)
  • crates/core/src/language.rs (1 hunks)
  • crates/core/src/matcher.rs (2 hunks)
  • crates/core/src/matcher/kind.rs (2 hunks)
  • crates/core/src/matcher/supertype.rs (1 hunks)
  • crates/dynamic/Cargo.toml (1 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
crates/config/src/rule/mod.rs

[warning] 272-272: crates/config/src/rule/mod.rs#L272
Added line #L272 was not covered by tests


[warning] 293-293: crates/config/src/rule/mod.rs#L293
Added line #L293 was not covered by tests


[warning] 320-320: crates/config/src/rule/mod.rs#L320
Added line #L320 was not covered by tests


[warning] 343-343: crates/config/src/rule/mod.rs#L343
Added line #L343 was not covered by tests


[warning] 508-511: crates/config/src/rule/mod.rs#L508-L511
Added lines #L508 - L511 were not covered by tests

crates/core/src/matcher/kind.rs

[warning] 37-37: crates/core/src/matcher/kind.rs#L37
Added line #L37 was not covered by tests

crates/core/src/matcher/supertype.rs

[warning] 36-37: crates/core/src/matcher/supertype.rs#L36-L37
Added lines #L36 - L37 were not covered by tests


[warning] 42-47: crates/core/src/matcher/supertype.rs#L42-L47
Added lines #L42 - L47 were not covered by tests


[warning] 49-49: crates/core/src/matcher/supertype.rs#L49
Added line #L49 was not covered by tests


[warning] 51-51: crates/core/src/matcher/supertype.rs#L51
Added line #L51 was not covered by tests


[warning] 66-68: crates/core/src/matcher/supertype.rs#L66-L68
Added lines #L66 - L68 were not covered by tests


[warning] 107-109: crates/core/src/matcher/supertype.rs#L107-L109
Added lines #L107 - L109 were not covered by tests


[warning] 125-127: crates/core/src/matcher/supertype.rs#L125-L127
Added lines #L125 - L127 were not covered by tests

🪛 GitHub Actions: coverage
crates/core/src/matcher/kind.rs

[warning] 115-115: unused variable: b. If this is intentional, prefix it with an underscore: _b


[warning] 116-116: unused variable: c. If this is intentional, prefix it with an underscore: _c

🔇 Additional comments (15)
crates/core/src/language.rs (1)

88-90: LGTM! Consistent with the TypeScript language reference update.

The change from function call to constant reference aligns with similar updates across the codebase.

crates/core/src/matcher/supertype.rs (2)

15-19: LGTM! Clear error handling.

The error type is well-defined and uses thiserror for deriving the Error trait.


71-87: LGTM! Clean and efficient matcher implementation.

The implementation correctly uses BitSet for tracking subtypes and provides efficient matching.

crates/core/src/matcher/kind.rs (1)

33-38: LGTM! Proper supertype handling.

The implementation correctly resets the kind ID when a supertype is detected.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 37-37: crates/core/src/matcher/kind.rs#L37
Added line #L37 was not covered by tests

crates/config/src/lib.rs (1)

58-58: LGTM! Consistent TypeScript language reference update.

The change from function call to constant reference aligns with similar updates across the codebase.

crates/core/src/matcher.rs (2)

11-11: LGTM!

The new module declaration follows the existing pattern and is placed appropriately with other matcher modules.


25-25: LGTM!

The new exports follow the existing pattern of exporting matcher types and their associated error types.

crates/config/src/rule/mod.rs (4)

65-67: LGTM!

The new supertype field is well-documented and follows the existing pattern of optional fields.


142-142: LGTM!

The supertype field in AtomicRule aligns with the serializable version.


221-221: LGTM!

The new Supertype variant in the Rule enum follows the existing pattern of atomic matchers.


272-272: Add test coverage for supertype matcher integration.

Several methods handling the supertype matcher lack test coverage:

  • defined_vars for supertype
  • verify_util for supertype
  • match_node_with_env for supertype
  • potential_kinds for supertype

Consider adding test cases that verify the integration of supertype matching with the existing matcher framework.

Also applies to: 293-293, 320-320, 343-343

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 272-272: crates/config/src/rule/mod.rs#L272
Added line #L272 was not covered by tests

crates/dynamic/Cargo.toml (1)

20-20: LGTM!

The update to tree-sitter version 0.25.1 is necessary for supertype support.

crates/core/Cargo.toml (1)

26-26: LGTM!

The update to the custom codemod version of tree-sitter-typescript aligns with the manual rebuild mentioned in the previous review.

crates/config/Cargo.toml (1)

29-29: Update tree-sitter-typescript Dependency Specification
The dependency for tree-sitter-typescript has been updated from a simple version string to a more structured declaration:

tree-sitter-typescript = { package = "tree-sitter-typescript-codemod", version = "0.25.0-codemod.1" }

This change standardizes the dependency across the project and aligns with the codemod strategy. Please verify that this new specification is compatible with all parts of the codebase that utilize this dependency.

Cargo.toml (1)

36-36: Update tree-sitter Dependency to Codemod Version
The tree-sitter dependency has been updated to:

tree-sitter = { version = "0.25.0-codemod.2", package = "tree-sitter-facade-sg-codemod" }

This update reflects the shift to using the codemod version of the Tree-sitter façade. Please ensure that all modules relying on Tree-sitter are tested for compatibility with the latest API changes introduced by this codemod version.

Comment on lines +21 to +69
#[derive(Clone)]
pub struct SupertypeMatcher<L: Language> {
supertype: KindId,
subtypes: BitSet,
lang: PhantomData<L>,
}

impl<L: Language> SupertypeMatcher<L> {
pub fn new(supertype_kind: &str, lang: L) -> Self {
let mut supertype_kind = lang
.get_ts_language()
.id_for_node_kind(supertype_kind, /*named*/ true);
if !lang
.get_ts_language()
.node_kind_is_supertype(supertype_kind)
{
supertype_kind = 0;
}
Self::from_id(supertype_kind, lang)
}

pub fn try_new(supertype_kind: &str, lang: L) -> Result<Self, SupertypeMatcherError> {
let s = Self::new(supertype_kind, lang);
if s.is_invalid() {
Err(SupertypeMatcherError::InvalidKindName(
supertype_kind.into(),
))
} else {
Ok(s)
}
}

pub fn from_id(supertype: KindId, lang: L) -> Self {
let mut subtypes = BitSet::new();
for kind in lang.get_ts_language().subtypes_for_supertype(supertype) {
subtypes.insert(kind as usize);
}
Self {
supertype,
subtypes,
lang: PhantomData,
}
}

/// Whether the kind matcher contains undefined tree-sitter kind.
pub fn is_invalid(&self) -> bool {
self.supertype == TS_BUILTIN_SYM_END
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Error Handling Test Coverage is Missing
Our investigation shows that none of the error paths in SupertypeMatcher are exercised by any tests. Specifically:

  • The error branch in the new() function (lines 36–37) that validates the supertype.
  • The error handling in try_new() (lines 42–51) triggering SupertypeMatcherError::InvalidKindName.
  • The is_invalid() method (lines 66–68) isn’t being validated via tests.

Please add tests to cover these scenarios.

🔗 Analysis chain

Add test coverage for error handling paths.

The implementation looks good, but some error handling paths are not covered by tests:

  • Lines 36-37: Supertype validation
  • Lines 42-51: Error handling in try_new
  • Lines 66-68: is_invalid method
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify test coverage for error handling paths

# Test: Check for test cases that cover error handling
rg -A 5 'test.*invalid|test.*error' crates/core/src/matcher/supertype.rs

Length of output: 74


Script:

#!/bin/bash
# Description: Verify test coverage for SupertypeMatcher error handling by searching across the repository for tests 
# that invoke error paths or reference related error messages.

echo "Searching for test invocations of try_new() in Rust files:"
rg -n "SupertypeMatcher::try_new" -t rust

echo -e "\nSearching for tests referencing error variants (e.g., InvalidKindName) in Rust files:"
rg -n "InvalidKindName" -t rust

echo -e "\nSearching for general error tests in modules related to matcher in Rust files:"
rg -n "SupertypeMatcherError" -t rust

Length of output: 1299


Script:

#!/bin/bash
# Description: Search for tests in the repository that cover error handling paths of SupertypeMatcher, 
# particularly tests that call try_new() with invalid parameters to trigger the error paths.

echo "Searching for test cases in the tests/ directory that reference try_new:"
rg -n "try_new" tests/

echo -e "\nSearching for test cases in the tests/ directory that reference InvalidKindName:"
rg -n "InvalidKindName" tests/

Length of output: 479

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 36-37: crates/core/src/matcher/supertype.rs#L36-L37
Added lines #L36 - L37 were not covered by tests


[warning] 42-47: crates/core/src/matcher/supertype.rs#L42-L47
Added lines #L42 - L47 were not covered by tests


[warning] 49-49: crates/core/src/matcher/supertype.rs#L49
Added line #L49 was not covered by tests


[warning] 51-51: crates/core/src/matcher/supertype.rs#L51
Added line #L51 was not covered by tests


[warning] 66-68: crates/core/src/matcher/supertype.rs#L66-L68
Added lines #L66 - L68 were not covered by tests

Comment on lines +507 to +512
if let Some(supertype) = atomic.supertype {
rules.push(R::Supertype(SupertypeMatcher::new(
&supertype,
env.lang.clone(),
)));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Supertype deserialization not adequately covered in tests

The grep results show tests in other areas (e.g. in matcher and pattern tests), but there isn’t any dedicated test exercising the configuration deserialization branch where a supertype is parsed (the code at crates/config/src/rule/mod.rs, lines 507–512). We need to add tests that ensure:

  • Successful deserialization of supertype rules from valid inputs.
  • Correct error handling when invalid supertypes are provided.
  • Proper integration of supertype rules with other kinds of rules in the overall config.
🔗 Analysis chain

Add test coverage for supertype deserialization.

The supertype deserialization logic lacks test coverage. Consider adding tests to verify:

  1. Successful deserialization of supertype rules
  2. Error handling for invalid supertypes
  3. Integration with other rule types
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check test coverage for supertype-related code

# Look for existing tests related to supertype
rg -l "test.*supertype" .

# Look for test patterns that could be adapted for supertype
rg "test_pattern|test_deserialize_rule" .

Length of output: 1851

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 508-511: crates/config/src/rule/mod.rs#L508-L511
Added lines #L508 - L511 were not covered by tests

@mohebifar mohebifar force-pushed the feat/supertype-matcher branch from d512c17 to 312c47f Compare February 3, 2025 05:56
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: 1

♻️ Duplicate comments (1)
crates/config/src/rule/mod.rs (1)

507-512: ⚠️ Potential issue

Error handling in supertype deserialization needs improvement.

The code uses new() which silently fails, instead of try_new() which properly handles errors.

Apply this diff to improve error handling:

   if let Some(supertype) = atomic.supertype {
-    rules.push(R::Supertype(SupertypeMatcher::new(
+    rules.push(R::Supertype(SupertypeMatcher::try_new(
       &supertype,
       env.lang.clone(),
-    )));
+    )?));
   }
🧹 Nitpick comments (2)
crates/core/src/matcher/supertype.rs (1)

15-19: Error handling needs expansion.

The error handling is minimal with only one error variant. Consider adding more specific error cases for:

  • Invalid supertype (not a valid tree-sitter kind)
  • Non-supertype (valid kind but not a supertype)
 #[derive(Debug, Error)]
 pub enum SupertypeMatcherError {
     #[error("Kind `{0}` is invalid.")]
     InvalidKindName(String),
+    #[error("Kind `{0}` is not a valid tree-sitter kind.")]
+    InvalidTreeSitterKind(String),
+    #[error("Kind `{0}` is not a supertype.")]
+    NotASupertype(String),
 }
crates/config/src/rule/mod.rs (1)

65-67: Documentation needs improvement.

The supertype field documentation is minimal. Consider adding:

  • Example usage
  • Explanation of supertype concept
  • Link to related documentation
-  /// The supertype name of the node to match.
+  /// The supertype name of the node to match. Supertypes represent abstract node types
+  /// that encompass multiple concrete node types. For example, 'declaration' is a supertype
+  /// that matches class_declaration, function_declaration, etc.
+  /// 
+  /// Example:
+  /// ```yaml
+  /// supertype: declaration
+  /// ```
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d512c17 and 312c47f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • Cargo.toml (1 hunks)
  • crates/config/Cargo.toml (1 hunks)
  • crates/config/src/lib.rs (1 hunks)
  • crates/config/src/rule/mod.rs (10 hunks)
  • crates/core/Cargo.toml (1 hunks)
  • crates/core/src/language.rs (1 hunks)
  • crates/core/src/matcher.rs (2 hunks)
  • crates/core/src/matcher/kind.rs (1 hunks)
  • crates/core/src/matcher/supertype.rs (1 hunks)
  • crates/dynamic/Cargo.toml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • crates/dynamic/Cargo.toml
  • crates/config/src/lib.rs
  • crates/core/src/language.rs
  • crates/config/Cargo.toml
  • Cargo.toml
  • crates/core/Cargo.toml
  • crates/core/src/matcher/kind.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: coverage
🔇 Additional comments (2)
crates/core/src/matcher/supertype.rs (1)

89-141: Test coverage needs improvement.

Current tests only cover the happy path. Missing test cases for:

  1. Invalid kind names
  2. Non-supertype kinds
  3. Edge cases in potential_kinds()

Run this script to analyze current test coverage:

crates/core/src/matcher.rs (1)

11-11: LGTM! Clean integration of the supertype module.

The changes properly integrate the new supertype functionality while maintaining the existing structure.

Also applies to: 25-25

Comment on lines +29 to +40
pub fn new(supertype_kind: &str, lang: L) -> Self {
let mut supertype_kind = lang
.get_ts_language()
.id_for_node_kind(supertype_kind, /*named*/ true);
if !lang
.get_ts_language()
.node_kind_is_supertype(supertype_kind)
{
supertype_kind = 0;
}
Self::from_id(supertype_kind, lang)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Silent failure in new() method needs attention.

The method silently sets supertype_kind to 0 when validation fails. This could lead to subtle bugs as callers won't know about the failure.

Consider using try_new() instead, which properly handles errors:

-  pub fn new(supertype_kind: &str, lang: L) -> Self {
-    let mut supertype_kind = lang
-      .get_ts_language()
-      .id_for_node_kind(supertype_kind, /*named*/ true);
-    if !lang
-      .get_ts_language()
-      .node_kind_is_supertype(supertype_kind)
-    {
-      supertype_kind = 0;
-    }
-    Self::from_id(supertype_kind, lang)
-  }
+  pub fn new(supertype_kind: &str, lang: L) -> Result<Self, SupertypeMatcherError> {
+    Self::try_new(supertype_kind, lang)
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn new(supertype_kind: &str, lang: L) -> Self {
let mut supertype_kind = lang
.get_ts_language()
.id_for_node_kind(supertype_kind, /*named*/ true);
if !lang
.get_ts_language()
.node_kind_is_supertype(supertype_kind)
{
supertype_kind = 0;
}
Self::from_id(supertype_kind, lang)
}
pub fn new(supertype_kind: &str, lang: L) -> Result<Self, SupertypeMatcherError> {
Self::try_new(supertype_kind, lang)
}

@HerringtonDarkholme
Copy link
Member

HerringtonDarkholme commented Feb 3, 2025

I'm not sure if supertype should be included as an API.

utils:
  declaration:
    any:
    - kind: class_declaration
    - kind: function_declaration
    - kind: generator_function_declaration
    - kind: lexical_declaration
    - kind: variable_declaration

which is equivalent to

{
  "type": "_declaration",
  "named": true,
  "subtypes": [
    { "type": "class_declaration", "named": true },
    { "type": "function_declaration", "named": true },
    { "type": "generator_function_declaration", "named": true },
    { "type": "lexical_declaration", "named": true },
    { "type": "variable_declaration", "named": true }
  ]
}
  • It also exposes more possibility of introducing breaking change when updating tree-sitter grammar.
  • Lastly, it adds a new API surface to learn. Yet it is not too powerful.

@mohebifar
Copy link
Member Author

I'm not sure if supertype should be included as an API.

utils:
  declaration:
    any:
    - kind: class_declaration
    - kind: function_declaration
    - kind: generator_function_declaration
    - kind: lexical_declaration
    - kind: variable_declaration

which is equivalent to

{
  "type": "_declaration",
  "named": true,
  "subtypes": [
    { "type": "class_declaration", "named": true },
    { "type": "function_declaration", "named": true },
    { "type": "generator_function_declaration", "named": true },
    { "type": "lexical_declaration", "named": true },
    { "type": "variable_declaration", "named": true }
  ]
}
  • It also exposes more possibility of introducing breaking change when updating tree-sitter grammar.
  • Lastly, it adds a new API surface to learn. Yet it is not too powerful.

Fair points, in that case, I think the least we can and should do is to disallow using supertypes in the kind position. Right now, if you pass any invalid kind, you'll get an error. Supertypes don't create an error and at the same time never match anything.
Screenshot 2025-02-03 at 10 21 31 AM

Screenshot 2025-02-03 at 10 21 53 AM

@HerringtonDarkholme
Copy link
Member

disallow using supertypes in the kind position

this is also a valid solution.

Alternatively, we can support supertype in kind without introducing new APIs. This may be even better.

@mohebifar
Copy link
Member Author

Alternatively, we can support supertype in kind without introducing new APIs. This may be even better.

Sure! If that sounds good to you I can send a PR to tree-sitter-wasm and update this one accordingly.

@HerringtonDarkholme
Copy link
Member

send a PR to tree-sitter-wasm and update this one accordingly

Yes please!

@mohebifar
Copy link
Member Author

Closing in favor of #1875

@mohebifar mohebifar closed this Mar 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants