Skip to content

Commit 249bc5c

Browse files
committed
Take references in from_query() and supply static queries
1 parent e3c5529 commit 249bc5c

File tree

3 files changed

+72
-43
lines changed

3 files changed

+72
-43
lines changed

crates/ark/src/lsp/indexer.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use stdext::unwrap;
1919
use stdext::unwrap::IntoResult;
2020
use tower_lsp::lsp_types::Range;
2121
use tree_sitter::Node;
22+
use tree_sitter::Query;
2223
use walkdir::DirEntry;
2324
use walkdir::WalkDir;
2425

@@ -347,23 +348,27 @@ fn index_r6_class_methods(
347348
entries: &mut Vec<IndexEntry>,
348349
) -> anyhow::Result<()> {
349350
// Tree-sitter query to match individual methods in R6Class public/private lists
350-
let query_str = r#"
351-
(argument
352-
name: (identifier) @access
353-
value: (call
354-
function: (identifier) @_list_fn
355-
arguments: (arguments
356-
(argument
357-
name: (identifier) @method_name
358-
value: (function_definition) @method_fn
359-
)
360-
)
361-
)
362-
(#match? @access "public|private")
363-
(#eq? @_list_fn "list")
364-
)
365-
"#;
366-
let mut ts_query = TsQuery::new(query_str)?;
351+
static R6_METHODS_QUERY: LazyLock<Query> = LazyLock::new(|| {
352+
let query_str = r#"
353+
(argument
354+
name: (identifier) @access
355+
value: (call
356+
function: (identifier) @_list_fn
357+
arguments: (arguments
358+
(argument
359+
name: (identifier) @method_name
360+
value: (function_definition) @method_fn
361+
)
362+
)
363+
)
364+
(#match? @access "public|private")
365+
(#eq? @_list_fn "list")
366+
)
367+
"#;
368+
let language = &tree_sitter_r::LANGUAGE.into();
369+
Query::new(language, query_str).expect("Failed to compile R6 methods query")
370+
});
371+
let mut ts_query = TsQuery::from_query(&*R6_METHODS_QUERY);
367372

368373
// We'll switch from Rope to String in the near future so let's not
369374
// worry about this conversion now

crates/ark/src/lsp/inputs/package_namespace.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
// Copyright (C) 2025 by Posit Software, PBC
55
//
66

7+
use std::sync::LazyLock;
8+
79
use tree_sitter::Parser;
10+
use tree_sitter::Query;
811

912
use crate::treesitter::TsQuery;
1013

@@ -32,24 +35,29 @@ impl Namespace {
3235
.ok_or_else(|| anyhow::anyhow!("Failed to parse NAMESPACE file"))?;
3336
let root_node = tree.root_node();
3437

35-
let query_str = r#"
36-
(call
37-
function: (identifier) @fn_name
38-
arguments: (arguments (argument value: (identifier) @exported))
39-
(#eq? @fn_name "export")
40-
)
41-
(call
42-
function: (identifier) @fn_name
43-
arguments: (arguments (argument value: (identifier) @pkg) (argument value: (identifier) @imported))
44-
(#eq? @fn_name "importFrom")
45-
)
46-
(call
47-
function: (identifier) @fn_name
48-
arguments: (arguments (argument value: (identifier) @imported_pkgs))
49-
(#eq? @fn_name "import")
50-
)
51-
"#;
52-
let mut ts_query = TsQuery::new(query_str)?;
38+
static NAMESPACE_QUERY: LazyLock<Query> = LazyLock::new(|| {
39+
let query_str = r#"
40+
(call
41+
function: (identifier) @fn_name
42+
arguments: (arguments (argument value: (identifier) @exported))
43+
(#eq? @fn_name "export")
44+
)
45+
(call
46+
function: (identifier) @fn_name
47+
arguments: (arguments (argument value: (identifier) @pkg) (argument value: (identifier) @imported))
48+
(#eq? @fn_name "importFrom")
49+
)
50+
(call
51+
function: (identifier) @fn_name
52+
arguments: (arguments (argument value: (identifier) @imported_pkgs))
53+
(#eq? @fn_name "import")
54+
)
55+
"#;
56+
let language = &tree_sitter_r::LANGUAGE.into();
57+
tree_sitter::Query::new(language, query_str).expect("Failed to compile NAMESPACE query")
58+
});
59+
60+
let mut ts_query = TsQuery::from_query(&*NAMESPACE_QUERY);
5361

5462
let captures = ts_query.captures_by(
5563
root_node,

crates/ark/src/treesitter.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -642,23 +642,35 @@ pub(crate) fn point_end_of_previous_row(
642642
}
643643
}
644644

645-
pub(crate) struct TsQuery {
646-
query: tree_sitter::Query,
645+
pub(crate) struct TsQuery<'ts_query> {
646+
query: QueryStorage<'ts_query>,
647647
cursor: tree_sitter::QueryCursor,
648648
}
649649

650-
impl TsQuery {
650+
pub(crate) enum QueryStorage<'ts_query> {
651+
Owned(tree_sitter::Query),
652+
Borrowed(&'ts_query tree_sitter::Query),
653+
}
654+
655+
impl<'ts_query> TsQuery<'ts_query> {
656+
#[allow(unused)]
651657
pub(crate) fn new(query_str: &str) -> anyhow::Result<Self> {
652658
let language = &tree_sitter_r::LANGUAGE.into();
653659
let query = tree_sitter::Query::new(language, query_str)
654660
.map_err(|err| anyhow!("Failed to compile query: {err}"))?;
655661

656-
Ok(Self::from_query(query))
662+
Ok(Self {
663+
query: QueryStorage::Owned(query),
664+
cursor: tree_sitter::QueryCursor::new(),
665+
})
657666
}
658667

659-
pub(crate) fn from_query(query: tree_sitter::Query) -> Self {
668+
pub(crate) fn from_query(query: &'ts_query tree_sitter::Query) -> Self {
660669
let cursor = tree_sitter::QueryCursor::new();
661-
Self { query, cursor }
670+
Self {
671+
query: QueryStorage::Borrowed(query),
672+
cursor,
673+
}
662674
}
663675

664676
/// Run the query on `contents` and collect all captures as (capture_name, node) pairs
@@ -670,8 +682,12 @@ impl TsQuery {
670682
where
671683
'tree: 'query,
672684
{
673-
let matches_iter = self.cursor.matches(&self.query, node, contents);
674-
AllCaptures::new(&self.query, matches_iter)
685+
let query = match self.query {
686+
QueryStorage::Owned(ref q) => q,
687+
QueryStorage::Borrowed(q) => q,
688+
};
689+
let matches_iter = self.cursor.matches(query, node, contents);
690+
AllCaptures::new(query, matches_iter)
675691
}
676692

677693
/// Run the query on `contents` and filter captures that match `capture_name`

0 commit comments

Comments
 (0)