fix(lib): replace raw array accesses with array_get

(cherry picked from commit 8bd923ab9e)
This commit is contained in:
Will Lillis 2025-05-04 00:12:07 -04:00 committed by Amaan Qureshi
parent bf655c0bea
commit b890e8bea0
7 changed files with 229 additions and 227 deletions

View file

@ -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);
}