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
(cherry picked from commit 869638f6cf)
This commit is contained in:
parent
15adfa9e51
commit
f837fc9813
|
|
@ -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.
|
// Assign all of the node's properties that depend on its children.
|
||||||
void ts_subtree_summarize_children(
|
void ts_subtree_summarize_children(
|
||||||
MutableSubtree self,
|
MutableSubtree self,
|
||||||
|
|
@ -386,20 +395,25 @@ void ts_subtree_summarize_children(
|
||||||
lookahead_end_byte = child_lookahead_end_byte;
|
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);
|
uint32_t grandchild_count = ts_subtree_child_count(child);
|
||||||
if (
|
if (ts_subtree_symbol(child) == ts_builtin_sym_error_repeat) {
|
||||||
self.ptr->symbol == ts_builtin_sym_error ||
|
// Refund an `_ERROR` child's extent penalty, which this node re-charges
|
||||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
// 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));
|
||||||
if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {
|
ts_assert(ts_subtree_error_cost(child) >= extent_cost);
|
||||||
if (ts_subtree_visible(child)) {
|
self.ptr->error_cost += ts_subtree_error_cost(child) - extent_cost;
|
||||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
} else {
|
||||||
} else if (grandchild_count > 0) {
|
self.ptr->error_cost += ts_subtree_error_cost(child);
|
||||||
self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;
|
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 ||
|
||||||
self.ptr->symbol == ts_builtin_sym_error_repeat
|
self.ptr->symbol == ts_builtin_sym_error_repeat
|
||||||
) {
|
) {
|
||||||
self.ptr->error_cost +=
|
self.ptr->error_cost += ts_subtree__error_extent_cost(self.ptr->size);
|
||||||
ERROR_COST_PER_RECOVERY +
|
|
||||||
ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes +
|
|
||||||
ERROR_COST_PER_SKIPPED_LINE * self.ptr->size.extent.row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.ptr->child_count > 0) {
|
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))
|
(member_expression (identifier) (property_identifier))
|
||||||
(arguments (string (string_fragment))))))
|
(arguments (string (string_fragment))))))
|
||||||
(return_statement (object)))))
|
(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