Merge pull request #37 from tree-sitter/api-cleanup

API cleanup
This commit is contained in:
Max Brunsfeld 2016-09-06 22:46:24 -07:00 committed by GitHub
commit b94a7bfd71
20 changed files with 280 additions and 189 deletions

View file

@ -43,7 +43,7 @@ typedef struct TSLexer {
TSSymbol result_symbol;
TSInput input;
TSDebugger debugger;
TSLogger logger;
char debug_buffer[TS_DEBUG_BUFFER_SIZE];
} TSLexer;

View file

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

View file

@ -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_

View file

@ -1,22 +0,0 @@
#include "helpers/spy_debugger.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
static void spy_debug(void *data, TSDebugType type, const char *msg) {
SpyDebugger *debugger = static_cast<SpyDebugger *>(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();
}

View file

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

View file

@ -0,0 +1,22 @@
#include "helpers/spy_logger.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
static void spy_log(void *data, TSLogType type, const char *msg) {
SpyLogger *logger = static_cast<SpyLogger *>(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();
}

View file

@ -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 <string>
#include <vector>
#include "tree_sitter/runtime.h"
class SpyDebugger {
class SpyLogger {
public:
void clear();
TSDebugger debugger();
TSLogger logger();
std::vector<std::string> messages;
};

View file

@ -1,22 +1,22 @@
#include "tree_sitter/runtime.h"
#include <stdio.h>
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;
}

View file

@ -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_

View file

@ -8,7 +8,7 @@ describe("compile_grammar", []() {
TSDocument *document;
before_each([&]() {
document = ts_document_make();
document = ts_document_new();
});
after_each([&]() {

View file

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

View file

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

View file

@ -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<size_t>(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<TSPoint>({ 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<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(leaf), Equals<TSPoint>({ 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<TSPoint>({ 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<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(leaf), Equals<TSPoint>({ 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<TSPoint>({ 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<TSPoint>({ 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<TSPoint>({ 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<TSPoint>({ 6, 7 }));
AssertThat(ts_node_end_point(node1), Equals<TSPoint>({ 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<TSPoint>({ 6, 4 }));
AssertThat(ts_node_end_point(node2), Equals<TSPoint>({ 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<size_t>(1));
AssertThat(ts_node_end_byte(node2), Equals<size_t>(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<TSPoint>({ 6, 7 }));
AssertThat(ts_node_end_point(node1), Equals<TSPoint>({ 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<TSPoint>({ 6, 4 }));

View file

@ -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<size_t>(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<size_t>(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<size_t>(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<TSDocument *>(nullptr));
AssertThat(ts_document_new(), Equals<TSDocument *>(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);

View file

@ -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_

View file

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

View file

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

View file

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

View file

@ -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=\""); \

View file

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