Skip to content

Commit 5023886

Browse files
committed
[function-grep] made some more filters work, added source code input to filter function to work with tree sitter querry
1 parent 78479b3 commit 5023886

File tree

4 files changed

+74
-11
lines changed

4 files changed

+74
-11
lines changed

function-grep/src/filter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub trait HasFilterInformation {
127127
}
128128
}
129129
}
130-
type FilterFunction = Box<dyn Fn(&Node<'_>) -> bool + Send + Sync>;
130+
type FilterFunction = Box<dyn Fn(&Node<'_>, &str) -> bool + Send + Sync>;
131131

132132
// TODO: make our own FromStr that also requires the proggramer to sepcify that attributes each
133133
// filter has and their type so that we can make macro that creates parser, and also so that we can
@@ -164,8 +164,8 @@ impl<Supports: std::fmt::Debug> std::fmt::Debug for InstantiatedFilter<Supports>
164164

165165
impl<Supports> InstantiatedFilter<Supports> {
166166
#[must_use]
167-
pub fn filter(&self, node: &Node<'_>) -> bool {
168-
(self.filter_function)(node)
167+
pub fn filter(&self, node: &Node<'_>, code: &str) -> bool {
168+
(self.filter_function)(node, code)
169169
}
170170

171171
#[must_use]

function-grep/src/filter/filter_parsers.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ pub fn label<'a>(
2727
}
2828
)
2929
}
30+
31+
pub fn string<'a>(
32+
substring: &mut impl Iterator<Item = &'a str>,
33+
format: &str,
34+
position: &str,
35+
) -> Result<String, String> {
36+
substring.next().map(ToOwned::to_owned).ok_or_else(||format! ("invalid options for function_in_lines filter\nexpected {format}\n missing {position} [number]"))
37+
}

function-grep/src/filter/general_filters.rs

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::collections::HashMap;
22

3-
use tree_sitter::Node;
3+
use tree_sitter::{Node, Query, QueryCursor};
44

55
use super::{
6-
filter_parsers::{extra, label, number},
6+
filter_parsers::{extra, label, number, string},
77
All, Attribute, AttributeType, Attributes, Filter, FilterFunction, HasFilterInformation,
88
Language,
99
};
@@ -45,7 +45,7 @@ impl FunctionInLines {
4545
impl Filter for FunctionInLines {
4646
fn parse_filter(&self, s: &str) -> Result<FilterFunction, String> {
4747
let (start, end) = Self::from_str(s)?;
48-
Ok(Box::new(move |node: &Node<'_>| {
48+
Ok(Box::new(move |node: &Node<'_>, _| {
4949
node.range().start_point.row >= start && node.range().end_point.row <= end
5050
}))
5151
}
@@ -83,7 +83,7 @@ impl Filter for FunctionInImpl {
8383
return Err(format!("invalid options for function_in_impl, this filter accepts not options, but got {s}"));
8484
}
8585

86-
Ok(Box::new(move |node: &Node<'_>| {
86+
Ok(Box::new(move |node: &Node<'_>, _| {
8787
node.parent().is_some_and(|parent| {
8888
parent
8989
.parent()
@@ -129,7 +129,7 @@ impl HasFilterInformation for FunctionWithParameterRust {
129129
}
130130

131131
fn attributes(&self) -> Attributes {
132-
HashMap::from([(Attribute("Name".to_string()), AttributeType::String)])
132+
HashMap::from([(Attribute("name".to_string()), AttributeType::String)])
133133
}
134134

135135
type Supports = Language;
@@ -155,14 +155,69 @@ impl HasFilterInformation for FunctionWithParameterPython {
155155
}
156156

157157
fn attributes(&self) -> Attributes {
158-
HashMap::from([(Attribute("Name".to_string()), AttributeType::String)])
158+
HashMap::from([(Attribute("name".to_string()), AttributeType::String)])
159159
}
160160

161161
type Supports = Language;
162162
}
163163

164164
impl Filter for FunctionWithParameterPython {
165165
fn parse_filter(&self, s: &str) -> Result<FilterFunction, String> {
166-
todo!()
166+
let query = Query::new(
167+
&tree_sitter_rust::LANGUAGE.into(),
168+
"((function_item
169+
parameters: (parameters (parameter pattern: (identifier) @param)))
170+
)
171+
((let_declaration
172+
value: (closure_expression
173+
parameters: (closure_parameters [((identifier) @param)
174+
(parameter pattern: (identifier) @param)])
175+
))
176+
)
177+
((const_item
178+
value: (closure_expression
179+
(closure_parameters [((identifier) @param)
180+
(parameter pattern: (identifier) @param)])
181+
))
182+
)
183+
((static_item
184+
value: (closure_expression
185+
(closure_parameters [((identifier) @param)
186+
(parameter pattern: (identifier) @param)])
187+
))
188+
)",
189+
)
190+
.map_err(|_| String::from("Could not create tree sitter filter"))?;
191+
let name = parse_with_param(s)?;
192+
Ok(Box::new(move |node: &Node<'_>, code| {
193+
let mut cursor = QueryCursor::new();
194+
cursor.set_max_start_depth(Some(0));
195+
let text_provider = code.as_bytes();
196+
cursor.matches(&query, *node, text_provider).any(|c| {
197+
c.captures
198+
.iter()
199+
.any(|c| c.node.utf8_text(text_provider).unwrap() == name)
200+
})
201+
}))
202+
}
203+
}
204+
205+
fn parse_with_param(s: &str) -> Result<String, String> {
206+
let mut substring = s.split(' ').filter(|s| *s != " ");
207+
let fst = substring.next().ok_or(
208+
"invalid options for function_in_lines filter\nexpected [string] or name: [string]",
209+
)?;
210+
match fst {
211+
"start:" => {
212+
let format = "name: [string]";
213+
let name = string(&mut substring, format, "name:")?;
214+
extra(&mut substring, format)?;
215+
Ok(name)
216+
}
217+
218+
name => {
219+
extra(&mut substring, "[string]")?;
220+
Ok(name.to_string())
221+
}
167222
}
168223
}

function-grep/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl ParsedFile {
158158
let ranges: Box<[Range]> = self
159159
.ranges()
160160
.filter_map(|range| root.descendant_for_point_range(range.start_point, range.end_point))
161-
.filter(|n| f.filter(n))
161+
.filter(|n| f.filter(n, &self.file))
162162
.map(|n| n.range())
163163
.collect();
164164
if ranges.is_empty() {

0 commit comments

Comments
 (0)