Skip to content

Commit d171492

Browse files
committed
feat(KindMatcher): Support supertypes
1 parent 84910e3 commit d171492

File tree

5 files changed

+46
-17
lines changed

5 files changed

+46
-17
lines changed

Cargo.lock

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ ignore = { version = "0.4.22" }
3333
regex = { version = "1.10.4" }
3434
serde = { version = "1.0.200", features = ["derive"] }
3535
serde_yaml = "0.9.33"
36-
tree-sitter = { version = "0.24.4" }
36+
tree-sitter = { version = "0.25.3" }
3737
thiserror = "2.0.0"
3838
schemars = "0.8.17"
3939
anyhow = "1.0.82"

crates/core/src/matcher/kind.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,30 @@ pub enum KindMatcherError {
2424

2525
#[derive(Clone)]
2626
pub struct KindMatcher<L: Language> {
27-
kind: KindId,
27+
subtypes: BitSet,
2828
lang: PhantomData<L>,
2929
}
3030

3131
impl<L: Language> KindMatcher<L> {
3232
pub fn new(node_kind: &str, lang: L) -> Self {
33-
Self {
34-
kind: lang
33+
let mut subtypes = BitSet::new();
34+
let kind_id = lang
35+
.get_ts_language()
36+
.id_for_node_kind(node_kind, /*named*/ true);
37+
if lang.get_ts_language().node_kind_is_supertype(kind_id) {
38+
lang
3539
.get_ts_language()
36-
.id_for_node_kind(node_kind, /*named*/ true),
40+
.subtypes_for_supertype(kind_id)
41+
.iter()
42+
.for_each(|subtype| {
43+
subtypes.insert((*subtype).into());
44+
});
45+
} else {
46+
subtypes.insert(kind_id.into());
47+
}
48+
49+
Self {
50+
subtypes,
3751
lang: PhantomData,
3852
}
3953
}
@@ -48,15 +62,17 @@ impl<L: Language> KindMatcher<L> {
4862
}
4963

5064
pub fn from_id(kind: KindId) -> Self {
65+
let mut subtypes = BitSet::new();
66+
subtypes.insert(kind.into());
5167
Self {
52-
kind,
68+
subtypes,
5369
lang: PhantomData,
5470
}
5571
}
5672

5773
/// Whether the kind matcher contains undefined tree-sitter kind.
5874
pub fn is_invalid(&self) -> bool {
59-
self.kind == TS_BUILTIN_SYM_END
75+
self.subtypes.contains(TS_BUILTIN_SYM_END.into())
6076
}
6177

6278
/// Construct a matcher that only matches ERROR
@@ -87,17 +103,15 @@ impl<L: Language> Matcher<L> for KindMatcher<L> {
87103
node: Node<'tree, D>,
88104
_env: &mut Cow<MetaVarEnv<'tree, D>>,
89105
) -> Option<Node<'tree, D>> {
90-
if node.kind_id() == self.kind {
106+
if self.subtypes.contains(node.kind_id().into()) {
91107
Some(node)
92108
} else {
93109
None
94110
}
95111
}
96112

97113
fn potential_kinds(&self) -> Option<BitSet> {
98-
let mut set = BitSet::new();
99-
set.insert(self.kind.into());
100-
Some(set)
114+
Some(self.subtypes.clone())
101115
}
102116
}
103117

@@ -138,6 +152,20 @@ mod test {
138152
);
139153
}
140154

155+
#[test]
156+
fn test_supertype_match() {
157+
let supertype_kind = "declaration";
158+
let cand = pattern_node("class A { a = 123 }");
159+
let cand = cand.root();
160+
let pattern = KindMatcher::new(supertype_kind, Tsx);
161+
assert!(
162+
pattern.find_node(cand.clone()).is_some(),
163+
"goal: {}, candidate: {}",
164+
supertype_kind,
165+
cand.to_sexp(),
166+
);
167+
}
168+
141169
#[test]
142170
fn test_kind_potential_kinds() {
143171
let kind = "field_definition";

crates/dynamic/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ unsafe fn load_ts_language(
126126
.get(name.as_bytes())
127127
.map_err(DynamicLangError::ReadSymbol)?;
128128
let lang = func();
129-
let version = lang.version();
129+
let version = lang.abi_version();
130130
if !(MIN_COMPATIBLE_LANGUAGE_VERSION..=LANGUAGE_VERSION).contains(&version) {
131131
Err(DynamicLangError::IncompatibleVersion(version))
132132
} else {

crates/napi/src/doc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub struct Wrapper {
5656
impl Content for Wrapper {
5757
type Underlying = u16;
5858
fn parse_tree_sitter(&self, parser: &mut Parser, tree: Option<&Tree>) -> Option<Tree> {
59-
parser.parse_utf16(self.inner.as_slice(), tree)
59+
parser.parse_utf16_le(self.inner.as_slice(), tree)
6060
}
6161
fn get_range(&self, range: Range<usize>) -> &[Self::Underlying] {
6262
// the range is in byte offset, but our underlying is u16

0 commit comments

Comments
 (0)