Skip to content

Commit bd3ceb6

Browse files
committed
fix: remove parent() calls, upgrade tree-sitter, fix PHP method call detection
1 parent 7bee8c8 commit bd3ceb6

File tree

5 files changed

+22
-56
lines changed

5 files changed

+22
-56
lines changed

native/Cargo.lock

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

native/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ crate-type = ["cdylib"]
1616
napi = { version = "2.16", default-features = false, features = ["napi9", "async", "serde-json"] }
1717
napi-derive = "2.16"
1818

19-
tree-sitter = "0.24"
19+
tree-sitter = "0.26.8"
2020
tree-sitter-typescript = "0.23"
2121
tree-sitter-javascript = "0.23"
2222
tree-sitter-python = "0.23"

native/queries/typescript-calls.scm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
; -------------------------------------------------------------
1717
(call_expression
1818
function: (member_expression
19-
property: (property_identifier) @callee.name)) @call
19+
property: (property_identifier) @callee.name)) @method.call
2020

2121
; -------------------------------------------------------------
2222
; Constructor calls: new Foo(), new Bar(args)

native/src/call_extractor.rs

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ pub fn extract_calls(content: &str, language_name: &str) -> Result<Vec<CallSite>
5656
_ => return Ok(vec![]),
5757
};
5858

59-
// Limit query analysis to prevent tree-sitter internal bugs
6059
let query = Query::new(&ts_language, query_source)
6160
.map_err(|e| anyhow!("Failed to compile query: {}", e))?;
6261

@@ -157,47 +156,17 @@ pub fn extract_calls(content: &str, language_name: &str) -> Result<Vec<CallSite>
157156
}
158157
}
159158

160-
// Safely detect method calls using query context analysis
161-
// For PHP: check if the call is wrapped in a method call pattern
162-
if let (Some(name), Some(CallType::Call), Some(pos)) = (&callee_name, call_type, position) {
163-
let is_method_call = match language {
164-
Language::TypeScript
165-
| Language::TypeScriptTsx
166-
| Language::JavaScript
167-
| Language::JavaScriptJsx => match_.captures.iter().any(|c| {
168-
callee_name_idx.map(|idx| c.index == idx).unwrap_or(false)
169-
&& (c.node.kind() == "property_identifier" || c.node.kind() == "identifier")
170-
}),
171-
Language::Python => match_.captures.iter().any(|c| {
172-
callee_name_idx.map(|idx| c.index == idx).unwrap_or(false)
173-
&& c.node.kind() == "identifier"
174-
}),
175-
Language::Rust => match_.captures.iter().any(|c| {
176-
callee_name_idx.map(|idx| c.index == idx).unwrap_or(false)
177-
&& c.node.kind() == "field_identifier"
178-
}),
179-
Language::Go => match_.captures.iter().any(|c| {
180-
callee_name_idx.map(|idx| c.index == idx).unwrap_or(false)
181-
&& c.node.kind() == "field_identifier"
182-
}),
183-
Language::Php => {
184-
// PHP method calls are already marked in query (@method.call, @static.call)
185-
// @call is only for direct function calls
186-
// So if we reach here with CallType::Call, it's definitely not a method call
187-
false
188-
}
189-
_ => false,
190-
};
191-
192-
let final_call_type = if is_method_call {
193-
CallType::MethodCall
194-
} else {
195-
CallType::Call
196-
};
197-
159+
// PHP method calls are already marked in query (@method.call, @static.call)
160+
// @call is only for direct function calls
161+
// So we need to check if the call was already classified as a method call
162+
if let (Some(name), Some(ct), Some(pos)) = (callee_name, call_type, position) {
198163
// PHP function/method names are case-insensitive; normalize to lowercase
199164
// so that HELPER() matches symbol helper during resolution and lookup.
200-
let normalized_name = if language == Language::Php {
165+
// Import names and constructor names should keep their original case for proper symbol resolution
166+
let normalized_name = if language == Language::Php
167+
&& ct != CallType::Import
168+
&& ct != CallType::Constructor
169+
{
201170
name.to_lowercase()
202171
} else {
203172
name.clone()
@@ -207,13 +176,6 @@ pub fn extract_calls(content: &str, language_name: &str) -> Result<Vec<CallSite>
207176
callee_name: normalized_name,
208177
line: pos.0,
209178
column: pos.1,
210-
call_type: final_call_type,
211-
});
212-
} else if let (Some(name), Some(ct), Some(pos)) = (callee_name, call_type, position) {
213-
calls.push(CallSite {
214-
callee_name: name,
215-
line: pos.0,
216-
column: pos.1,
217179
call_type: ct,
218180
});
219181
}

native/src/parser.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ fn extract_name(cursor: &tree_sitter::TreeCursor, source: &str) -> Option<String
497497
};
498498

499499
for i in 0..node.child_count() {
500-
if let Some(child) = node.child(i) {
500+
if let Some(child) = node.child(i.try_into().unwrap()) {
501501
if let Some(name) = extract_identifier(child) {
502502
#[cfg(debug_assertions)]
503503
{
@@ -511,7 +511,7 @@ fn extract_name(cursor: &tree_sitter::TreeCursor, source: &str) -> Option<String
511511

512512
if node.kind() == "export_statement" {
513513
for i in 0..node.child_count() {
514-
if let Some(child) = node.child(i) {
514+
if let Some(child) = node.child(i.try_into().unwrap()) {
515515
let child_kind = child.kind();
516516
if matches!(
517517
child_kind,
@@ -524,7 +524,7 @@ fn extract_name(cursor: &tree_sitter::TreeCursor, source: &str) -> Option<String
524524
| "abstract_class_declaration"
525525
) {
526526
for j in 0..child.child_count() {
527-
if let Some(grandchild) = child.child(j) {
527+
if let Some(grandchild) = child.child(j.try_into().unwrap()) {
528528
if let Some(name) = extract_identifier(grandchild) {
529529
#[cfg(debug_assertions)]
530530
{
@@ -538,10 +538,12 @@ fn extract_name(cursor: &tree_sitter::TreeCursor, source: &str) -> Option<String
538538

539539
if child_kind == "lexical_declaration" {
540540
for j in 0..child.child_count() {
541-
if let Some(declarator) = child.child(j) {
541+
if let Some(declarator) = child.child(j.try_into().unwrap()) {
542542
if declarator.kind() == "variable_declarator" {
543543
for k in 0..declarator.child_count() {
544-
if let Some(name_node) = declarator.child(k) {
544+
if let Some(name_node) =
545+
declarator.child(k.try_into().unwrap())
546+
{
545547
if name_node.kind() == "identifier" {
546548
#[cfg(debug_assertions)]
547549
{

0 commit comments

Comments
 (0)