mirror of
https://github.com/open-goal/jak-project
synced 2026-07-07 14:13:45 -04:00
formatter: handle top level blank lines and better handle comments (#2702)
This commit is contained in:
@@ -5,11 +5,52 @@
|
||||
#include "config/rule_config.h"
|
||||
|
||||
namespace formatter {
|
||||
const std::shared_ptr<FormattingRule> default_rule = std::make_shared<FormattingRule>();
|
||||
const std::shared_ptr<IndentationRule> default_rule = std::make_shared<IndentationRule>();
|
||||
}
|
||||
|
||||
std::shared_ptr<FormattingRule> FormatterTreeNode::get_formatting_rule(const int depth,
|
||||
const int index) const {
|
||||
std::string get_source_code(const std::string& source, const TSNode& node) {
|
||||
uint32_t start = ts_node_start_byte(node);
|
||||
uint32_t end = ts_node_end_byte(node);
|
||||
// TODO - comments end with a \n, this is likely a tree-sitter grammar problem
|
||||
return str_util::rtrim(source.substr(start, end - start));
|
||||
}
|
||||
|
||||
int num_blank_lines_following_node(const std::string& source, const TSNode& node) {
|
||||
int num_lines = 0;
|
||||
uint32_t cursor = ts_node_end_byte(node);
|
||||
while (cursor < source.length() && source.at(cursor) == '\n') {
|
||||
num_lines++;
|
||||
cursor++;
|
||||
}
|
||||
return num_lines;
|
||||
}
|
||||
|
||||
// Check if the original source only has whitespace up to a new-line after it's token
|
||||
bool node_preceeded_by_only_whitespace(const std::string& source, const TSNode& node) {
|
||||
uint32_t pos = ts_node_start_byte(node);
|
||||
while (pos > 0) {
|
||||
const auto& c = source.at(pos);
|
||||
if (c == '\n') {
|
||||
return true;
|
||||
} else if (c == ' ' || c == '\t') {
|
||||
pos--;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FormatterTreeNode::FormatterTreeNode(const std::string& source, const TSNode& node)
|
||||
: token(get_source_code(source, node)) {
|
||||
// Set any metadata based on the value of the token
|
||||
metadata.is_comment = str_util::starts_with(str_util::ltrim(token.value()), ";");
|
||||
metadata.num_blank_lines_following = num_blank_lines_following_node(source, node);
|
||||
metadata.is_inline = !node_preceeded_by_only_whitespace(source, node);
|
||||
};
|
||||
|
||||
std::shared_ptr<IndentationRule> FormatterTreeNode::get_formatting_rule(const int depth,
|
||||
const int index) const {
|
||||
// TODO - really lazy for now
|
||||
if (!rules.empty()) {
|
||||
return rules.at(0);
|
||||
@@ -41,16 +82,9 @@ bool nodes_on_same_line(const std::string& source, const TSNode& n1, const TSNod
|
||||
return !str_util::contains(code_between, "\n");
|
||||
}
|
||||
|
||||
std::string get_source_code(const std::string& source, const TSNode& node) {
|
||||
uint32_t start = ts_node_start_byte(node);
|
||||
uint32_t end = ts_node_end_byte(node);
|
||||
// TODO - comments end with a \n, this is likely a tree-sitter grammar problem
|
||||
return str_util::rtrim(source.substr(start, end - start));
|
||||
}
|
||||
|
||||
FormatterTree::FormatterTree(const std::string& source, const TSNode& root_node) {
|
||||
root = FormatterTreeNode();
|
||||
root.metadata.is_root = true;
|
||||
root.metadata.is_top_level = true;
|
||||
construct_formatter_tree_recursive(source, root_node, root);
|
||||
}
|
||||
|
||||
@@ -59,7 +93,7 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
|
||||
TSNode curr_node,
|
||||
FormatterTreeNode& tree_node) {
|
||||
if (ts_node_child_count(curr_node) == 0) {
|
||||
tree_node.refs.push_back(FormatterTreeNode(get_source_code(source, curr_node)));
|
||||
tree_node.refs.push_back(FormatterTreeNode(source, curr_node));
|
||||
return;
|
||||
}
|
||||
const std::string curr_node_type = ts_node_type(curr_node);
|
||||
@@ -80,8 +114,9 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
|
||||
list_node.metadata.multiple_elements_first_line =
|
||||
!node_followed_by_only_whitespace(source, child_node);
|
||||
// Peek at the first element of the list to determine formatting rules
|
||||
if (formatter::opengoal_rules.find(contents) != formatter::opengoal_rules.end()) {
|
||||
list_node.rules = formatter::opengoal_rules.at(contents);
|
||||
if (formatter::opengoal_indentation_rules.find(contents) !=
|
||||
formatter::opengoal_indentation_rules.end()) {
|
||||
list_node.rules = formatter::opengoal_indentation_rules.at(contents);
|
||||
}
|
||||
}
|
||||
construct_formatter_tree_recursive(source, child_node, list_node);
|
||||
|
||||
Reference in New Issue
Block a user