diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index c1a6dea9..c1ad5c53 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -43,7 +43,7 @@ typedef struct TSLexer { TSSymbol result_symbol; TSInput input; - TSDebugger debugger; + TSLogger logger; char debug_buffer[TS_DEBUG_BUFFER_SIZE]; } TSLexer; diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index d57e60d9..8b9a863e 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -19,20 +19,20 @@ typedef enum { typedef struct { void *payload; - const char *(*read_fn)(void *payload, size_t *bytes_read); - int (*seek_fn)(void *payload, size_t character, size_t byte); + const char *(*read)(void *payload, size_t *bytes_read); + int (*seek)(void *payload, size_t character_index, size_t byte_index); TSInputEncoding encoding; } TSInput; typedef enum { - TSDebugTypeParse, - TSDebugTypeLex, -} TSDebugType; + TSLogTypeParse, + TSLogTypeLex, +} TSLogType; typedef struct { void *payload; - void (*debug_fn)(void *payload, TSDebugType, const char *); -} TSDebugger; + void (*log)(void *payload, TSLogType, const char *); +} TSLogger; typedef struct { size_t position; @@ -65,7 +65,7 @@ TSPoint ts_node_end_point(TSNode); TSSymbol ts_node_symbol(TSNode); TSSymbolIterator ts_node_symbols(TSNode); void ts_symbol_iterator_next(TSSymbolIterator *); -const char *ts_node_name(TSNode, const TSDocument *); +const char *ts_node_type(TSNode, const TSDocument *); char *ts_node_string(TSNode, const TSDocument *); bool ts_node_eq(TSNode, TSNode); bool ts_node_is_named(TSNode); @@ -79,18 +79,22 @@ TSNode ts_node_next_sibling(TSNode); TSNode ts_node_next_named_sibling(TSNode); TSNode ts_node_prev_sibling(TSNode); TSNode ts_node_prev_named_sibling(TSNode); -TSNode ts_node_descendant_for_range(TSNode, size_t, size_t); -TSNode ts_node_named_descendant_for_range(TSNode, size_t, size_t); +TSNode ts_node_descendant_for_char_range(TSNode, size_t, size_t); +TSNode ts_node_named_descendant_for_char_range(TSNode, size_t, size_t); +TSNode ts_node_descendant_for_byte_range(TSNode, size_t, size_t); +TSNode ts_node_named_descendant_for_byte_range(TSNode, size_t, size_t); +TSNode ts_node_descendant_for_point_range(TSNode, TSPoint, TSPoint); +TSNode ts_node_named_descendant_for_point_range(TSNode, TSPoint, TSPoint); -TSDocument *ts_document_make(); +TSDocument *ts_document_new(); void ts_document_free(TSDocument *); const TSLanguage *ts_document_language(TSDocument *); void ts_document_set_language(TSDocument *, const TSLanguage *); TSInput ts_document_input(TSDocument *); void ts_document_set_input(TSDocument *, TSInput); void ts_document_set_input_string(TSDocument *, const char *); -TSDebugger ts_document_debugger(const TSDocument *); -void ts_document_set_debugger(TSDocument *, TSDebugger); +TSLogger ts_document_logger(const TSDocument *); +void ts_document_set_logger(TSDocument *, TSLogger); void ts_document_print_debugging_graphs(TSDocument *, bool); void ts_document_edit(TSDocument *, TSInputEdit); int ts_document_parse(TSDocument *); diff --git a/spec/helpers/log_debugger.h b/spec/helpers/log_debugger.h deleted file mode 100644 index 0b0e0720..00000000 --- a/spec/helpers/log_debugger.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef HELPERS_LOG_DEBUGGER_H_ -#define HELPERS_LOG_DEBUGGER_H_ - -#include "tree_sitter/runtime.h" - -TSDebugger log_debugger_make(bool include_lexing); - -#endif // HELPERS_LOG_DEBUGGER_H_ diff --git a/spec/helpers/spy_debugger.cc b/spec/helpers/spy_debugger.cc deleted file mode 100644 index 15bc69ec..00000000 --- a/spec/helpers/spy_debugger.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "helpers/spy_debugger.h" -#include -#include - -using std::string; -using std::vector; - -static void spy_debug(void *data, TSDebugType type, const char *msg) { - SpyDebugger *debugger = static_cast(data); - debugger->messages.push_back(msg); -} - -TSDebugger SpyDebugger::debugger() { - TSDebugger result; - result.payload = (void *)this; - result.debug_fn = spy_debug; - return result; -} - -void SpyDebugger::clear() { - messages.clear(); -} diff --git a/spec/helpers/spy_input.cc b/spec/helpers/spy_input.cc index 3968bcc2..d5d4bf96 100644 --- a/spec/helpers/spy_input.cc +++ b/spec/helpers/spy_input.cc @@ -63,8 +63,8 @@ TSInput SpyInput::input() { TSInput result; result.payload = this; result.encoding = encoding; - result.seek_fn = seek; - result.read_fn = read; + result.seek = seek; + result.read = read; return result; } diff --git a/spec/helpers/spy_logger.cc b/spec/helpers/spy_logger.cc new file mode 100644 index 00000000..7e3a92a1 --- /dev/null +++ b/spec/helpers/spy_logger.cc @@ -0,0 +1,22 @@ +#include "helpers/spy_logger.h" +#include +#include + +using std::string; +using std::vector; + +static void spy_log(void *data, TSLogType type, const char *msg) { + SpyLogger *logger = static_cast(data); + logger->messages.push_back(msg); +} + +TSLogger SpyLogger::logger() { + TSLogger result; + result.payload = (void *)this; + result.log = spy_log; + return result; +} + +void SpyLogger::clear() { + messages.clear(); +} diff --git a/spec/helpers/spy_debugger.h b/spec/helpers/spy_logger.h similarity index 61% rename from spec/helpers/spy_debugger.h rename to spec/helpers/spy_logger.h index 811d4e76..9f98fcb8 100644 --- a/spec/helpers/spy_debugger.h +++ b/spec/helpers/spy_logger.h @@ -1,14 +1,14 @@ -#ifndef HELPERS_SPY_DEBUGGER_H_ -#define HELPERS_SPY_DEBUGGER_H_ +#ifndef HELPERS_SPY_LOGGER_H_ +#define HELPERS_SPY_LOGGER_H_ #include #include #include "tree_sitter/runtime.h" -class SpyDebugger { +class SpyLogger { public: void clear(); - TSDebugger debugger(); + TSLogger logger(); std::vector messages; }; diff --git a/spec/helpers/log_debugger.cc b/spec/helpers/stderr_logger.cc similarity index 57% rename from spec/helpers/log_debugger.cc rename to spec/helpers/stderr_logger.cc index a65ab333..a6ebbe61 100644 --- a/spec/helpers/log_debugger.cc +++ b/spec/helpers/stderr_logger.cc @@ -1,22 +1,22 @@ #include "tree_sitter/runtime.h" #include -static void log_debug(void *payload, TSDebugType type, const char *msg) { +static void log(void *payload, TSLogType type, const char *msg) { bool include_lexing = (bool)payload; switch (type) { - case TSDebugTypeParse: + case TSLogTypeParse: fprintf(stderr, "* %s\n", msg); break; - case TSDebugTypeLex: + case TSLogTypeLex: if (include_lexing) fprintf(stderr, " %s\n", msg); break; } } -TSDebugger log_debugger_make(bool include_lexing) { - TSDebugger result; +TSLogger stderr_logger_new(bool include_lexing) { + TSLogger result; result.payload = (void *)include_lexing; - result.debug_fn = log_debug; + result.log = log; return result; } diff --git a/spec/helpers/stderr_logger.h b/spec/helpers/stderr_logger.h new file mode 100644 index 00000000..9c88b21d --- /dev/null +++ b/spec/helpers/stderr_logger.h @@ -0,0 +1,8 @@ +#ifndef HELPERS_STDERR_LOGGER_H_ +#define HELPERS_STDERR_LOGGER_H_ + +#include "tree_sitter/runtime.h" + +TSLogger stderr_logger_new(bool include_lexing); + +#endif // HELPERS_STDERR_LOGGER_H_ diff --git a/spec/integration/compile_grammar_spec.cc b/spec/integration/compile_grammar_spec.cc index 06891c8b..a8f8988d 100644 --- a/spec/integration/compile_grammar_spec.cc +++ b/spec/integration/compile_grammar_spec.cc @@ -8,7 +8,7 @@ describe("compile_grammar", []() { TSDocument *document; before_each([&]() { - document = ts_document_make(); + document = ts_document_new(); }); after_each([&]() { diff --git a/spec/integration/corpus_specs.cc b/spec/integration/corpus_specs.cc index 485aef79..3653809d 100644 --- a/spec/integration/corpus_specs.cc +++ b/spec/integration/corpus_specs.cc @@ -3,7 +3,7 @@ #include "helpers/load_language.h" #include "helpers/read_test_entries.h" #include "helpers/spy_input.h" -#include "helpers/log_debugger.h" +#include "helpers/stderr_logger.h" #include "helpers/point_helpers.h" #include "helpers/encoding_helpers.h" #include "helpers/record_alloc.h" @@ -77,10 +77,10 @@ describe("The Corpus", []() { before_each([&]() { record_alloc::start(); - document = ts_document_make(); + document = ts_document_new(); ts_document_set_language(document, get_test_language(language_name)); - // ts_document_set_debugger(document, log_debugger_make(true)); + // ts_document_set_logger(document, stderr_logger_new(true)); // ts_document_print_debugging_graphs(document, true); }); diff --git a/spec/runtime/document_spec.cc b/spec/runtime/document_spec.cc index 05ded944..ec479b4e 100644 --- a/spec/runtime/document_spec.cc +++ b/spec/runtime/document_spec.cc @@ -1,13 +1,11 @@ #include "spec_helper.h" #include "runtime/alloc.h" -#include "runtime/debugger.h" #include "helpers/record_alloc.h" #include "helpers/stream_methods.h" #include "helpers/tree_helpers.h" -#include "helpers/spy_debugger.h" +#include "helpers/spy_logger.h" #include "helpers/spy_input.h" #include "helpers/load_language.h" -#include "helpers/log_debugger.h" START_TEST @@ -17,7 +15,7 @@ describe("Document", [&]() { before_each([&]() { record_alloc::start(); - doc = ts_document_make(); + doc = ts_document_new(); }); after_each([&]() { @@ -71,8 +69,8 @@ describe("Document", [&]() { it("allows the input to be retrieved later", [&]() { ts_document_set_input(doc, spy_input->input()); AssertThat(ts_document_input(doc).payload, Equals(spy_input)); - AssertThat(ts_document_input(doc).read_fn, Equals(spy_input->input().read_fn)); - AssertThat(ts_document_input(doc).seek_fn, Equals(spy_input->input().seek_fn)); + AssertThat(ts_document_input(doc).read, Equals(spy_input->input().read)); + AssertThat(ts_document_input(doc).seek, Equals(spy_input->input().seek)); }); it("does not assume that the document's text has changed", [&]() { @@ -146,51 +144,51 @@ describe("Document", [&]() { }); }); - describe("set_debugger(TSDebugger)", [&]() { - SpyDebugger *debugger; + describe("set_logger(TSDebugger)", [&]() { + SpyLogger *logger; before_each([&]() { - debugger = new SpyDebugger(); + logger = new SpyLogger(); ts_document_set_language(doc, get_test_language("json")); ts_document_set_input_string(doc, "[1, 2]"); }); after_each([&]() { - delete debugger; + delete logger; }); it("calls the debugger with a message for each lex action", [&]() { - ts_document_set_debugger(doc, debugger->debugger()); + ts_document_set_logger(doc, logger->logger()); ts_document_parse(doc); - AssertThat(debugger->messages, Contains("lookahead char:'1'")); - AssertThat(debugger->messages, Contains("lookahead char:'['")); + AssertThat(logger->messages, Contains("lookahead char:'1'")); + AssertThat(logger->messages, Contains("lookahead char:'['")); }); it("calls the debugger with a message for each parse action", [&]() { - ts_document_set_debugger(doc, debugger->debugger()); + ts_document_set_logger(doc, logger->logger()); ts_document_parse(doc); - AssertThat(debugger->messages, Contains("new_parse")); - AssertThat(debugger->messages, Contains("lookahead char:'['")); - AssertThat(debugger->messages, Contains("reduce sym:array, child_count:4")); - AssertThat(debugger->messages, Contains("accept")); + AssertThat(logger->messages, Contains("new_parse")); + AssertThat(logger->messages, Contains("lookahead char:'['")); + AssertThat(logger->messages, Contains("reduce sym:array, child_count:4")); + AssertThat(logger->messages, Contains("accept")); }); it("allows the debugger to be retrieved later", [&]() { - ts_document_set_debugger(doc, debugger->debugger()); - AssertThat(ts_document_debugger(doc).payload, Equals(debugger)); + ts_document_set_logger(doc, logger->logger()); + AssertThat(ts_document_logger(doc).payload, Equals(logger)); }); describe("disabling debugging", [&]() { before_each([&]() { - ts_document_set_debugger(doc, debugger->debugger()); - ts_document_set_debugger(doc, ts_debugger_null()); + ts_document_set_logger(doc, logger->logger()); + ts_document_set_logger(doc, {NULL, NULL}); }); it("does not call the debugger any more", [&]() { ts_document_parse(doc); - AssertThat(debugger->messages, IsEmpty()); + AssertThat(logger->messages, IsEmpty()); }); }); }); diff --git a/spec/runtime/node_spec.cc b/spec/runtime/node_spec.cc index 11e473a8..056362a6 100644 --- a/spec/runtime/node_spec.cc +++ b/spec/runtime/node_spec.cc @@ -11,7 +11,8 @@ START_TEST describe("Node", []() { TSDocument *document; TSNode array_node; - string input_string = "\n" + string input_string = + "\n" "\n" "[\n" " 123,\n" @@ -38,7 +39,7 @@ describe("Node", []() { before_each([&]() { record_alloc::start(); - document = ts_document_make(); + document = ts_document_new(); ts_document_set_language(document, get_test_language("json")); ts_document_set_input_string(document, input_string.c_str()); ts_document_parse(document); @@ -62,7 +63,7 @@ describe("Node", []() { describe("named_child_count(), named_child(i)", [&]() { it("returns the named child node at the given index", [&]() { - AssertThat(ts_node_name(array_node, document), Equals("array")); + AssertThat(ts_node_type(array_node, document), Equals("array")); AssertThat(ts_node_named_child_count(array_node), Equals(3)); AssertThat(ts_node_start_byte(array_node), Equals(array_index)); @@ -76,9 +77,9 @@ describe("Node", []() { TSNode false_node = ts_node_named_child(array_node, 1); TSNode object_node = ts_node_named_child(array_node, 2); - AssertThat(ts_node_name(number_node, document), Equals("number")); - AssertThat(ts_node_name(false_node, document), Equals("false")); - AssertThat(ts_node_name(object_node, document), Equals("object")); + AssertThat(ts_node_type(number_node, document), Equals("number")); + AssertThat(ts_node_type(false_node, document), Equals("false")); + AssertThat(ts_node_type(object_node, document), Equals("object")); AssertThat(ts_node_start_byte(number_node), Equals(number_index)); AssertThat(ts_node_end_byte(number_node), Equals(number_end_index)); @@ -100,7 +101,7 @@ describe("Node", []() { TSNode pair_node = ts_node_named_child(object_node, 0); - AssertThat(ts_node_name(pair_node, document), Equals("pair")); + AssertThat(ts_node_type(pair_node, document), Equals("pair")); AssertThat(ts_node_start_byte(pair_node), Equals(string_index)); AssertThat(ts_node_end_byte(pair_node), Equals(null_end_index)); AssertThat(ts_node_start_point(pair_node), Equals({ 6, 4 })); @@ -110,8 +111,8 @@ describe("Node", []() { TSNode string_node = ts_node_named_child(pair_node, 0); TSNode null_node = ts_node_named_child(pair_node, 1); - AssertThat(ts_node_name(string_node, document), Equals("string")); - AssertThat(ts_node_name(null_node, document), Equals("null")); + AssertThat(ts_node_type(string_node, document), Equals("string")); + AssertThat(ts_node_type(null_node, document), Equals("null")); AssertThat(ts_node_start_byte(string_node), Equals(string_index)); AssertThat(ts_node_end_byte(string_node), Equals(string_end_index)); @@ -148,7 +149,7 @@ describe("Node", []() { ts_symbol_iterator_next(&iterator); AssertThat(iterator.done, Equals(true)); - TSNode false_node = ts_node_descendant_for_range(array_node, false_index, false_index + 1); + TSNode false_node = ts_node_descendant_for_char_range(array_node, false_index, false_index + 1); iterator = ts_node_symbols(false_node); AssertThat(iterator.done, Equals(false)); AssertThat(ts_language_symbol_name(language, iterator.value), Equals("false")); @@ -160,7 +161,7 @@ describe("Node", []() { ts_symbol_iterator_next(&iterator); AssertThat(iterator.done, Equals(true)); - TSNode comma_node = ts_node_descendant_for_range(array_node, number_end_index, number_end_index); + TSNode comma_node = ts_node_descendant_for_char_range(array_node, number_end_index, number_end_index); iterator = ts_node_symbols(comma_node); AssertThat(iterator.done, Equals(false)); AssertThat(ts_language_symbol_name(language, iterator.value), Equals(",")); @@ -181,14 +182,14 @@ describe("Node", []() { TSNode child6 = ts_node_child(array_node, 5); TSNode child7 = ts_node_child(array_node, 6); - AssertThat(ts_node_name(array_node, document), Equals("array")); - AssertThat(ts_node_name(child1, document), Equals("[")); - AssertThat(ts_node_name(child2, document), Equals("number")); - AssertThat(ts_node_name(child3, document), Equals(",")); - AssertThat(ts_node_name(child4, document), Equals("false")); - AssertThat(ts_node_name(child5, document), Equals(",")); - AssertThat(ts_node_name(child6, document), Equals("object")); - AssertThat(ts_node_name(child7, document), Equals("]")); + AssertThat(ts_node_type(array_node, document), Equals("array")); + AssertThat(ts_node_type(child1, document), Equals("[")); + AssertThat(ts_node_type(child2, document), Equals("number")); + AssertThat(ts_node_type(child3, document), Equals(",")); + AssertThat(ts_node_type(child4, document), Equals("false")); + AssertThat(ts_node_type(child5, document), Equals(",")); + AssertThat(ts_node_type(child6, document), Equals("object")); + AssertThat(ts_node_type(child7, document), Equals("]")); AssertThat(ts_node_is_named(array_node), IsTrue()); AssertThat(ts_node_is_named(child1), IsFalse()); @@ -229,13 +230,13 @@ describe("Node", []() { TSNode grandchild3 = ts_node_child(pair, 1); TSNode grandchild4 = ts_node_child(pair, 2); - AssertThat(ts_node_name(left_brace, document), Equals("{")); - AssertThat(ts_node_name(pair, document), Equals("pair")); - AssertThat(ts_node_name(right_brace, document), Equals("}")); + AssertThat(ts_node_type(left_brace, document), Equals("{")); + AssertThat(ts_node_type(pair, document), Equals("pair")); + AssertThat(ts_node_type(right_brace, document), Equals("}")); - AssertThat(ts_node_name(grandchild2, document), Equals("string")); - AssertThat(ts_node_name(grandchild3, document), Equals(":")); - AssertThat(ts_node_name(grandchild4, document), Equals("null")); + AssertThat(ts_node_type(grandchild2, document), Equals("string")); + AssertThat(ts_node_type(grandchild3, document), Equals(":")); + AssertThat(ts_node_type(grandchild4, document), Equals("null")); AssertThat(ts_node_parent(grandchild2), Equals(pair)); AssertThat(ts_node_parent(grandchild3), Equals(pair)); @@ -332,18 +333,18 @@ describe("Node", []() { }); }); - describe("named_descendant_for_range(start, end)", [&]() { + describe("named_descendant_for_char_range(start, end)", [&]() { describe("when there is a leaf node that spans the given range exactly", [&]() { it("returns that leaf node", [&]() { - TSNode leaf = ts_node_named_descendant_for_range(array_node, string_index, string_end_index - 1); - AssertThat(ts_node_name(leaf, document), Equals("string")); + TSNode leaf = ts_node_named_descendant_for_char_range(array_node, string_index, string_end_index - 1); + AssertThat(ts_node_type(leaf, document), Equals("string")); AssertThat(ts_node_start_byte(leaf), Equals(string_index)); AssertThat(ts_node_end_byte(leaf), Equals(string_end_index)); AssertThat(ts_node_start_point(leaf), Equals({ 6, 4 })); AssertThat(ts_node_end_point(leaf), Equals({ 6, 7 })); - leaf = ts_node_named_descendant_for_range(array_node, number_index, number_end_index - 1); - AssertThat(ts_node_name(leaf, document), Equals("number")); + leaf = ts_node_named_descendant_for_char_range(array_node, number_index, number_end_index - 1); + AssertThat(ts_node_type(leaf, document), Equals("number")); AssertThat(ts_node_start_byte(leaf), Equals(number_index)); AssertThat(ts_node_end_byte(leaf), Equals(number_end_index)); AssertThat(ts_node_start_point(leaf), Equals({ 3, 2 })); @@ -353,15 +354,15 @@ describe("Node", []() { describe("when there is a leaf node that extends beyond the given range", [&]() { it("returns that leaf node", [&]() { - TSNode leaf = ts_node_named_descendant_for_range(array_node, string_index, string_index + 1); - AssertThat(ts_node_name(leaf, document), Equals("string")); + TSNode leaf = ts_node_named_descendant_for_char_range(array_node, string_index, string_index + 1); + AssertThat(ts_node_type(leaf, document), Equals("string")); AssertThat(ts_node_start_byte(leaf), Equals(string_index)); AssertThat(ts_node_end_byte(leaf), Equals(string_end_index)); AssertThat(ts_node_start_point(leaf), Equals({ 6, 4 })); AssertThat(ts_node_end_point(leaf), Equals({ 6, 7 })); - leaf = ts_node_named_descendant_for_range(array_node, string_index + 1, string_index + 2); - AssertThat(ts_node_name(leaf, document), Equals("string")); + leaf = ts_node_named_descendant_for_char_range(array_node, string_index + 1, string_index + 2); + AssertThat(ts_node_type(leaf, document), Equals("string")); AssertThat(ts_node_start_byte(leaf), Equals(string_index)); AssertThat(ts_node_end_byte(leaf), Equals(string_end_index)); AssertThat(ts_node_start_point(leaf), Equals({ 6, 4 })); @@ -371,8 +372,8 @@ describe("Node", []() { describe("when there is no leaf node that spans the given range", [&]() { it("returns the smallest node that does span the range", [&]() { - TSNode pair_node = ts_node_named_descendant_for_range(array_node, string_index, string_index + 3); - AssertThat(ts_node_name(pair_node, document), Equals("pair")); + TSNode pair_node = ts_node_named_descendant_for_char_range(array_node, string_index, string_index + 3); + AssertThat(ts_node_type(pair_node, document), Equals("pair")); AssertThat(ts_node_start_byte(pair_node), Equals(string_index)); AssertThat(ts_node_end_byte(pair_node), Equals(null_end_index)); AssertThat(ts_node_start_point(pair_node), Equals({ 6, 4 })); @@ -380,8 +381,8 @@ describe("Node", []() { }); it("does not return invisible nodes (repeats)", [&]() { - TSNode node = ts_node_named_descendant_for_range(array_node, number_end_index, number_end_index + 1); - AssertThat(ts_node_name(node, document), Equals("array")); + TSNode node = ts_node_named_descendant_for_char_range(array_node, number_end_index, number_end_index + 1); + AssertThat(ts_node_type(node, document), Equals("array")); AssertThat(ts_node_start_byte(node), Equals(array_index)); AssertThat(ts_node_end_byte(node), Equals(array_end_index)); AssertThat(ts_node_start_point(node), Equals({ 2, 0 })); @@ -390,17 +391,51 @@ describe("Node", []() { }); }); - describe("descendant_for_range(start, end)", [&]() { - it("returns the smallest concrete node that spans the given range", [&]() { - TSNode node1 = ts_node_descendant_for_range(array_node, colon_index, colon_index); - AssertThat(ts_node_name(node1, document), Equals(":")); + describe("descendant_for_char_range(start, end)", [&]() { + it("returns the smallest node that spans the given range", [&]() { + TSNode node1 = ts_node_descendant_for_char_range(array_node, colon_index, colon_index); + AssertThat(ts_node_type(node1, document), Equals(":")); AssertThat(ts_node_start_byte(node1), Equals(colon_index)); AssertThat(ts_node_end_byte(node1), Equals(colon_index + 1)); AssertThat(ts_node_start_point(node1), Equals({ 6, 7 })); AssertThat(ts_node_end_point(node1), Equals({ 6, 8 })); - TSNode node2 = ts_node_descendant_for_range(array_node, string_index + 2, string_index + 4); - AssertThat(ts_node_name(node2, document), Equals("pair")); + TSNode node2 = ts_node_descendant_for_char_range(array_node, string_index + 2, string_index + 4); + AssertThat(ts_node_type(node2, document), Equals("pair")); + AssertThat(ts_node_start_byte(node2), Equals(string_index)); + AssertThat(ts_node_end_byte(node2), Equals(null_end_index)); + AssertThat(ts_node_start_point(node2), Equals({ 6, 4 })); + AssertThat(ts_node_end_point(node2), Equals({ 6, 13 })); + }); + }); + + describe("descendant_for_byte_range(start, end)", [&]() { + it("returns the smallest concrete node that spans the given range", [&]() { + ts_document_set_input_string(document, "[\"αβγδ\", \"αβγδ\"]"); + ts_document_parse(document); + TSNode array_node = ts_document_root_node(document); + + TSNode node1 = ts_node_descendant_for_char_range(array_node, 7, 7); + AssertThat(ts_node_type(node1, document), Equals(",")); + + TSNode node2 = ts_node_descendant_for_byte_range(array_node, 6, 10); + AssertThat(ts_node_type(node2, document), Equals("string")); + AssertThat(ts_node_start_byte(node2), Equals(1)); + AssertThat(ts_node_end_byte(node2), Equals(11)); + }); + }); + + describe("descendant_for_point_range(start, end)", [&]() { + it("returns the smallest concrete node that spans the given range", [&]() { + TSNode node1 = ts_node_descendant_for_point_range(array_node, {6, 7}, {6, 7}); + AssertThat(ts_node_type(node1, document), Equals(":")); + AssertThat(ts_node_start_byte(node1), Equals(colon_index)); + AssertThat(ts_node_end_byte(node1), Equals(colon_index + 1)); + AssertThat(ts_node_start_point(node1), Equals({ 6, 7 })); + AssertThat(ts_node_end_point(node1), Equals({ 6, 8 })); + + TSNode node2 = ts_node_descendant_for_point_range(array_node, {6, 6}, {6, 8}); + AssertThat(ts_node_type(node2, document), Equals("pair")); AssertThat(ts_node_start_byte(node2), Equals(string_index)); AssertThat(ts_node_end_byte(node2), Equals(null_end_index)); AssertThat(ts_node_start_point(node2), Equals({ 6, 4 })); diff --git a/spec/runtime/parser_spec.cc b/spec/runtime/parser_spec.cc index 837f3f4e..0f0b5fa1 100644 --- a/spec/runtime/parser_spec.cc +++ b/spec/runtime/parser_spec.cc @@ -3,7 +3,6 @@ #include "helpers/record_alloc.h" #include "helpers/spy_input.h" #include "helpers/load_language.h" -#include "helpers/log_debugger.h" #include "helpers/record_alloc.h" START_TEST @@ -20,7 +19,7 @@ describe("Parser", [&]() { chunk_size = 3; input = nullptr; - doc = ts_document_make(); + doc = ts_document_new(); }); after_each([&]() { @@ -102,7 +101,7 @@ describe("Parser", [&]() { "(array (number) (ERROR (UNEXPECTED '@')) (true))"); TSNode error = ts_node_named_child(root, 1); - AssertThat(ts_node_name(error, doc), Equals("ERROR")); + AssertThat(ts_node_type(error, doc), Equals("ERROR")); AssertThat(get_node_text(error), Equals(", @@@@@")); AssertThat(ts_node_child_count(error), Equals(2)); @@ -113,7 +112,7 @@ describe("Parser", [&]() { AssertThat(get_node_text(garbage), Equals("@@@@@")); TSNode node_after_error = ts_node_named_child(root, 2); - AssertThat(ts_node_name(node_after_error, doc), Equals("true")); + AssertThat(ts_node_type(node_after_error, doc), Equals("true")); AssertThat(get_node_text(node_after_error), Equals("true")); }); }); @@ -127,20 +126,20 @@ describe("Parser", [&]() { TSNode error = ts_node_named_child(root, 1); AssertThat(ts_node_symbol(error), Equals(ts_builtin_sym_error)); - AssertThat(ts_node_name(error, doc), Equals("ERROR")); + AssertThat(ts_node_type(error, doc), Equals("ERROR")); AssertThat(get_node_text(error), Equals(", faaaaalse")); AssertThat(ts_node_child_count(error), Equals(2)); TSNode comma = ts_node_child(error, 0); - AssertThat(ts_node_name(comma, doc), Equals(",")); + AssertThat(ts_node_type(comma, doc), Equals(",")); AssertThat(get_node_text(comma), Equals(",")); TSNode garbage = ts_node_child(error, 1); - AssertThat(ts_node_name(garbage, doc), Equals("ERROR")); + AssertThat(ts_node_type(garbage, doc), Equals("ERROR")); AssertThat(get_node_text(garbage), Equals("faaaaalse")); TSNode last = ts_node_named_child(root, 2); - AssertThat(ts_node_name(last, doc), Equals("true")); + AssertThat(ts_node_type(last, doc), Equals("true")); AssertThat(ts_node_start_byte(last), Equals(strlen(" [123, faaaaalse, "))); }); }); @@ -153,12 +152,12 @@ describe("Parser", [&]() { "(array (number) (true) (ERROR (false)) (true))"); TSNode error = ts_node_named_child(root, 2); - AssertThat(ts_node_name(error, doc), Equals("ERROR")); + AssertThat(ts_node_type(error, doc), Equals("ERROR")); AssertThat(get_node_text(error), Equals("false")); AssertThat(ts_node_child_count(error), Equals(1)); TSNode last = ts_node_named_child(root, 1); - AssertThat(ts_node_name(last, doc), Equals("true")); + AssertThat(ts_node_type(last, doc), Equals("true")); AssertThat(get_node_text(last), Equals("true")); }); }); @@ -309,8 +308,8 @@ describe("Parser", [&]() { assert_root_node( "(program (expression_statement (math_op (identifier) (number))))"); - TSNode node = ts_node_named_descendant_for_range(root, 1, 1); - AssertThat(ts_node_name(node, doc), Equals("identifier")); + TSNode node = ts_node_named_descendant_for_char_range(root, 1, 1); + AssertThat(ts_node_type(node, doc), Equals("identifier")); AssertThat(ts_node_end_byte(node), Equals(strlen("abXYZc"))); }); }); @@ -327,8 +326,8 @@ describe("Parser", [&]() { assert_root_node( "(program (expression_statement (math_op (identifier) (number))))"); - TSNode node = ts_node_named_descendant_for_range(root, 1, 1); - AssertThat(ts_node_name(node, doc), Equals("identifier")); + TSNode node = ts_node_named_descendant_for_char_range(root, 1, 1); + AssertThat(ts_node_type(node, doc), Equals("identifier")); AssertThat(ts_node_end_byte(node), Equals(strlen("abcXYZ"))); }); }); @@ -461,7 +460,7 @@ describe("Parser", [&]() { it("handles failures when allocating documents", [&]() { record_alloc::start(); - TSDocument *document = ts_document_make(); + TSDocument *document = ts_document_new(); ts_document_free(document); AssertThat(record_alloc::outstanding_allocation_indices(), IsEmpty()); @@ -471,7 +470,7 @@ describe("Parser", [&]() { for (size_t i = 0; i < allocation_count; i++) { record_alloc::start(); record_alloc::fail_at_allocation_index(i); - AssertThat(ts_document_make(), Equals(nullptr)); + AssertThat(ts_document_new(), Equals(nullptr)); AssertThat(record_alloc::outstanding_allocation_indices(), IsEmpty()); } @@ -507,7 +506,7 @@ describe("Parser", [&]() { for (size_t i = 0; i < allocation_count; i++) { record_alloc::stop(); - doc = ts_document_make(); + doc = ts_document_new(); record_alloc::start(); record_alloc::fail_at_allocation_index(i); @@ -522,7 +521,7 @@ describe("Parser", [&]() { } record_alloc::stop(); - doc = ts_document_make(); + doc = ts_document_new(); record_alloc::start(); record_alloc::fail_at_allocation_index(allocation_count + 1); diff --git a/src/runtime/debugger.h b/src/runtime/debugger.h deleted file mode 100644 index 06e5a744..00000000 --- a/src/runtime/debugger.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RUNTIME_DEBUGGER_H_ -#define RUNTIME_DEBUGGER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tree_sitter/runtime.h" - -static inline TSDebugger ts_debugger_null() { - TSDebugger debugger = { 0, 0 }; - return debugger; -} - -#ifdef __cplusplus -} -#endif - -#endif // RUNTIME_DEBUGGER_H_ diff --git a/src/runtime/document.c b/src/runtime/document.c index 384246a1..1211eb5e 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -6,7 +6,7 @@ #include "runtime/string_input.h" #include "runtime/document.h" -TSDocument *ts_document_make() { +TSDocument *ts_document_new() { TSDocument *self = ts_calloc(1, sizeof(TSDocument)); if (!self) goto error; @@ -44,12 +44,12 @@ void ts_document_set_language(TSDocument *self, const TSLanguage *language) { } } -TSDebugger ts_document_debugger(const TSDocument *self) { - return self->parser.lexer.debugger; +TSLogger ts_document_logger(const TSDocument *self) { + return self->parser.lexer.logger; } -void ts_document_set_debugger(TSDocument *self, TSDebugger debugger) { - self->parser.lexer.debugger = debugger; +void ts_document_set_logger(TSDocument *self, TSLogger logger) { + self->parser.lexer.logger = logger; } void ts_document_print_debugging_graphs(TSDocument *self, bool should_print) { @@ -90,7 +90,7 @@ void ts_document_edit(TSDocument *self, TSInputEdit edit) { } int ts_document_parse(TSDocument *self) { - if (!self->input.read_fn || !self->parser.language) + if (!self->input.read || !self->parser.language) return -1; TSTree *reusable_tree = self->valid ? self->tree : NULL; diff --git a/src/runtime/lexer.c b/src/runtime/lexer.c index 243fa78a..d87ebd9c 100644 --- a/src/runtime/lexer.c +++ b/src/runtime/lexer.c @@ -3,14 +3,13 @@ #include "tree_sitter/parser.h" #include "runtime/tree.h" #include "runtime/length.h" -#include "runtime/debugger.h" #include "runtime/utf16.h" #include "utf8proc.h" #define LOG(...) \ - if (self->debugger.debug_fn) { \ + if (self->logger.log) { \ snprintf(self->debug_buffer, TS_DEBUG_BUFFER_SIZE, __VA_ARGS__); \ - self->debugger.debug_fn(self->debugger.payload, TSDebugTypeLex, \ + self->logger.log(self->logger.payload, TSLogTypeLex, \ self->debug_buffer); \ } @@ -25,11 +24,11 @@ static void ts_lexer__get_chunk(TSLexer *self) { TSInput input = self->input; if (!self->chunk || self->current_position.bytes != self->chunk_start + self->chunk_size) - input.seek_fn(input.payload, self->current_position.chars, + input.seek(input.payload, self->current_position.chars, self->current_position.bytes); self->chunk_start = self->current_position.bytes; - self->chunk = input.read_fn(input.payload, &self->chunk_size); + self->chunk = input.read(input.payload, &self->chunk_size); if (!self->chunk_size) self->chunk = empty_chunk; } @@ -86,7 +85,7 @@ void ts_lexer_init(TSLexer *self) { .advance = ts_lexer__advance, .chunk = NULL, .chunk_start = 0, - .debugger = ts_debugger_null(), + .logger = {}, }; ts_lexer_reset(self, ts_length_zero()); } diff --git a/src/runtime/node.c b/src/runtime/node.c index ad3264d8..787fc649 100644 --- a/src/runtime/node.c +++ b/src/runtime/node.c @@ -138,9 +138,13 @@ static inline TSNode ts_node__next_sibling(TSNode self, bool include_anonymous) return ts_node__null(); } -static inline TSNode ts_node__descendant_for_range(TSNode self, size_t min, - size_t max, - bool include_anonymous) { +static inline bool ts_point_gt(TSPoint a, TSPoint b) { + return a.row > b.row || (a.row == b.row && a.column > b.column); +} + +static inline TSNode ts_node__descendant_for_char_range(TSNode self, size_t min, + size_t max, + bool include_anonymous) { TSNode node = self; TSNode last_visible_node = self; @@ -165,6 +169,61 @@ static inline TSNode ts_node__descendant_for_range(TSNode self, size_t min, return last_visible_node; } +static inline TSNode ts_node__descendant_for_byte_range(TSNode self, size_t min, + size_t max, + bool include_anonymous) { + TSNode node = self; + TSNode last_visible_node = self; + + bool did_descend = true; + while (did_descend) { + did_descend = false; + + for (size_t i = 0; i < ts_node__tree(node)->child_count; i++) { + TSNode child = ts_node__direct_child(node, i); + if (ts_node_start_byte(child) > min) + break; + if (ts_node_end_byte(child) > max) { + node = child; + if (ts_node__is_relevant(node, include_anonymous)) + last_visible_node = node; + did_descend = true; + break; + } + } + } + + return last_visible_node; +} + +static inline TSNode ts_node__descendant_for_point_range(TSNode self, + TSPoint min, + TSPoint max, + bool include_anonymous) { + TSNode node = self; + TSNode last_visible_node = self; + + bool did_descend = true; + while (did_descend) { + did_descend = false; + + for (size_t i = 0; i < ts_node__tree(node)->child_count; i++) { + TSNode child = ts_node__direct_child(node, i); + if (ts_point_gt(ts_node_start_point(child), min)) + break; + if (ts_point_gt(ts_node_end_point(child), max)) { + node = child; + if (ts_node__is_relevant(node, include_anonymous)) + last_visible_node = node; + did_descend = true; + break; + } + } + } + + return last_visible_node; +} + /* * Public */ @@ -222,7 +281,7 @@ void ts_symbol_iterator_next(TSSymbolIterator *self) { self->done = true; } -const char *ts_node_name(TSNode self, const TSDocument *document) { +const char *ts_node_type(TSNode self, const TSDocument *document) { TSSymbol symbol = ts_node__tree(self)->symbol; return ts_language_symbol_name(document->parser.language, symbol); } @@ -290,10 +349,26 @@ TSNode ts_node_prev_named_sibling(TSNode self) { return ts_node__prev_sibling(self, false); } -TSNode ts_node_descendant_for_range(TSNode self, size_t min, size_t max) { - return ts_node__descendant_for_range(self, min, max, true); +TSNode ts_node_descendant_for_char_range(TSNode self, size_t min, size_t max) { + return ts_node__descendant_for_char_range(self, min, max, true); } -TSNode ts_node_named_descendant_for_range(TSNode self, size_t min, size_t max) { - return ts_node__descendant_for_range(self, min, max, false); +TSNode ts_node_named_descendant_for_char_range(TSNode self, size_t min, size_t max) { + return ts_node__descendant_for_char_range(self, min, max, false); +} + +TSNode ts_node_descendant_for_byte_range(TSNode self, size_t min, size_t max) { + return ts_node__descendant_for_byte_range(self, min, max, true); +} + +TSNode ts_node_named_descendant_for_byte_range(TSNode self, size_t min, size_t max) { + return ts_node__descendant_for_byte_range(self, min, max, false); +} + +TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint min, TSPoint max) { + return ts_node__descendant_for_point_range(self, min, max, true); +} + +TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint min, TSPoint max) { + return ts_node__descendant_for_point_range(self, min, max, false); } diff --git a/src/runtime/parser.c b/src/runtime/parser.c index ae34d6ab..4216c645 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -15,10 +15,10 @@ #include "runtime/error_costs.h" #define LOG(...) \ - if (self->lexer.debugger.debug_fn) { \ + if (self->lexer.logger.log) { \ snprintf(self->lexer.debug_buffer, TS_DEBUG_BUFFER_SIZE, __VA_ARGS__); \ - self->lexer.debugger.debug_fn(self->lexer.debugger.payload, \ - TSDebugTypeParse, self->lexer.debug_buffer); \ + self->lexer.logger.log(self->lexer.logger.payload, \ + TSLogTypeParse, self->lexer.debug_buffer); \ } \ if (self->print_debugging_graphs) { \ fprintf(stderr, "graph {\nlabel=\""); \ diff --git a/src/runtime/string_input.c b/src/runtime/string_input.c index b1b87edc..338047c9 100644 --- a/src/runtime/string_input.c +++ b/src/runtime/string_input.c @@ -36,8 +36,8 @@ TSInput ts_string_input_make(const char *string) { input->length = strlen(string); return (TSInput){ .payload = input, - .read_fn = ts_string_input_read, - .seek_fn = ts_string_input_seek, + .read = ts_string_input_read, + .seek = ts_string_input_seek, .encoding = TSInputEncodingUTF8, };