mirror of
https://github.com/tree-sitter/tree-sitter.git
synced 2026-09-10 07:36:22 -04:00
fix(lib): accumulate error costs through hidden error nodes
This commit is contained in:
parent
c279989118
commit
869638f6cf
|
|
@ -335,6 +335,15 @@ void ts_subtree_compress(
|
|||
}
|
||||
}
|
||||
|
||||
// The part of an error node's cost that penalizes the extent it spans, as
|
||||
// opposed to the cost of its contents.
|
||||
static inline uint32_t ts_subtree__error_extent_cost(Length size) {
|
||||
return
|
||||
ERROR_COST_PER_RECOVERY +
|
||||
ERROR_COST_PER_SKIPPED_CHAR * size.bytes +
|
||||
ERROR_COST_PER_SKIPPED_LINE * size.extent.row;
|
||||
}
|
||||
|
||||
// Assign all of the node's properties that depend on its children.
|
||||
void ts_subtree_summarize_children(
|
||||
MutableSubtree self,
|
||||
|
|
@ -386,20 +395,25 @@ void ts_subtree_summarize_children(
|
|||
lookahead_end_byte = child_lookahead_end_byte;
|
||||
}
|
||||
|
||||
if (ts_subtree_symbol(child) != ts_builtin_sym_error_repeat) {
|
||||
self.ptr->error_cost += ts_subtree_error_cost(child);
|
||||
}
|
||||
|
||||
uint32_t grandchild_count = ts_subtree_child_count(child);
|
||||
if (
|
||||
self.ptr->symbol == ts_builtin_sym_error ||
|
||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
||||
) {
|
||||
if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
|
||||
if (ts_subtree_visible(child)) {
|
||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||
} else if (grandchild_count > 0) {
|
||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
|
||||
if (ts_subtree_symbol(child) == ts_builtin_sym_error_repeat) {
|
||||
// Refund an `_ERROR` child's extent penalty, which this node re-charges
|
||||
// as part of its own extent below, so that the grouping is cost-neutral.
|
||||
uint32_t extent_cost = ts_subtree__error_extent_cost(ts_subtree_size(child));
|
||||
ts_assert(ts_subtree_error_cost(child) >= extent_cost);
|
||||
self.ptr->error_cost += ts_subtree_error_cost(child) - extent_cost;
|
||||
} else {
|
||||
self.ptr->error_cost += ts_subtree_error_cost(child);
|
||||
if (
|
||||
self.ptr->symbol == ts_builtin_sym_error ||
|
||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
||||
) {
|
||||
if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
|
||||
if (ts_subtree_visible(child)) {
|
||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||
} else if (grandchild_count > 0) {
|
||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -443,10 +457,7 @@ void ts_subtree_summarize_children(
|
|||
self.ptr->symbol == ts_builtin_sym_error ||
|
||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
||||
) {
|
||||
self.ptr->error_cost +=
|
||||
ERROR_COST_PER_RECOVERY +
|
||||
ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes +
|
||||
ERROR_COST_PER_SKIPPED_LINE * self.ptr->size.extent.row;
|
||||
self.ptr->error_cost += ts_subtree__error_extent_cost(self.ptr->size);
|
||||
}
|
||||
|
||||
if (self.ptr->child_count > 0) {
|
||||
|
|
|
|||
20
test/fixtures/error_corpus/javascript_errors.txt
vendored
20
test/fixtures/error_corpus/javascript_errors.txt
vendored
|
|
@ -187,3 +187,23 @@ function main(x) {
|
|||
(member_expression (identifier) (property_identifier))
|
||||
(arguments (string (string_fragment))))))
|
||||
(return_statement (object)))))
|
||||
|
||||
===================================================
|
||||
Stray tokens around a parenthesized ternary
|
||||
===================================================
|
||||
|
||||
x
|
||||
// one
|
||||
( a ? b : c ) :
|
||||
// two
|
||||
y.
|
||||
|
||||
---
|
||||
|
||||
(program
|
||||
(ERROR
|
||||
(call_expression
|
||||
(identifier)
|
||||
(comment)
|
||||
(arguments (ternary_expression (identifier) (identifier) (identifier))))
|
||||
(ERROR (comment) (identifier))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue