lang/include/tree_sitter_wrapper.hpp

214 lines
5.9 KiB
C++
Raw Normal View History

2023-07-16 20:55:07 +03:00
#pragma once
#include <string>
#include "utils.hpp"
2023-07-16 20:55:07 +03:00
#include "tree_sitter/api.h"
extern "C" const TSLanguage *tree_sitter_lang();
2023-07-16 20:55:07 +03:00
namespace parser {
class ParseTree {
public:
class Node {
public:
Node(const TSNode &node, const std::string *source)
: node_(node), source_(source) {}
2023-07-16 20:55:07 +03:00
std::string get_type() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (get_type)");
}
return ts_node_type(node_);
}
2023-07-16 20:55:07 +03:00
std::pair<size_t, size_t> get_start_point() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (get_start_point)");
}
TSPoint point = ts_node_start_point(node_);
return {point.row, point.column};
2023-07-16 20:55:07 +03:00
}
std::pair<size_t, size_t> get_end_point() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (get_end_point)");
}
TSPoint point = ts_node_end_point(node_);
return {point.row, point.column};
2023-07-16 20:55:07 +03:00
}
std::string get_as_sexpression() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (get_as_sexpression)");
}
return ts_node_string(node_);
}
2023-07-16 20:55:07 +03:00
std::string get_value() const { // from source
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (get_value)");
}
2023-07-16 20:55:07 +03:00
size_t start = ts_node_start_byte(node_);
size_t end = ts_node_end_byte(node_);
return source_->substr(start, end - start);
}
2023-07-25 21:33:57 +03:00
size_t get_value_length() const { // from source
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (get_value_length)");
}
size_t start = ts_node_start_byte(node_);
size_t end = ts_node_end_byte(node_);
return end - start;
}
bool is_null() const { return ts_node_is_null(node_); }
2023-07-16 20:55:07 +03:00
bool is_named() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (is_named)");
}
return ts_node_is_named(node_);
}
2023-07-16 20:55:07 +03:00
bool is_missing() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (is_missing)");
}
return ts_node_is_missing(node_);
}
2023-07-16 20:55:07 +03:00
bool is_extra() const { // comments, etc.
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (is_extra)");
}
2023-07-16 20:55:07 +03:00
return ts_node_is_extra(node_);
}
bool has_error() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (has_error)");
}
return ts_node_has_error(node_);
}
2023-07-16 20:55:07 +03:00
Node nth_child(size_t n) const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (nth_child)");
}
return Node(ts_node_child(node_, n), source_);
}
2023-07-16 20:55:07 +03:00
size_t child_count() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (child_count)");
}
return ts_node_child_count(node_);
}
2023-07-16 20:55:07 +03:00
Node nth_named_child(size_t n) const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (nth_named_child)");
}
2023-07-16 20:55:07 +03:00
return Node(ts_node_named_child(node_, n), source_);
}
size_t named_child_count() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (named_child_count)");
}
return ts_node_named_child_count(node_);
}
2023-07-16 20:55:07 +03:00
Node child_by_field_name(const std::string &name) const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (child_by_field_name)");
}
return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()),
source_);
2023-07-16 20:55:07 +03:00
}
Node previous_sibling() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (previous_sibling)");
}
2023-07-16 20:55:07 +03:00
return Node(ts_node_prev_sibling(node_), source_);
}
Node previous_named_sibling() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (previous_named_sibling)");
}
2023-07-16 20:55:07 +03:00
return Node(ts_node_prev_named_sibling(node_), source_);
}
Node next_sibling() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (next_sibling)");
}
return Node(ts_node_next_sibling(node_), source_);
}
2023-07-16 20:55:07 +03:00
Node next_named_sibling() const {
if (is_null()) {
error_handling::handle_general_error(
"Null parsing node method called (next_named_sibling)");
}
2023-07-16 20:55:07 +03:00
return Node(ts_node_next_named_sibling(node_), source_);
}
2023-07-16 20:55:07 +03:00
private:
TSNode node_;
const std::string *source_;
2023-07-16 20:55:07 +03:00
};
ParseTree(const std::string &source) : source_(source) {
TSParser *parser = ts_parser_new();
2023-07-16 20:55:07 +03:00
ts_parser_set_language(parser, tree_sitter_lang());
tree_ = ts_parser_parse_string(parser, nullptr, source_.c_str(),
source_.size());
2023-07-16 20:55:07 +03:00
ts_parser_delete(parser);
}
ParseTree(const ParseTree &parse_tree)
: tree_(ts_tree_copy(parse_tree.tree_)), source_(parse_tree.source_) {}
2023-07-16 20:55:07 +03:00
2023-07-20 14:38:44 +03:00
Node get_root() const { return Node(ts_tree_root_node(tree_), &source_); }
2023-07-16 20:55:07 +03:00
~ParseTree() { ts_tree_delete(tree_); }
2023-07-16 20:55:07 +03:00
2023-07-20 14:38:44 +03:00
bool is_properly_parsed() { // TODO: find place
return !get_root().has_error();
2023-07-16 20:55:07 +03:00
}
2023-07-16 20:55:07 +03:00
private:
TSTree *tree_;
2023-07-16 20:55:07 +03:00
std::string source_; // for token value extraction
};
} // namespace parser