Subject: bug#61235: 30.0.50; tree-sit: `treesit-node-check' lacks a way to tell if a node belongs to a deleted parser

From: Mickey Petersen <[email-masked]>
Date: Mon, 06 Feb 2023 12:35:20 +0000

Eli Zaretskii <[email-masked]> writes:

>> From: Yuan Fu <[email-masked]>
>> Date: Sun, 5 Feb 2023 20:24:27 -0800
>> Cc: [email-masked],
>>  Eli Zaretskii <[email-masked]>
>>
>> Mickey Petersen <[email-masked]> writes:
>>
>> > There's no way to tell if a node belongs to a now-deleted
>> > parser. Checking if it is `missing' or `outdated' returns nil; there
>> > is no way to ascertain this state except by catching an error if you
>> > try to get its node text, type, etc.
>>
>> That sounds reasonable. I can add treesit-parser-live-p, and add
>> a "live" PROPERTY to treesit-node-check.
>
> I'm not sure I understand the need.  AFAIU, a parser is deleted only
> if we call treesit-parser-delete; are we saying that a Lisp program
> doesn't know that it deleted a parser?  What exactly is the practical
> situation where this problem happens, and why?
>
> Frankly, I don't think we should at this stage add APIs without a very
> good reason.  We should instead collect experience, both from users
> and from Lisp programs, and analyze them before deciding whether more
> APIs are necessary.
>

Because node references are retained even after a parser is deleted.

Retrieving a node; somehow deleting the parser (maybe you closed the
buffer, or you were doing some off-hand parsing); and then doing
_anything_ with the aforementioned node yields an error for which
there is no way to test for.

This is particularly the case when you mix and match parsers in the
same buffer.

>> +DEFUN ("treesit-parser-live-p",
>> +       Ftreesit_parser_live_p, Streesit_parser_live_p, 1, 1, 0,
>> +       doc: /* Check whether PARSER is not deleted and its buffer is live.  */)
>> +  (Lisp_Object parser)
>> +{
>> +  treesit_check_parser (parser);
>> +  if (XTS_PARSER (parser)->deleted)
>> +    return Qnil;
>> +  else if (NILP (Fbuffer_live_p (XTS_PARSER (parser)->buffer)))
>> +    return Qnil;
>> +  else
>> +    return Qt;
>> +}
>
> Doesn't treesit_check_parser signal an error if the parser was
> deleted?  If so, how will the above be useful, if someone wants to
> avoid errors?