Add containing range APIs to query cursor
Co-authored-by: Kirill Bulatov <mail4score@gmail.com> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com> Co-authored-by: dino <dinojoaocosta@gmail.com> Co-authored-by: John Tur <john-tur@outlook.com> Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Co-authored-by: dino <dinojoaocosta@gmail.com> Co-authored-by: Will Lillis <will.lillis24@gmail.com>
This commit is contained in:
parent
7d3feeae9a
commit
c0b1710f8a
13 changed files with 420 additions and 34 deletions
110
lib/src/query.c
110
lib/src/query.c
|
|
@ -318,10 +318,8 @@ struct TSQueryCursor {
|
|||
CaptureListPool capture_list_pool;
|
||||
uint32_t depth;
|
||||
uint32_t max_start_depth;
|
||||
uint32_t start_byte;
|
||||
uint32_t end_byte;
|
||||
TSPoint start_point;
|
||||
TSPoint end_point;
|
||||
TSRange included_range;
|
||||
TSRange containing_range;
|
||||
uint32_t next_state_id;
|
||||
const TSQueryCursorOptions *query_options;
|
||||
TSQueryCursorState query_state;
|
||||
|
|
@ -1336,7 +1334,7 @@ static void ts_query__perform_analysis(
|
|||
// of the query pattern.
|
||||
bool does_match = false;
|
||||
|
||||
// ERROR nodes can appear anywhere, so if the step is
|
||||
// ERROR nodes can appear anywhere, so if the step is
|
||||
// looking for an ERROR node, consider it potentially matchable.
|
||||
if (step->symbol == ts_builtin_sym_error) {
|
||||
does_match = true;
|
||||
|
|
@ -3155,10 +3153,18 @@ TSQueryCursor *ts_query_cursor_new(void) {
|
|||
.states = array_new(),
|
||||
.finished_states = array_new(),
|
||||
.capture_list_pool = capture_list_pool_new(),
|
||||
.start_byte = 0,
|
||||
.end_byte = UINT32_MAX,
|
||||
.start_point = {0, 0},
|
||||
.end_point = POINT_MAX,
|
||||
.included_range = {
|
||||
.start_point = {0, 0},
|
||||
.end_point = POINT_MAX,
|
||||
.start_byte = 0,
|
||||
.end_byte = UINT32_MAX,
|
||||
},
|
||||
.containing_range = {
|
||||
.start_point = {0, 0},
|
||||
.end_point = POINT_MAX,
|
||||
.start_byte = 0,
|
||||
.end_byte = UINT32_MAX,
|
||||
},
|
||||
.max_start_depth = UINT32_MAX,
|
||||
.operation_count = 0,
|
||||
};
|
||||
|
|
@ -3266,8 +3272,8 @@ bool ts_query_cursor_set_byte_range(
|
|||
if (start_byte > end_byte) {
|
||||
return false;
|
||||
}
|
||||
self->start_byte = start_byte;
|
||||
self->end_byte = end_byte;
|
||||
self->included_range.start_byte = start_byte;
|
||||
self->included_range.end_byte = end_byte;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3282,8 +3288,40 @@ bool ts_query_cursor_set_point_range(
|
|||
if (point_gt(start_point, end_point)) {
|
||||
return false;
|
||||
}
|
||||
self->start_point = start_point;
|
||||
self->end_point = end_point;
|
||||
self->included_range.start_point = start_point;
|
||||
self->included_range.end_point = end_point;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ts_query_cursor_set_containing_byte_range(
|
||||
TSQueryCursor *self,
|
||||
uint32_t start_byte,
|
||||
uint32_t end_byte
|
||||
) {
|
||||
if (end_byte == 0) {
|
||||
end_byte = UINT32_MAX;
|
||||
}
|
||||
if (start_byte > end_byte) {
|
||||
return false;
|
||||
}
|
||||
self->containing_range.start_byte = start_byte;
|
||||
self->containing_range.end_byte = end_byte;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ts_query_cursor_set_containing_point_range(
|
||||
TSQueryCursor *self,
|
||||
TSPoint start_point,
|
||||
TSPoint end_point
|
||||
) {
|
||||
if (end_point.row == 0 && end_point.column == 0) {
|
||||
end_point = POINT_MAX;
|
||||
}
|
||||
if (point_gt(start_point, end_point)) {
|
||||
return false;
|
||||
}
|
||||
self->containing_range.start_point = start_point;
|
||||
self->containing_range.end_point = end_point;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3314,8 +3352,8 @@ static bool ts_query_cursor__first_in_progress_capture(
|
|||
|
||||
TSNode node = array_get(captures, state->consumed_capture_count)->node;
|
||||
if (
|
||||
ts_node_end_byte(node) <= self->start_byte ||
|
||||
point_lte(ts_node_end_point(node), self->start_point)
|
||||
ts_node_end_byte(node) <= self->included_range.start_byte ||
|
||||
point_lte(ts_node_end_point(node), self->included_range.start_point)
|
||||
) {
|
||||
state->consumed_capture_count++;
|
||||
i--;
|
||||
|
|
@ -3771,28 +3809,38 @@ static inline bool ts_query_cursor__advance(
|
|||
bool is_empty = start_byte == end_byte;
|
||||
|
||||
bool parent_precedes_range = !ts_node_is_null(parent_node) && (
|
||||
ts_node_end_byte(parent_node) <= self->start_byte ||
|
||||
point_lte(ts_node_end_point(parent_node), self->start_point)
|
||||
ts_node_end_byte(parent_node) <= self->included_range.start_byte ||
|
||||
point_lte(ts_node_end_point(parent_node), self->included_range.start_point)
|
||||
);
|
||||
bool parent_follows_range = !ts_node_is_null(parent_node) && (
|
||||
ts_node_start_byte(parent_node) >= self->end_byte ||
|
||||
point_gte(ts_node_start_point(parent_node), self->end_point)
|
||||
ts_node_start_byte(parent_node) >= self->included_range.end_byte ||
|
||||
point_gte(ts_node_start_point(parent_node), self->included_range.end_point)
|
||||
);
|
||||
bool node_precedes_range =
|
||||
parent_precedes_range ||
|
||||
end_byte < self->start_byte ||
|
||||
point_lt(end_point, self->start_point) ||
|
||||
(!is_empty && end_byte == self->start_byte) ||
|
||||
(!is_empty && point_eq(end_point, self->start_point));
|
||||
end_byte < self->included_range.start_byte ||
|
||||
point_lt(end_point, self->included_range.start_point) ||
|
||||
(!is_empty && end_byte == self->included_range.start_byte) ||
|
||||
(!is_empty && point_eq(end_point, self->included_range.start_point));
|
||||
|
||||
bool node_follows_range = parent_follows_range || (
|
||||
start_byte >= self->end_byte ||
|
||||
point_gte(start_point, self->end_point)
|
||||
start_byte >= self->included_range.end_byte ||
|
||||
point_gte(start_point, self->included_range.end_point)
|
||||
);
|
||||
bool parent_intersects_range = !parent_precedes_range && !parent_follows_range;
|
||||
bool node_intersects_range = !node_precedes_range && !node_follows_range;
|
||||
bool node_within_containing_range =
|
||||
start_byte >= self->containing_range.start_byte &&
|
||||
point_gte(start_point, self->containing_range.start_point) &&
|
||||
end_byte <= self->containing_range.end_byte &&
|
||||
point_lte(end_point, self->containing_range.end_point);
|
||||
bool node_intersects_containing_range =
|
||||
end_byte > self->containing_range.start_byte &&
|
||||
point_gt(end_point, self->containing_range.start_point) &&
|
||||
start_byte < self->containing_range.end_byte &&
|
||||
point_lt(start_point, self->containing_range.end_point);
|
||||
|
||||
if (self->on_visible_node) {
|
||||
if (node_within_containing_range && self->on_visible_node) {
|
||||
TSSymbol symbol = ts_node_symbol(node);
|
||||
bool is_named = ts_node_is_named(node);
|
||||
bool is_missing = ts_node_is_missing(node);
|
||||
|
|
@ -4182,7 +4230,7 @@ static inline bool ts_query_cursor__advance(
|
|||
}
|
||||
}
|
||||
|
||||
if (ts_query_cursor__should_descend(self, node_intersects_range)) {
|
||||
if (node_intersects_containing_range && ts_query_cursor__should_descend(self, node_intersects_range)) {
|
||||
switch (ts_tree_cursor_goto_first_child_internal(&self->cursor)) {
|
||||
case TreeCursorStepVisible:
|
||||
self->depth++;
|
||||
|
|
@ -4304,12 +4352,12 @@ bool ts_query_cursor_next_capture(
|
|||
TSNode node = array_get(captures, state->consumed_capture_count)->node;
|
||||
|
||||
bool node_precedes_range = (
|
||||
ts_node_end_byte(node) <= self->start_byte ||
|
||||
point_lte(ts_node_end_point(node), self->start_point)
|
||||
ts_node_end_byte(node) <= self->included_range.start_byte ||
|
||||
point_lte(ts_node_end_point(node), self->included_range.start_point)
|
||||
);
|
||||
bool node_follows_range = (
|
||||
ts_node_start_byte(node) >= self->end_byte ||
|
||||
point_gte(ts_node_start_point(node), self->end_point)
|
||||
ts_node_start_byte(node) >= self->included_range.end_byte ||
|
||||
point_gte(ts_node_start_point(node), self->included_range.end_point)
|
||||
);
|
||||
bool node_outside_of_range = node_precedes_range || node_follows_range;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue