From d853b6504d342f2c55fe1737490beb236a13334a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 31 Jan 2017 10:21:47 -0800 Subject: [PATCH] Add version number to TSLanguage structs --- include/tree_sitter/parser.h | 2 ++ include/tree_sitter/runtime.h | 3 +++ spec/runtime/document_spec.cc | 11 +++++++++++ src/compiler/generate_code/c_code.cc | 4 +++- src/runtime/document.c | 1 + src/runtime/language.c | 4 ++++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index 8e5658f4..197015f4 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -65,6 +65,7 @@ typedef union { } TSParseActionEntry; typedef struct TSLanguage { + uint32_t version; uint32_t symbol_count; uint32_t token_count; uint32_t external_token_count; @@ -166,6 +167,7 @@ typedef struct TSLanguage { #define GET_LANGUAGE(...) \ static TSLanguage language = { \ + .version = LANGUAGE_VERSION, \ .symbol_count = SYMBOL_COUNT, \ .token_count = TOKEN_COUNT, \ .symbol_metadata = ts_symbol_metadata, \ diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 68e804f1..00d8e7c4 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -9,6 +9,8 @@ extern "C" { #include #include +#define TREE_SITTER_LANGUAGE_VERSION 1 + typedef unsigned short TSSymbol; typedef struct TSLanguage TSLanguage; typedef struct TSDocument TSDocument; @@ -114,6 +116,7 @@ uint32_t ts_document_parse_count(const TSDocument *); uint32_t ts_language_symbol_count(const TSLanguage *); const char *ts_language_symbol_name(const TSLanguage *, TSSymbol); +uint32_t ts_language_version(const TSLanguage *); #ifdef __cplusplus } diff --git a/spec/runtime/document_spec.cc b/spec/runtime/document_spec.cc index 2694acc6..52e65ffb 100644 --- a/spec/runtime/document_spec.cc +++ b/spec/runtime/document_spec.cc @@ -164,6 +164,17 @@ describe("Document", [&]() { "(program (expression_statement " "(object (pair (string) (array (number) (number))))))"); }); + + it("does not allow setting a language with a different version number", [&]() { + TSLanguage language = *get_test_language("json"); + AssertThat(ts_language_version(&language), Equals(TREE_SITTER_LANGUAGE_VERSION)); + + language.version++; + AssertThat(ts_language_version(&language), !Equals(TREE_SITTER_LANGUAGE_VERSION)); + + ts_document_set_language(document, &language); + AssertThat(ts_document_language(document), IsNull()); + }); }); describe("set_logger(TSLogger)", [&]() { diff --git a/src/compiler/generate_code/c_code.cc b/src/compiler/generate_code/c_code.cc index a28648c8..755a7402 100644 --- a/src/compiler/generate_code/c_code.cc +++ b/src/compiler/generate_code/c_code.cc @@ -11,6 +11,7 @@ #include "compiler/lexical_grammar.h" #include "compiler/rules/built_in_symbols.h" #include "compiler/util/string_helpers.h" +#include "tree_sitter/runtime.h" namespace tree_sitter { namespace generate_code { @@ -134,6 +135,7 @@ class CCodeGenerator { } } + line("#define LANGUAGE_VERSION " + to_string(TREE_SITTER_LANGUAGE_VERSION)); line("#define STATE_COUNT " + to_string(parse_table.states.size())); line("#define SYMBOL_COUNT " + to_string(parse_table.symbols.size())); line("#define TOKEN_COUNT " + to_string(token_count)); @@ -227,7 +229,7 @@ class CCodeGenerator { for (size_t i = 0, n = lexical_grammar.variables.size(); i < n; i++) { for (size_t j = 0; j < syntax_grammar.external_tokens.size(); j++) { const ExternalToken &external_token = syntax_grammar.external_tokens[j]; - if (external_token.corresponding_internal_token.index == i) { + if (external_token.corresponding_internal_token.index == Symbol::Index(i)) { external_tokens_by_corresponding_internal_token.insert({i, j}); break; } diff --git a/src/runtime/document.c b/src/runtime/document.c index c68d8c62..8c1eb779 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -36,6 +36,7 @@ const TSLanguage *ts_document_language(TSDocument *self) { } void ts_document_set_language(TSDocument *self, const TSLanguage *language) { + if (language->version != TREE_SITTER_LANGUAGE_VERSION) return; ts_document_invalidate(self); parser_set_language(&self->parser, language); if (self->tree) { diff --git a/src/runtime/language.c b/src/runtime/language.c index af08bb38..7f1bdefa 100644 --- a/src/runtime/language.c +++ b/src/runtime/language.c @@ -34,6 +34,10 @@ uint32_t ts_language_symbol_count(const TSLanguage *language) { return language->symbol_count; } +uint32_t ts_language_version(const TSLanguage *language) { + return language->version; +} + TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *language, TSSymbol symbol) { if (symbol == ts_builtin_sym_error)