diff --git a/cli/src/generate/render.rs b/cli/src/generate/render.rs index bc7a6aa0..af167a5d 100644 --- a/cli/src/generate/render.rs +++ b/cli/src/generate/render.rs @@ -383,7 +383,7 @@ impl Generator { fn add_field_sequences(&mut self) { let mut flat_field_maps = vec![]; - let mut next_flat_field_map_index = self.parse_table.child_infos.len(); + let mut next_flat_field_map_index = 0; self.get_field_map_id( &Vec::new(), &mut flat_field_maps, @@ -412,29 +412,41 @@ impl Generator { } } - add_line!(self, "static const TSFieldMapping ts_field_map[] = {{",); + add_line!( + self, + "static const TSFieldMapSlice ts_field_map_slices[] = {{", + ); indent!(self); - - add_line!(self, "/* child info id -> (field map index, count) */"); for (child_info_id, (row_id, length)) in field_map_ids.into_iter().enumerate() { if length > 0 { - add_line!(self, "[{}] = {{{}, {}, 0}},", child_info_id, row_id, length); + add_line!( + self, + "[{}] = {{.index = {}, .length = {}}},", + child_info_id, + row_id, + length + ); } } + dedent!(self); + add_line!(self, "}};"); + add_line!(self, ""); - add!(self, "\n"); - add_line!(self, "/* field id -> child index */"); + add_line!( + self, + "static const TSFieldMapEntry ts_field_map_entries[] = {{", + ); + indent!(self); for (row_index, field_pairs) in flat_field_maps.into_iter().skip(1) { add_line!(self, "[{}] =", row_index); indent!(self); for (field_name, location) in field_pairs { - add_line!( - self, - "{{{}, {}, {}}},", - self.field_id(&field_name), - location.index, - location.inherited - ); + add_whitespace!(self); + add!(self, "{{{}, {}", self.field_id(&field_name), location.index); + if location.inherited { + add!(self, ", .inherited = true"); + } + add!(self, "}},\n"); } dedent!(self); } @@ -887,8 +899,15 @@ impl Generator { add_line!(self, ".field_count = FIELD_COUNT,"); if !self.field_names.is_empty() { - add_line!(self, ".field_map = (const TSFieldMapping *)ts_field_map,"); add_line!(self, ".field_names = ts_field_names,"); + add_line!( + self, + ".field_map_slices = (const TSFieldMapSlice *)ts_field_map_slices," + ); + add_line!( + self, + ".field_map_entries = (const TSFieldMapEntry *)ts_field_map_entries," + ); } add_line!( @@ -1007,7 +1026,7 @@ impl Generator { } fn field_id(&self, field_name: &String) -> String { - format!("field_id_{}", field_name) + format!("field_{}", field_name) } fn metadata_for_symbol(&self, symbol: Symbol) -> (&str, VariableType) { diff --git a/lib/include/tree_sitter/parser.h b/lib/include/tree_sitter/parser.h index d81d0271..9d25a40f 100644 --- a/lib/include/tree_sitter/parser.h +++ b/lib/include/tree_sitter/parser.h @@ -23,7 +23,12 @@ typedef struct { TSFieldId field_id; uint8_t child_index; bool inherited; -} TSFieldMapping; +} TSFieldMapEntry; + +typedef struct { + uint16_t index; + uint16_t length; +} TSFieldMapSlice; typedef uint16_t TSStateId; @@ -106,7 +111,8 @@ struct TSLanguage { void (*deserialize)(void *, const char *, unsigned); } external_scanner; uint32_t field_count; - const TSFieldMapping *field_map; + const TSFieldMapSlice *field_map_slices; + const TSFieldMapEntry *field_map_entries; const char **field_names; }; diff --git a/lib/src/language.h b/lib/src/language.h index 09adca62..908c0646 100644 --- a/lib/src/language.h +++ b/lib/src/language.h @@ -90,18 +90,12 @@ ts_language_alias_sequence(const TSLanguage *self, uint32_t child_info_id) { static inline void ts_language_field_map( const TSLanguage *self, uint32_t child_info_id, - const TSFieldMapping **start, - const TSFieldMapping **end + const TSFieldMapEntry **start, + const TSFieldMapEntry **end ) { - // To find the field mappings for a given child info id, first index - // into the field map using the child info id directly. This 'header' - // row contains two values: - // * the index where the field mappings start - // * the number of field mappings. - const TSFieldMapping *field_map = self->field_map; - TSFieldMapping header = field_map[child_info_id]; - *start = &field_map[header.field_id]; - *end = &field_map[header.field_id] + header.child_index; + TSFieldMapSlice slice = self->field_map_slices[child_info_id]; + *start = &self->field_map_entries[slice.index]; + *end = &self->field_map_entries[slice.index] + slice.length; } #ifdef __cplusplus diff --git a/lib/src/node.c b/lib/src/node.c index 7ae8f115..6ac4636d 100644 --- a/lib/src/node.c +++ b/lib/src/node.c @@ -461,7 +461,7 @@ TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) { recur: if (!field_id || ts_node_child_count(self) == 0) return ts_node__null(); - const TSFieldMapping *field_map, *field_map_end; + const TSFieldMapEntry *field_map, *field_map_end; ts_language_field_map( self.tree->language, ts_node__subtree(self).ptr->child_info_id, diff --git a/lib/src/tree_cursor.c b/lib/src/tree_cursor.c index 099992b9..4f3f9ae7 100644 --- a/lib/src/tree_cursor.c +++ b/lib/src/tree_cursor.c @@ -264,7 +264,7 @@ TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) { } } - const TSFieldMapping *field_map, *field_map_end; + const TSFieldMapEntry *field_map, *field_map_end; ts_language_field_map( self->tree->language, parent_entry->subtree->ptr->child_info_id,