fix(lib): replace raw array accesses with array_get
(cherry picked from commit 8bd923ab9e)
This commit is contained in:
parent
bf655c0bea
commit
b890e8bea0
7 changed files with 229 additions and 227 deletions
283
lib/src/query.c
283
lib/src/query.c
|
|
@ -437,26 +437,26 @@ static CaptureListPool capture_list_pool_new(void) {
|
|||
static void capture_list_pool_reset(CaptureListPool *self) {
|
||||
for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {
|
||||
// This invalid size means that the list is not in use.
|
||||
self->list.contents[i].size = UINT32_MAX;
|
||||
array_get(&self->list, i)->size = UINT32_MAX;
|
||||
}
|
||||
self->free_capture_list_count = self->list.size;
|
||||
}
|
||||
|
||||
static void capture_list_pool_delete(CaptureListPool *self) {
|
||||
for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {
|
||||
array_delete(&self->list.contents[i]);
|
||||
array_delete(array_get(&self->list, i));
|
||||
}
|
||||
array_delete(&self->list);
|
||||
}
|
||||
|
||||
static const CaptureList *capture_list_pool_get(const CaptureListPool *self, uint16_t id) {
|
||||
if (id >= self->list.size) return &self->empty_list;
|
||||
return &self->list.contents[id];
|
||||
return array_get(&self->list, id);
|
||||
}
|
||||
|
||||
static CaptureList *capture_list_pool_get_mut(CaptureListPool *self, uint16_t id) {
|
||||
ts_assert(id < self->list.size);
|
||||
return &self->list.contents[id];
|
||||
return array_get(&self->list, id);
|
||||
}
|
||||
|
||||
static bool capture_list_pool_is_empty(const CaptureListPool *self) {
|
||||
|
|
@ -469,8 +469,8 @@ static uint16_t capture_list_pool_acquire(CaptureListPool *self) {
|
|||
// First see if any already allocated capture list is currently unused.
|
||||
if (self->free_capture_list_count > 0) {
|
||||
for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {
|
||||
if (self->list.contents[i].size == UINT32_MAX) {
|
||||
array_clear(&self->list.contents[i]);
|
||||
if (array_get(&self->list, i)->size == UINT32_MAX) {
|
||||
array_clear(array_get(&self->list, i));
|
||||
self->free_capture_list_count--;
|
||||
return i;
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ static uint16_t capture_list_pool_acquire(CaptureListPool *self) {
|
|||
|
||||
static void capture_list_pool_release(CaptureListPool *self, uint16_t id) {
|
||||
if (id >= self->list.size) return;
|
||||
self->list.contents[id].size = UINT32_MAX;
|
||||
array_get(&self->list, id)->size = UINT32_MAX;
|
||||
self->free_capture_list_count++;
|
||||
}
|
||||
|
||||
|
|
@ -774,10 +774,10 @@ static int symbol_table_id_for_name(
|
|||
uint32_t length
|
||||
) {
|
||||
for (unsigned i = 0; i < self->slices.size; i++) {
|
||||
Slice slice = self->slices.contents[i];
|
||||
Slice slice = *array_get(&self->slices, i);
|
||||
if (
|
||||
slice.length == length &&
|
||||
!strncmp(&self->characters.contents[slice.offset], name, length)
|
||||
!strncmp(array_get(&self->characters, slice.offset), name, length)
|
||||
) return i;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -788,9 +788,9 @@ static const char *symbol_table_name_for_id(
|
|||
uint16_t id,
|
||||
uint32_t *length
|
||||
) {
|
||||
Slice slice = self->slices.contents[id];
|
||||
Slice slice = *(array_get(&self->slices,id));
|
||||
*length = slice.length;
|
||||
return &self->characters.contents[slice.offset];
|
||||
return array_get(&self->characters, slice.offset);
|
||||
}
|
||||
|
||||
static uint16_t symbol_table_insert_name(
|
||||
|
|
@ -805,8 +805,8 @@ static uint16_t symbol_table_insert_name(
|
|||
.length = length,
|
||||
};
|
||||
array_grow_by(&self->characters, length + 1);
|
||||
memcpy(&self->characters.contents[slice.offset], name, length);
|
||||
self->characters.contents[self->characters.size - 1] = 0;
|
||||
memcpy(array_get(&self->characters, slice.offset), name, length);
|
||||
*array_get(&self->characters, self->characters.size - 1) = 0;
|
||||
array_push(&self->slices, slice);
|
||||
return self->slices.size - 1;
|
||||
}
|
||||
|
|
@ -1118,23 +1118,23 @@ static inline bool ts_query__pattern_map_search(
|
|||
while (size > 1) {
|
||||
uint32_t half_size = size / 2;
|
||||
uint32_t mid_index = base_index + half_size;
|
||||
TSSymbol mid_symbol = self->steps.contents[
|
||||
self->pattern_map.contents[mid_index].step_index
|
||||
].symbol;
|
||||
TSSymbol mid_symbol = array_get(&self->steps,
|
||||
array_get(&self->pattern_map, mid_index)->step_index
|
||||
)->symbol;
|
||||
if (needle > mid_symbol) base_index = mid_index;
|
||||
size -= half_size;
|
||||
}
|
||||
|
||||
TSSymbol symbol = self->steps.contents[
|
||||
self->pattern_map.contents[base_index].step_index
|
||||
].symbol;
|
||||
TSSymbol symbol = array_get(&self->steps,
|
||||
array_get(&self->pattern_map, base_index)->step_index
|
||||
)->symbol;
|
||||
|
||||
if (needle > symbol) {
|
||||
base_index++;
|
||||
if (base_index < self->pattern_map.size) {
|
||||
symbol = self->steps.contents[
|
||||
self->pattern_map.contents[base_index].step_index
|
||||
].symbol;
|
||||
symbol = array_get(&self->steps,
|
||||
array_get(&self->pattern_map, base_index)->step_index
|
||||
)->symbol;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1157,9 +1157,9 @@ static inline void ts_query__pattern_map_insert(
|
|||
// initiated first, which allows the ordering of the states array
|
||||
// to be maintained more efficiently.
|
||||
while (index < self->pattern_map.size) {
|
||||
PatternEntry *entry = &self->pattern_map.contents[index];
|
||||
PatternEntry *entry = array_get(&self->pattern_map, index);
|
||||
if (
|
||||
self->steps.contents[entry->step_index].symbol == symbol &&
|
||||
array_get(&self->steps, entry->step_index)->symbol == symbol &&
|
||||
entry->pattern_index < new_entry.pattern_index
|
||||
) {
|
||||
index++;
|
||||
|
|
@ -1192,11 +1192,11 @@ static void ts_query__perform_analysis(
|
|||
#ifdef DEBUG_ANALYZE_QUERY
|
||||
printf("Iteration: %u. Final step indices:", iteration);
|
||||
for (unsigned j = 0; j < analysis->final_step_indices.size; j++) {
|
||||
printf(" %4u", analysis->final_step_indices.contents[j]);
|
||||
printf(" %4u", *array_get(&analysis->final_step_indices, j));
|
||||
}
|
||||
printf("\n");
|
||||
for (unsigned j = 0; j < analysis->states.size; j++) {
|
||||
AnalysisState *state = analysis->states.contents[j];
|
||||
AnalysisState *state = *array_get(&analysis->states, j);
|
||||
printf(" %3u: step: %u, stack: [", j, state->step_index);
|
||||
for (unsigned k = 0; k < state->depth; k++) {
|
||||
printf(
|
||||
|
|
@ -1239,7 +1239,7 @@ static void ts_query__perform_analysis(
|
|||
|
||||
analysis_state_set__clear(&analysis->next_states, &analysis->state_pool);
|
||||
for (unsigned j = 0; j < analysis->states.size; j++) {
|
||||
AnalysisState * const state = analysis->states.contents[j];
|
||||
AnalysisState * const state = *array_get(&analysis->states, j);
|
||||
|
||||
// For efficiency, it's important to avoid processing the same analysis state more
|
||||
// than once. To achieve this, keep the states in order of ascending position within
|
||||
|
|
@ -1262,7 +1262,7 @@ static void ts_query__perform_analysis(
|
|||
analysis_state_set__push(
|
||||
&analysis->next_states,
|
||||
&analysis->state_pool,
|
||||
analysis->states.contents[j]
|
||||
*array_get(&analysis->states, j)
|
||||
);
|
||||
j++;
|
||||
}
|
||||
|
|
@ -1274,12 +1274,12 @@ static void ts_query__perform_analysis(
|
|||
const TSSymbol parent_symbol = analysis_state__top(state)->parent_symbol;
|
||||
const TSFieldId parent_field_id = analysis_state__top(state)->field_id;
|
||||
const unsigned child_index = analysis_state__top(state)->child_index;
|
||||
const QueryStep * const step = &self->steps.contents[state->step_index];
|
||||
const QueryStep * const step = array_get(&self->steps, state->step_index);
|
||||
|
||||
unsigned subgraph_index, exists;
|
||||
array_search_sorted_by(subgraphs, .symbol, parent_symbol, &subgraph_index, &exists);
|
||||
if (!exists) continue;
|
||||
const AnalysisSubgraph *subgraph = &subgraphs->contents[subgraph_index];
|
||||
const AnalysisSubgraph *subgraph = array_get(subgraphs, subgraph_index);
|
||||
|
||||
// Follow every possible path in the parse table, but only visit states that
|
||||
// are part of the subgraph for the current symbol.
|
||||
|
|
@ -1315,7 +1315,8 @@ static void ts_query__perform_analysis(
|
|||
&node_index, &exists
|
||||
);
|
||||
while (node_index < subgraph->nodes.size) {
|
||||
AnalysisSubgraphNode *node = &subgraph->nodes.contents[node_index++];
|
||||
AnalysisSubgraphNode *node = array_get(&subgraph->nodes, node_index);
|
||||
node_index++;
|
||||
if (node->state != successor.state || node->child_index != successor.child_index) break;
|
||||
|
||||
// Use the subgraph to determine what alias and field will eventually be applied
|
||||
|
|
@ -1416,7 +1417,7 @@ static void ts_query__perform_analysis(
|
|||
if (does_match) {
|
||||
for (;;) {
|
||||
next_state.step_index++;
|
||||
next_step = &self->steps.contents[next_state.step_index];
|
||||
next_step = array_get(&self->steps, next_state.step_index);
|
||||
if (
|
||||
next_step->depth == PATTERN_DONE_MARKER ||
|
||||
next_step->depth <= step->depth
|
||||
|
|
@ -1440,7 +1441,7 @@ static void ts_query__perform_analysis(
|
|||
// record that matching can terminate at this step of the pattern. Otherwise,
|
||||
// add this state to the list of states to process on the next iteration.
|
||||
if (!next_step->is_dead_end) {
|
||||
bool did_finish_pattern = self->steps.contents[next_state.step_index].depth != step->depth;
|
||||
bool did_finish_pattern = array_get(&self->steps, next_state.step_index)->depth != step->depth;
|
||||
if (did_finish_pattern) {
|
||||
array_insert_sorted_by(&analysis->finished_parent_symbols, , state->root_symbol);
|
||||
} else if (next_state.depth == 0) {
|
||||
|
|
@ -1460,7 +1461,7 @@ static void ts_query__perform_analysis(
|
|||
next_step->alternative_index > next_state.step_index
|
||||
) {
|
||||
next_state.step_index = next_step->alternative_index;
|
||||
next_step = &self->steps.contents[next_state.step_index];
|
||||
next_step = array_get(&self->steps, next_state.step_index);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
@ -1478,9 +1479,9 @@ static void ts_query__perform_analysis(
|
|||
static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
||||
Array(uint16_t) non_rooted_pattern_start_steps = array_new();
|
||||
for (unsigned i = 0; i < self->pattern_map.size; i++) {
|
||||
PatternEntry *pattern = &self->pattern_map.contents[i];
|
||||
PatternEntry *pattern = array_get(&self->pattern_map, i);
|
||||
if (!pattern->is_rooted) {
|
||||
QueryStep *step = &self->steps.contents[pattern->step_index];
|
||||
QueryStep *step = array_get(&self->steps, pattern->step_index);
|
||||
if (step->symbol != WILDCARD_SYMBOL) {
|
||||
array_push(&non_rooted_pattern_start_steps, i);
|
||||
}
|
||||
|
|
@ -1492,7 +1493,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// captures, and record the indices of all of the steps that have child steps.
|
||||
Array(uint32_t) parent_step_indices = array_new();
|
||||
for (unsigned i = 0; i < self->steps.size; i++) {
|
||||
QueryStep *step = &self->steps.contents[i];
|
||||
QueryStep *step = array_get(&self->steps, i);
|
||||
if (step->depth == PATTERN_DONE_MARKER) {
|
||||
step->parent_pattern_guaranteed = true;
|
||||
step->root_pattern_guaranteed = true;
|
||||
|
|
@ -1503,7 +1504,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
bool is_wildcard = step->symbol == WILDCARD_SYMBOL;
|
||||
step->contains_captures = step->capture_ids[0] != NONE;
|
||||
for (unsigned j = i + 1; j < self->steps.size; j++) {
|
||||
QueryStep *next_step = &self->steps.contents[j];
|
||||
QueryStep *next_step = array_get(&self->steps, j);
|
||||
if (
|
||||
next_step->depth == PATTERN_DONE_MARKER ||
|
||||
next_step->depth <= step->depth
|
||||
|
|
@ -1533,8 +1534,8 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// parent.
|
||||
AnalysisSubgraphArray subgraphs = array_new();
|
||||
for (unsigned i = 0; i < parent_step_indices.size; i++) {
|
||||
uint32_t parent_step_index = parent_step_indices.contents[i];
|
||||
TSSymbol parent_symbol = self->steps.contents[parent_step_index].symbol;
|
||||
uint32_t parent_step_index = *array_get(&parent_step_indices, i);
|
||||
TSSymbol parent_symbol = array_get(&self->steps, parent_step_index)->symbol;
|
||||
AnalysisSubgraph subgraph = { .symbol = parent_symbol };
|
||||
array_insert_sorted_by(&subgraphs, .symbol, subgraph);
|
||||
}
|
||||
|
|
@ -1576,7 +1577,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
&exists
|
||||
);
|
||||
if (exists) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
AnalysisSubgraph *subgraph = array_get(&subgraphs, subgraph_index);
|
||||
if (subgraph->nodes.size == 0 || array_back(&subgraph->nodes)->state != state) {
|
||||
array_push(&subgraph->nodes, ((AnalysisSubgraphNode) {
|
||||
.state = state,
|
||||
|
|
@ -1613,7 +1614,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
&exists
|
||||
);
|
||||
if (exists) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
AnalysisSubgraph *subgraph = array_get(&subgraphs, subgraph_index);
|
||||
if (
|
||||
subgraph->start_states.size == 0 ||
|
||||
*array_back(&subgraph->start_states) != state
|
||||
|
|
@ -1630,7 +1631,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// from the end states using the predecessor map.
|
||||
Array(AnalysisSubgraphNode) next_nodes = array_new();
|
||||
for (unsigned i = 0; i < subgraphs.size; i++) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[i];
|
||||
AnalysisSubgraph *subgraph = array_get(&subgraphs, i);
|
||||
if (subgraph->nodes.size == 0) {
|
||||
array_delete(&subgraph->start_states);
|
||||
array_erase(&subgraphs, i);
|
||||
|
|
@ -1671,16 +1672,16 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
#ifdef DEBUG_ANALYZE_QUERY
|
||||
printf("\nSubgraphs:\n");
|
||||
for (unsigned i = 0; i < subgraphs.size; i++) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[i];
|
||||
AnalysisSubgraph *subgraph = array_get(&subgraphs, i);
|
||||
printf(" %u, %s:\n", subgraph->symbol, ts_language_symbol_name(self->language, subgraph->symbol));
|
||||
for (unsigned j = 0; j < subgraph->start_states.size; j++) {
|
||||
printf(
|
||||
" {state: %u}\n",
|
||||
subgraph->start_states.contents[j]
|
||||
*array_get(&subgraph->start_states, j)
|
||||
);
|
||||
}
|
||||
for (unsigned j = 0; j < subgraph->nodes.size; j++) {
|
||||
AnalysisSubgraphNode *node = &subgraph->nodes.contents[j];
|
||||
AnalysisSubgraphNode *node = array_get(&subgraph->nodes, j);
|
||||
printf(
|
||||
" {state: %u, child_index: %u, production_id: %u, done: %d}\n",
|
||||
node->state, node->child_index, node->production_id, node->done
|
||||
|
|
@ -1695,9 +1696,9 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
bool all_patterns_are_valid = true;
|
||||
QueryAnalysis analysis = query_analysis__new();
|
||||
for (unsigned i = 0; i < parent_step_indices.size; i++) {
|
||||
uint16_t parent_step_index = parent_step_indices.contents[i];
|
||||
uint16_t parent_depth = self->steps.contents[parent_step_index].depth;
|
||||
TSSymbol parent_symbol = self->steps.contents[parent_step_index].symbol;
|
||||
uint16_t parent_step_index = *array_get(&parent_step_indices, i);
|
||||
uint16_t parent_depth = array_get(&self->steps, parent_step_index)->depth;
|
||||
TSSymbol parent_symbol = array_get(&self->steps, parent_step_index)->symbol;
|
||||
if (parent_symbol == ts_builtin_sym_error) continue;
|
||||
|
||||
// Find the subgraph that corresponds to this pattern's root symbol. If the pattern's
|
||||
|
|
@ -1709,18 +1710,18 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
uint32_t j, child_exists;
|
||||
array_search_sorted_by(&self->step_offsets, .step_index, first_child_step_index, &j, &child_exists);
|
||||
ts_assert(child_exists);
|
||||
*error_offset = self->step_offsets.contents[j].byte_offset;
|
||||
*error_offset = array_get(&self->step_offsets, j)->byte_offset;
|
||||
all_patterns_are_valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize an analysis state at every parse state in the table where
|
||||
// this parent symbol can occur.
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
AnalysisSubgraph *subgraph = array_get(&subgraphs, subgraph_index);
|
||||
analysis_state_set__clear(&analysis.states, &analysis.state_pool);
|
||||
analysis_state_set__clear(&analysis.deeper_states, &analysis.state_pool);
|
||||
for (unsigned j = 0; j < subgraph->start_states.size; j++) {
|
||||
TSStateId parse_state = subgraph->start_states.contents[j];
|
||||
TSStateId parse_state = *array_get(&subgraph->start_states, j);
|
||||
analysis_state_set__push(&analysis.states, &analysis.state_pool, &((AnalysisState) {
|
||||
.step_index = parent_step_index + 1,
|
||||
.stack = {
|
||||
|
|
@ -1740,7 +1741,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
#ifdef DEBUG_ANALYZE_QUERY
|
||||
printf(
|
||||
"\nWalk states for %s:\n",
|
||||
ts_language_symbol_name(self->language, analysis.states.contents[0]->stack[0].parent_symbol)
|
||||
ts_language_symbol_name(self->language, (*array_get(&analysis.states, 0))->stack[0].parent_symbol)
|
||||
);
|
||||
#endif
|
||||
|
||||
|
|
@ -1751,7 +1752,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// be considered fallible.
|
||||
if (analysis.did_abort) {
|
||||
for (unsigned j = parent_step_index + 1; j < self->steps.size; j++) {
|
||||
QueryStep *step = &self->steps.contents[j];
|
||||
QueryStep *step = array_get(&self->steps, j);
|
||||
if (
|
||||
step->depth <= parent_depth ||
|
||||
step->depth == PATTERN_DONE_MARKER
|
||||
|
|
@ -1772,7 +1773,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
uint32_t j, impossible_exists;
|
||||
array_search_sorted_by(&self->step_offsets, .step_index, impossible_step_index, &j, &impossible_exists);
|
||||
if (j >= self->step_offsets.size) j = self->step_offsets.size - 1;
|
||||
*error_offset = self->step_offsets.contents[j].byte_offset;
|
||||
*error_offset = array_get(&self->step_offsets, j)->byte_offset;
|
||||
all_patterns_are_valid = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1780,8 +1781,8 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// Mark as fallible any step where a match terminated.
|
||||
// Later, this property will be propagated to all of the step's predecessors.
|
||||
for (unsigned j = 0; j < analysis.final_step_indices.size; j++) {
|
||||
uint32_t final_step_index = analysis.final_step_indices.contents[j];
|
||||
QueryStep *step = &self->steps.contents[final_step_index];
|
||||
uint32_t final_step_index = *array_get(&analysis.final_step_indices, j);
|
||||
QueryStep *step = array_get(&self->steps, final_step_index);
|
||||
if (
|
||||
step->depth != PATTERN_DONE_MARKER &&
|
||||
step->depth > parent_depth &&
|
||||
|
|
@ -1796,7 +1797,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// Mark as indefinite any step with captures that are used in predicates.
|
||||
Array(uint16_t) predicate_capture_ids = array_new();
|
||||
for (unsigned i = 0; i < self->patterns.size; i++) {
|
||||
QueryPattern *pattern = &self->patterns.contents[i];
|
||||
QueryPattern *pattern = array_get(&self->patterns, i);
|
||||
|
||||
// Gather all of the captures that are used in predicates for this pattern.
|
||||
array_clear(&predicate_capture_ids);
|
||||
|
|
@ -1805,7 +1806,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
end = start + pattern->predicate_steps.length,
|
||||
j = start; j < end; j++
|
||||
) {
|
||||
TSQueryPredicateStep *step = &self->predicate_steps.contents[j];
|
||||
TSQueryPredicateStep *step = array_get(&self->predicate_steps, j);
|
||||
if (step->type == TSQueryPredicateStepTypeCapture) {
|
||||
uint16_t value_id = step->value_id;
|
||||
array_insert_sorted_by(&predicate_capture_ids, , value_id);
|
||||
|
|
@ -1818,7 +1819,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
end = start + pattern->steps.length,
|
||||
j = start; j < end; j++
|
||||
) {
|
||||
QueryStep *step = &self->steps.contents[j];
|
||||
QueryStep *step = array_get(&self->steps, j);
|
||||
for (unsigned k = 0; k < MAX_STEP_CAPTURE_COUNT; k++) {
|
||||
uint16_t capture_id = step->capture_ids[k];
|
||||
if (capture_id == NONE) break;
|
||||
|
|
@ -1838,7 +1839,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
while (!done) {
|
||||
done = true;
|
||||
for (unsigned i = self->steps.size - 1; i > 0; i--) {
|
||||
QueryStep *step = &self->steps.contents[i];
|
||||
QueryStep *step = array_get(&self->steps, i);
|
||||
if (step->depth == PATTERN_DONE_MARKER) continue;
|
||||
|
||||
// Determine if this step is definite or has definite alternatives.
|
||||
|
|
@ -1851,12 +1852,12 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
if (step->alternative_index == NONE || step->alternative_index < i) {
|
||||
break;
|
||||
}
|
||||
step = &self->steps.contents[step->alternative_index];
|
||||
step = array_get(&self->steps, step->alternative_index);
|
||||
}
|
||||
|
||||
// If not, mark its predecessor as indefinite.
|
||||
if (!parent_pattern_guaranteed) {
|
||||
QueryStep *prev_step = &self->steps.contents[i - 1];
|
||||
QueryStep *prev_step = array_get(&self->steps, i - 1);
|
||||
if (
|
||||
!prev_step->is_dead_end &&
|
||||
prev_step->depth != PATTERN_DONE_MARKER &&
|
||||
|
|
@ -1872,7 +1873,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
#ifdef DEBUG_ANALYZE_QUERY
|
||||
printf("Steps:\n");
|
||||
for (unsigned i = 0; i < self->steps.size; i++) {
|
||||
QueryStep *step = &self->steps.contents[i];
|
||||
QueryStep *step = array_get(&self->steps, i);
|
||||
if (step->depth == PATTERN_DONE_MARKER) {
|
||||
printf(" %u: DONE\n", i);
|
||||
} else {
|
||||
|
|
@ -1896,18 +1897,18 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
// prevent certain optimizations with range restrictions.
|
||||
analysis.did_abort = false;
|
||||
for (uint32_t i = 0; i < non_rooted_pattern_start_steps.size; i++) {
|
||||
uint16_t pattern_entry_index = non_rooted_pattern_start_steps.contents[i];
|
||||
PatternEntry *pattern_entry = &self->pattern_map.contents[pattern_entry_index];
|
||||
uint16_t pattern_entry_index = *array_get(&non_rooted_pattern_start_steps, i);
|
||||
PatternEntry *pattern_entry = array_get(&self->pattern_map, pattern_entry_index);
|
||||
|
||||
analysis_state_set__clear(&analysis.states, &analysis.state_pool);
|
||||
analysis_state_set__clear(&analysis.deeper_states, &analysis.state_pool);
|
||||
for (unsigned j = 0; j < subgraphs.size; j++) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[j];
|
||||
AnalysisSubgraph *subgraph = array_get(&subgraphs, j);
|
||||
TSSymbolMetadata metadata = ts_language_symbol_metadata(self->language, subgraph->symbol);
|
||||
if (metadata.visible || metadata.named) continue;
|
||||
|
||||
for (uint32_t k = 0; k < subgraph->start_states.size; k++) {
|
||||
TSStateId parse_state = subgraph->start_states.contents[k];
|
||||
TSStateId parse_state = *array_get(&subgraph->start_states, k);
|
||||
analysis_state_set__push(&analysis.states, &analysis.state_pool, &((AnalysisState) {
|
||||
.step_index = pattern_entry->step_index,
|
||||
.stack = {
|
||||
|
|
@ -1936,11 +1937,11 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
);
|
||||
|
||||
if (analysis.finished_parent_symbols.size > 0) {
|
||||
self->patterns.contents[pattern_entry->pattern_index].is_non_local = true;
|
||||
array_get(&self->patterns, pattern_entry->pattern_index)->is_non_local = true;
|
||||
}
|
||||
|
||||
for (unsigned k = 0; k < analysis.finished_parent_symbols.size; k++) {
|
||||
TSSymbol symbol = analysis.finished_parent_symbols.contents[k];
|
||||
TSSymbol symbol = *array_get(&analysis.finished_parent_symbols, k);
|
||||
array_insert_sorted_by(&self->repeat_symbols_with_rootless_patterns, , symbol);
|
||||
}
|
||||
}
|
||||
|
|
@ -1950,7 +1951,7 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
printf("\nRepetition symbols with rootless patterns:\n");
|
||||
printf("aborted analysis: %d\n", analysis.did_abort);
|
||||
for (unsigned i = 0; i < self->repeat_symbols_with_rootless_patterns.size; i++) {
|
||||
TSSymbol symbol = self->repeat_symbols_with_rootless_patterns.contents[i];
|
||||
TSSymbol symbol = *array_get(&self->repeat_symbols_with_rootless_patterns, i);
|
||||
printf(" %u, %s\n", symbol, ts_language_symbol_name(self->language, symbol));
|
||||
}
|
||||
printf("\n");
|
||||
|
|
@ -1959,8 +1960,8 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
|
||||
// Cleanup
|
||||
for (unsigned i = 0; i < subgraphs.size; i++) {
|
||||
array_delete(&subgraphs.contents[i].start_states);
|
||||
array_delete(&subgraphs.contents[i].nodes);
|
||||
array_delete(&array_get(&subgraphs, i)->start_states);
|
||||
array_delete(&array_get(&subgraphs, i)->nodes);
|
||||
}
|
||||
array_delete(&subgraphs);
|
||||
query_analysis__delete(&analysis);
|
||||
|
|
@ -1979,7 +1980,7 @@ static void ts_query__add_negated_fields(
|
|||
TSFieldId *field_ids,
|
||||
uint16_t field_count
|
||||
) {
|
||||
QueryStep *step = &self->steps.contents[step_index];
|
||||
QueryStep *step = array_get(&self->steps, step_index);
|
||||
|
||||
// The negated field array stores a list of field lists, separated by zeros.
|
||||
// Try to find the start index of an existing list that matches this new list.
|
||||
|
|
@ -1987,7 +1988,7 @@ static void ts_query__add_negated_fields(
|
|||
unsigned match_count = 0;
|
||||
unsigned start_i = 0;
|
||||
for (unsigned i = 0; i < self->negated_fields.size; i++) {
|
||||
TSFieldId existing_field_id = self->negated_fields.contents[i];
|
||||
TSFieldId existing_field_id = *array_get(&self->negated_fields, i);
|
||||
|
||||
// At each zero value, terminate the match attempt. If we've exactly
|
||||
// matched the new field list, then reuse this index. Otherwise,
|
||||
|
|
@ -2257,10 +2258,10 @@ static TSQueryError ts_query__parse_pattern(
|
|||
// For all of the branches except for the last one, add the subsequent branch as an
|
||||
// alternative, and link the end of the branch to the current end of the steps.
|
||||
for (unsigned i = 0; i < branch_step_indices.size - 1; i++) {
|
||||
uint32_t step_index = branch_step_indices.contents[i];
|
||||
uint32_t next_step_index = branch_step_indices.contents[i + 1];
|
||||
QueryStep *start_step = &self->steps.contents[step_index];
|
||||
QueryStep *end_step = &self->steps.contents[next_step_index - 1];
|
||||
uint32_t step_index = *array_get(&branch_step_indices, i);
|
||||
uint32_t next_step_index = *array_get(&branch_step_indices, i + 1);
|
||||
QueryStep *start_step = array_get(&self->steps, step_index);
|
||||
QueryStep *end_step = array_get(&self->steps, next_step_index - 1);
|
||||
start_step->alternative_index = next_step_index;
|
||||
end_step->alternative_index = self->steps.size;
|
||||
end_step->is_dead_end = true;
|
||||
|
|
@ -2540,13 +2541,13 @@ static TSQueryError ts_query__parse_pattern(
|
|||
last_child_step->alternative_index != NONE &&
|
||||
last_child_step->alternative_index < self->steps.size
|
||||
) {
|
||||
QueryStep *alternative_step = &self->steps.contents[last_child_step->alternative_index];
|
||||
QueryStep *alternative_step = array_get(&self->steps, last_child_step->alternative_index);
|
||||
alternative_step->is_last_child = true;
|
||||
while (
|
||||
alternative_step->alternative_index != NONE &&
|
||||
alternative_step->alternative_index < self->steps.size
|
||||
) {
|
||||
alternative_step = &self->steps.contents[alternative_step->alternative_index];
|
||||
alternative_step = array_get(&self->steps, alternative_step->alternative_index);
|
||||
alternative_step->is_last_child = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -2652,7 +2653,7 @@ static TSQueryError ts_query__parse_pattern(
|
|||
}
|
||||
|
||||
uint32_t step_index = starting_step_index;
|
||||
QueryStep *step = &self->steps.contents[step_index];
|
||||
QueryStep *step = array_get(&self->steps, step_index);
|
||||
for (;;) {
|
||||
step->field = field_id;
|
||||
if (
|
||||
|
|
@ -2661,7 +2662,7 @@ static TSQueryError ts_query__parse_pattern(
|
|||
step->alternative_index < self->steps.size
|
||||
) {
|
||||
step_index = step->alternative_index;
|
||||
step = &self->steps.contents[step_index];
|
||||
step = array_get(&self->steps, step_index);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
@ -2710,9 +2711,9 @@ static TSQueryError ts_query__parse_pattern(
|
|||
// Stop when `step->alternative_index` is `NONE` or it points to
|
||||
// `repeat_step` or beyond. Note that having just been pushed,
|
||||
// `repeat_step` occupies slot `self->steps.size - 1`.
|
||||
QueryStep *step = &self->steps.contents[starting_step_index];
|
||||
QueryStep *step = array_get(&self->steps, starting_step_index);
|
||||
while (step->alternative_index != NONE && step->alternative_index < self->steps.size - 1) {
|
||||
step = &self->steps.contents[step->alternative_index];
|
||||
step = array_get(&self->steps, step->alternative_index);
|
||||
}
|
||||
step->alternative_index = self->steps.size;
|
||||
}
|
||||
|
|
@ -2724,9 +2725,9 @@ static TSQueryError ts_query__parse_pattern(
|
|||
stream_advance(stream);
|
||||
stream_skip_whitespace(stream);
|
||||
|
||||
QueryStep *step = &self->steps.contents[starting_step_index];
|
||||
QueryStep *step = array_get(&self->steps, starting_step_index);
|
||||
while (step->alternative_index != NONE && step->alternative_index < self->steps.size) {
|
||||
step = &self->steps.contents[step->alternative_index];
|
||||
step = array_get(&self->steps, step->alternative_index);
|
||||
}
|
||||
step->alternative_index = self->steps.size;
|
||||
}
|
||||
|
|
@ -2752,7 +2753,7 @@ static TSQueryError ts_query__parse_pattern(
|
|||
|
||||
uint32_t step_index = starting_step_index;
|
||||
for (;;) {
|
||||
QueryStep *step = &self->steps.contents[step_index];
|
||||
QueryStep *step = array_get(&self->steps, step_index);
|
||||
query_step__add_capture(step, capture_id);
|
||||
if (
|
||||
step->alternative_index != NONE &&
|
||||
|
|
@ -2850,14 +2851,14 @@ TSQuery *ts_query_new(
|
|||
// Maintain a map that can look up patterns for a given root symbol.
|
||||
uint16_t wildcard_root_alternative_index = NONE;
|
||||
for (;;) {
|
||||
QueryStep *step = &self->steps.contents[start_step_index];
|
||||
QueryStep *step = array_get(&self->steps, start_step_index);
|
||||
|
||||
// If a pattern has a wildcard at its root, but it has a non-wildcard child,
|
||||
// then optimize the matching process by skipping matching the wildcard.
|
||||
// Later, during the matching process, the query cursor will check that
|
||||
// there is a parent node, and capture it if necessary.
|
||||
if (step->symbol == WILDCARD_SYMBOL && step->depth == 0 && !step->field) {
|
||||
QueryStep *second_step = &self->steps.contents[start_step_index + 1];
|
||||
QueryStep *second_step = array_get(&self->steps, start_step_index + 1);
|
||||
if (second_step->symbol != WILDCARD_SYMBOL && second_step->depth == 1 && !second_step->is_immediate) {
|
||||
wildcard_root_alternative_index = step->alternative_index;
|
||||
start_step_index += 1;
|
||||
|
|
@ -2872,7 +2873,7 @@ TSQuery *ts_query_new(
|
|||
uint32_t start_depth = step->depth;
|
||||
bool is_rooted = start_depth == 0;
|
||||
for (uint32_t step_index = start_step_index + 1; step_index < self->steps.size; step_index++) {
|
||||
QueryStep *child_step = &self->steps.contents[step_index];
|
||||
QueryStep *child_step = array_get(&self->steps, step_index);
|
||||
if (child_step->is_dead_end) break;
|
||||
if (child_step->depth == start_depth) {
|
||||
is_rooted = false;
|
||||
|
|
@ -2976,24 +2977,24 @@ const TSQueryPredicateStep *ts_query_predicates_for_pattern(
|
|||
uint32_t pattern_index,
|
||||
uint32_t *step_count
|
||||
) {
|
||||
Slice slice = self->patterns.contents[pattern_index].predicate_steps;
|
||||
Slice slice = array_get(&self->patterns, pattern_index)->predicate_steps;
|
||||
*step_count = slice.length;
|
||||
if (slice.length == 0) return NULL;
|
||||
return &self->predicate_steps.contents[slice.offset];
|
||||
return array_get(&self->predicate_steps, slice.offset);
|
||||
}
|
||||
|
||||
uint32_t ts_query_start_byte_for_pattern(
|
||||
const TSQuery *self,
|
||||
uint32_t pattern_index
|
||||
) {
|
||||
return self->patterns.contents[pattern_index].start_byte;
|
||||
return array_get(&self->patterns, pattern_index)->start_byte;
|
||||
}
|
||||
|
||||
uint32_t ts_query_end_byte_for_pattern(
|
||||
const TSQuery *self,
|
||||
uint32_t pattern_index
|
||||
) {
|
||||
return self->patterns.contents[pattern_index].end_byte;
|
||||
return array_get(&self->patterns, pattern_index)->end_byte;
|
||||
}
|
||||
|
||||
bool ts_query_is_pattern_rooted(
|
||||
|
|
@ -3001,7 +3002,7 @@ bool ts_query_is_pattern_rooted(
|
|||
uint32_t pattern_index
|
||||
) {
|
||||
for (unsigned i = 0; i < self->pattern_map.size; i++) {
|
||||
PatternEntry *entry = &self->pattern_map.contents[i];
|
||||
PatternEntry *entry = array_get(&self->pattern_map, i);
|
||||
if (entry->pattern_index == pattern_index) {
|
||||
if (!entry->is_rooted) return false;
|
||||
}
|
||||
|
|
@ -3014,7 +3015,7 @@ bool ts_query_is_pattern_non_local(
|
|||
uint32_t pattern_index
|
||||
) {
|
||||
if (pattern_index < self->patterns.size) {
|
||||
return self->patterns.contents[pattern_index].is_non_local;
|
||||
return array_get(&self->patterns, pattern_index)->is_non_local;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3026,12 +3027,12 @@ bool ts_query_is_pattern_guaranteed_at_step(
|
|||
) {
|
||||
uint32_t step_index = UINT32_MAX;
|
||||
for (unsigned i = 0; i < self->step_offsets.size; i++) {
|
||||
StepOffset *step_offset = &self->step_offsets.contents[i];
|
||||
StepOffset *step_offset = array_get(&self->step_offsets, i);
|
||||
if (step_offset->byte_offset > byte_offset) break;
|
||||
step_index = step_offset->step_index;
|
||||
}
|
||||
if (step_index < self->steps.size) {
|
||||
return self->steps.contents[step_index].root_pattern_guaranteed;
|
||||
return array_get(&self->steps, step_index)->root_pattern_guaranteed;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3042,8 +3043,8 @@ bool ts_query__step_is_fallible(
|
|||
uint16_t step_index
|
||||
) {
|
||||
ts_assert((uint32_t)step_index + 1 < self->steps.size);
|
||||
QueryStep *step = &self->steps.contents[step_index];
|
||||
QueryStep *next_step = &self->steps.contents[step_index + 1];
|
||||
QueryStep *step = array_get(&self->steps, step_index);
|
||||
QueryStep *next_step = array_get(&self->steps, step_index + 1);
|
||||
return (
|
||||
next_step->depth != PATTERN_DONE_MARKER &&
|
||||
next_step->depth > step->depth &&
|
||||
|
|
@ -3061,7 +3062,7 @@ void ts_query_disable_capture(
|
|||
int id = symbol_table_id_for_name(&self->captures, name, length);
|
||||
if (id != -1) {
|
||||
for (unsigned i = 0; i < self->steps.size; i++) {
|
||||
QueryStep *step = &self->steps.contents[i];
|
||||
QueryStep *step = array_get(&self->steps, i);
|
||||
query_step__remove_capture(step, id);
|
||||
}
|
||||
}
|
||||
|
|
@ -3074,7 +3075,7 @@ void ts_query_disable_pattern(
|
|||
// Remove the given pattern from the pattern map. Its steps will still
|
||||
// be in the `steps` array, but they will never be read.
|
||||
for (unsigned i = 0; i < self->pattern_map.size; i++) {
|
||||
PatternEntry *pattern = &self->pattern_map.contents[i];
|
||||
PatternEntry *pattern = array_get(&self->pattern_map, i);
|
||||
if (pattern->pattern_index == pattern_index) {
|
||||
array_erase(&self->pattern_map, i);
|
||||
i--;
|
||||
|
|
@ -3151,7 +3152,7 @@ void ts_query_cursor_exec(
|
|||
if (query) {
|
||||
LOG("query steps:\n");
|
||||
for (unsigned i = 0; i < query->steps.size; i++) {
|
||||
QueryStep *step = &query->steps.contents[i];
|
||||
QueryStep *step = array_get(&query->steps, i);
|
||||
LOG(" %u: {", i);
|
||||
if (step->depth == PATTERN_DONE_MARKER) {
|
||||
LOG("DONE");
|
||||
|
|
@ -3256,7 +3257,7 @@ static bool ts_query_cursor__first_in_progress_capture(
|
|||
*byte_offset = UINT32_MAX;
|
||||
*pattern_index = UINT32_MAX;
|
||||
for (unsigned i = 0; i < self->states.size; i++) {
|
||||
QueryState *state = &self->states.contents[i];
|
||||
QueryState *state = array_get(&self->states, i);
|
||||
if (state->dead) continue;
|
||||
|
||||
const CaptureList *captures = capture_list_pool_get(
|
||||
|
|
@ -3267,7 +3268,7 @@ static bool ts_query_cursor__first_in_progress_capture(
|
|||
continue;
|
||||
}
|
||||
|
||||
TSNode node = captures->contents[state->consumed_capture_count].node;
|
||||
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)
|
||||
|
|
@ -3283,7 +3284,7 @@ static bool ts_query_cursor__first_in_progress_capture(
|
|||
node_start_byte < *byte_offset ||
|
||||
(node_start_byte == *byte_offset && state->pattern_index < *pattern_index)
|
||||
) {
|
||||
QueryStep *step = &self->query->steps.contents[state->step_index];
|
||||
QueryStep *step = array_get(&self->query->steps, state->step_index);
|
||||
if (is_definite) {
|
||||
// We're being a bit conservative here by asserting that the following step
|
||||
// is not immediate, because this capture might end up being discarded if the
|
||||
|
|
@ -3339,8 +3340,8 @@ void ts_query_cursor__compare_captures(
|
|||
for (;;) {
|
||||
if (i < left_captures->size) {
|
||||
if (j < right_captures->size) {
|
||||
TSQueryCapture *left = &left_captures->contents[i];
|
||||
TSQueryCapture *right = &right_captures->contents[j];
|
||||
TSQueryCapture *left = array_get(left_captures, i);
|
||||
TSQueryCapture *right = array_get(right_captures, j);
|
||||
if (left->node.id == right->node.id && left->index == right->index) {
|
||||
i++;
|
||||
j++;
|
||||
|
|
@ -3379,7 +3380,7 @@ static void ts_query_cursor__add_state(
|
|||
TSQueryCursor *self,
|
||||
const PatternEntry *pattern
|
||||
) {
|
||||
QueryStep *step = &self->query->steps.contents[pattern->step_index];
|
||||
QueryStep *step = array_get(&self->query->steps, pattern->step_index);
|
||||
uint32_t start_depth = self->depth - step->depth;
|
||||
|
||||
// Keep the states array in ascending order of start_depth and pattern_index,
|
||||
|
|
@ -3403,7 +3404,7 @@ static void ts_query_cursor__add_state(
|
|||
// need to execute in order to keep the states ordered by pattern_index.
|
||||
uint32_t index = self->states.size;
|
||||
while (index > 0) {
|
||||
QueryState *prev_state = &self->states.contents[index - 1];
|
||||
QueryState *prev_state = array_get(&self->states, index - 1);
|
||||
if (prev_state->start_depth < start_depth) break;
|
||||
if (prev_state->start_depth == start_depth) {
|
||||
// Avoid inserting an unnecessary duplicate state, which would be
|
||||
|
|
@ -3467,7 +3468,7 @@ static CaptureList *ts_query_cursor__prepare_to_capture(
|
|||
" abandon state. index:%u, pattern:%u, offset:%u.\n",
|
||||
state_index, pattern_index, byte_offset
|
||||
);
|
||||
QueryState *other_state = &self->states.contents[state_index];
|
||||
QueryState *other_state = array_get(&self->states, state_index);
|
||||
state->capture_list_id = other_state->capture_list_id;
|
||||
other_state->capture_list_id = NONE;
|
||||
other_state->dead = true;
|
||||
|
|
@ -3537,8 +3538,8 @@ static QueryState *ts_query_cursor__copy_state(
|
|||
}
|
||||
|
||||
array_insert(&self->states, state_index + 1, copy);
|
||||
*state_ref = &self->states.contents[state_index];
|
||||
return &self->states.contents[state_index + 1];
|
||||
*state_ref = array_get(&self->states, state_index);
|
||||
return array_get(&self->states, state_index + 1);
|
||||
}
|
||||
|
||||
static inline bool ts_query_cursor__should_descend(
|
||||
|
|
@ -3553,8 +3554,8 @@ static inline bool ts_query_cursor__should_descend(
|
|||
// If there are in-progress matches whose remaining steps occur
|
||||
// deeper in the tree, then descend.
|
||||
for (unsigned i = 0; i < self->states.size; i++) {
|
||||
QueryState *state = &self->states.contents[i];;
|
||||
QueryStep *next_step = &self->query->steps.contents[state->step_index];
|
||||
QueryState *state = array_get(&self->states, i);
|
||||
QueryStep *next_step = array_get(&self->query->steps, state->step_index);
|
||||
if (
|
||||
next_step->depth != PATTERN_DONE_MARKER &&
|
||||
state->start_depth + next_step->depth > self->depth
|
||||
|
|
@ -3648,8 +3649,8 @@ static inline bool ts_query_cursor__advance(
|
|||
// After leaving a node, remove any states that cannot make further progress.
|
||||
uint32_t deleted_count = 0;
|
||||
for (unsigned i = 0, n = self->states.size; i < n; i++) {
|
||||
QueryState *state = &self->states.contents[i];
|
||||
QueryStep *step = &self->query->steps.contents[state->step_index];
|
||||
QueryState *state = array_get(&self->states, i);
|
||||
QueryStep *step = array_get(&self->query->steps, state->step_index);
|
||||
|
||||
// If a state completed its pattern inside of this node, but was deferred from finishing
|
||||
// in order to search for longer matches, mark it as finished.
|
||||
|
|
@ -3682,7 +3683,7 @@ static inline bool ts_query_cursor__advance(
|
|||
}
|
||||
|
||||
else if (deleted_count > 0) {
|
||||
self->states.contents[i - deleted_count] = *state;
|
||||
*array_get(&self->states, i - deleted_count) = *state;
|
||||
}
|
||||
}
|
||||
self->states.size -= deleted_count;
|
||||
|
|
@ -3785,11 +3786,11 @@ static inline bool ts_query_cursor__advance(
|
|||
// Add new states for any patterns whose root node is a wildcard.
|
||||
if (!node_is_error) {
|
||||
for (unsigned i = 0; i < self->query->wildcard_root_pattern_count; i++) {
|
||||
PatternEntry *pattern = &self->query->pattern_map.contents[i];
|
||||
PatternEntry *pattern = array_get(&self->query->pattern_map, i);
|
||||
|
||||
// If this node matches the first step of the pattern, then add a new
|
||||
// state at the start of this pattern.
|
||||
QueryStep *step = &self->query->steps.contents[pattern->step_index];
|
||||
QueryStep *step = array_get(&self->query->steps, pattern->step_index);
|
||||
uint32_t start_depth = self->depth - step->depth;
|
||||
if (
|
||||
(pattern->is_rooted ?
|
||||
|
|
@ -3807,9 +3808,9 @@ static inline bool ts_query_cursor__advance(
|
|||
// Add new states for any patterns whose root node matches this node.
|
||||
unsigned i;
|
||||
if (ts_query__pattern_map_search(self->query, symbol, &i)) {
|
||||
PatternEntry *pattern = &self->query->pattern_map.contents[i];
|
||||
PatternEntry *pattern = array_get(&self->query->pattern_map, i);
|
||||
|
||||
QueryStep *step = &self->query->steps.contents[pattern->step_index];
|
||||
QueryStep *step = array_get(&self->query->steps, pattern->step_index);
|
||||
uint32_t start_depth = self->depth - step->depth;
|
||||
do {
|
||||
// If this node matches the first step of the pattern, then add a new
|
||||
|
|
@ -3827,15 +3828,15 @@ static inline bool ts_query_cursor__advance(
|
|||
// Advance to the next pattern whose root node matches this node.
|
||||
i++;
|
||||
if (i == self->query->pattern_map.size) break;
|
||||
pattern = &self->query->pattern_map.contents[i];
|
||||
step = &self->query->steps.contents[pattern->step_index];
|
||||
pattern = array_get(&self->query->pattern_map, i);
|
||||
step = array_get(&self->query->steps, pattern->step_index);
|
||||
} while (step->symbol == symbol);
|
||||
}
|
||||
|
||||
// Update all of the in-progress states with current node.
|
||||
for (unsigned j = 0, copy_count = 0; j < self->states.size; j += 1 + copy_count) {
|
||||
QueryState *state = &self->states.contents[j];
|
||||
QueryStep *step = &self->query->steps.contents[state->step_index];
|
||||
QueryState *state = array_get(&self->states, j);
|
||||
QueryStep *step = array_get(&self->query->steps, state->step_index);
|
||||
state->has_in_progress_alternatives = false;
|
||||
copy_count = 0;
|
||||
|
||||
|
|
@ -3884,7 +3885,7 @@ static inline bool ts_query_cursor__advance(
|
|||
}
|
||||
|
||||
if (step->negated_field_list_id) {
|
||||
TSFieldId *negated_field_ids = &self->query->negated_fields.contents[step->negated_field_list_id];
|
||||
TSFieldId *negated_field_ids = array_get(&self->query->negated_fields, step->negated_field_list_id);
|
||||
for (;;) {
|
||||
TSFieldId negated_field_id = *negated_field_ids;
|
||||
if (negated_field_id) {
|
||||
|
|
@ -3985,7 +3986,7 @@ static inline bool ts_query_cursor__advance(
|
|||
state->step_index
|
||||
);
|
||||
|
||||
QueryStep *next_step = &self->query->steps.contents[state->step_index];
|
||||
QueryStep *next_step = array_get(&self->query->steps, state->step_index);
|
||||
|
||||
// For a given step, if the current symbol is the wildcard symbol, `_`, and it is **not**
|
||||
// named, meaning it should capture anonymous nodes, **and** the next step is immediate,
|
||||
|
|
@ -4008,8 +4009,8 @@ static inline bool ts_query_cursor__advance(
|
|||
// so this is an interactive process.
|
||||
unsigned end_index = j + 1;
|
||||
for (unsigned k = j; k < end_index; k++) {
|
||||
QueryState *child_state = &self->states.contents[k];
|
||||
QueryStep *child_step = &self->query->steps.contents[child_state->step_index];
|
||||
QueryState *child_state = array_get(&self->states, k);
|
||||
QueryStep *child_step = array_get(&self->query->steps, child_state->step_index);
|
||||
if (child_step->alternative_index != NONE) {
|
||||
// A "dead-end" step exists only to add a non-sequential jump into the step sequence,
|
||||
// via its alternative index. When a state reaches a dead-end step, it jumps straight
|
||||
|
|
@ -4050,7 +4051,7 @@ static inline bool ts_query_cursor__advance(
|
|||
}
|
||||
|
||||
for (unsigned j = 0; j < self->states.size; j++) {
|
||||
QueryState *state = &self->states.contents[j];
|
||||
QueryState *state = array_get(&self->states, j);
|
||||
if (state->dead) {
|
||||
array_erase(&self->states, j);
|
||||
j--;
|
||||
|
|
@ -4062,7 +4063,7 @@ static inline bool ts_query_cursor__advance(
|
|||
// one state has a strict subset of another state's captures.
|
||||
bool did_remove = false;
|
||||
for (unsigned k = j + 1; k < self->states.size; k++) {
|
||||
QueryState *other_state = &self->states.contents[k];
|
||||
QueryState *other_state = array_get(&self->states, k);
|
||||
|
||||
// Query states are kept in ascending order of start_depth and pattern_index.
|
||||
// Since the longest-match criteria is only used for deduping matches of the same
|
||||
|
|
@ -4122,7 +4123,7 @@ static inline bool ts_query_cursor__advance(
|
|||
state->step_index,
|
||||
capture_list_pool_get(&self->capture_list_pool, state->capture_list_id)->size
|
||||
);
|
||||
QueryStep *next_step = &self->query->steps.contents[state->step_index];
|
||||
QueryStep *next_step = array_get(&self->query->steps, state->step_index);
|
||||
if (next_step->depth == PATTERN_DONE_MARKER) {
|
||||
if (state->has_in_progress_alternatives) {
|
||||
LOG(" defer finishing pattern %u\n", state->pattern_index);
|
||||
|
|
@ -4167,7 +4168,7 @@ bool ts_query_cursor_next_match(
|
|||
}
|
||||
}
|
||||
|
||||
QueryState *state = &self->finished_states.contents[0];
|
||||
QueryState *state = array_get(&self->finished_states, 0);
|
||||
if (state->id == UINT32_MAX) state->id = self->next_state_id++;
|
||||
match->id = state->id;
|
||||
match->pattern_index = state->pattern_index;
|
||||
|
|
@ -4187,7 +4188,7 @@ void ts_query_cursor_remove_match(
|
|||
uint32_t match_id
|
||||
) {
|
||||
for (unsigned i = 0; i < self->finished_states.size; i++) {
|
||||
const QueryState *state = &self->finished_states.contents[i];
|
||||
const QueryState *state = array_get(&self->finished_states, i);
|
||||
if (state->id == match_id) {
|
||||
capture_list_pool_release(
|
||||
&self->capture_list_pool,
|
||||
|
|
@ -4201,7 +4202,7 @@ void ts_query_cursor_remove_match(
|
|||
// Remove unfinished query states as well to prevent future
|
||||
// captures for a match being removed.
|
||||
for (unsigned i = 0; i < self->states.size; i++) {
|
||||
const QueryState *state = &self->states.contents[i];
|
||||
const QueryState *state = array_get(&self->states, i);
|
||||
if (state->id == match_id) {
|
||||
capture_list_pool_release(
|
||||
&self->capture_list_pool,
|
||||
|
|
@ -4241,7 +4242,7 @@ bool ts_query_cursor_next_capture(
|
|||
uint32_t first_finished_capture_byte = first_unfinished_capture_byte;
|
||||
uint32_t first_finished_pattern_index = first_unfinished_pattern_index;
|
||||
for (unsigned i = 0; i < self->finished_states.size;) {
|
||||
QueryState *state = &self->finished_states.contents[i];
|
||||
QueryState *state = array_get(&self->finished_states, i);
|
||||
const CaptureList *captures = capture_list_pool_get(
|
||||
&self->capture_list_pool,
|
||||
state->capture_list_id
|
||||
|
|
@ -4257,7 +4258,7 @@ bool ts_query_cursor_next_capture(
|
|||
continue;
|
||||
}
|
||||
|
||||
TSNode node = captures->contents[state->consumed_capture_count].node;
|
||||
TSNode node = array_get(captures, state->consumed_capture_count)->node;
|
||||
|
||||
bool node_precedes_range = (
|
||||
ts_node_end_byte(node) <= self->start_byte ||
|
||||
|
|
@ -4297,7 +4298,7 @@ bool ts_query_cursor_next_capture(
|
|||
if (first_finished_state) {
|
||||
state = first_finished_state;
|
||||
} else if (first_unfinished_state_is_definite) {
|
||||
state = &self->states.contents[first_unfinished_state_index];
|
||||
state = array_get(&self->states, first_unfinished_state_index);
|
||||
} else {
|
||||
state = NULL;
|
||||
}
|
||||
|
|
@ -4326,7 +4327,7 @@ bool ts_query_cursor_next_capture(
|
|||
);
|
||||
capture_list_pool_release(
|
||||
&self->capture_list_pool,
|
||||
self->states.contents[first_unfinished_state_index].capture_list_id
|
||||
array_get(&self->states, first_unfinished_state_index)->capture_list_id
|
||||
);
|
||||
array_erase(&self->states, first_unfinished_state_index);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue