Subject: bug#79363: 31.0.50; Font locking issue in go-ts-mode when tree-sitter grammar is automatically installed

From: Juri Linkov <[email-masked]>
Date: Tue, 02 Sep 2025 09:31:52 +0300

> 1. `go-ts-mode--font-lock-settings' depends on the following functions:
>
>      (defun go-ts-mode--iota-query-supported-p ()
>        "Return t if the iota query is supported by the tree-sitter-go grammar."
>        (ignore-errors
>          (or (treesit-query-string "" '((iota) @font-lock-constant-face) 'go) t)))
>      
>      (defun go-ts-mode--method-elem-supported-p ()
>        "Return t if Go grammar uses `method_elem' instead of `method_spec'."
>        (ignore-errors
>          (or (treesit-query-string "" '((method_elem) @cap) 'go) t)))
>
> 2. In this sceneario we don't have the Go grammar installed yet.  So,
>    `treesit-query-string' returns a `not-found' error.
> 3. Because of the previous error, `go-ts-mode--method-elem-supported-p'
>    returns `nil'.  Thus, the "definition" rule uses "method_spec" which
>    is not supported by the default grammar (commit
>    "12fe553fdaaa7449f764bc876fd777704d4fb752").
>
>      (defvar go-ts-mode--font-lock-settings
>        (treesit-font-lock-rules
>         ...
>         :language 'go
>         :feature 'definition
>         `(...
>           (,(if (go-ts-mode--method-elem-supported-p)
>                 'method_elem
>               'method_spec)
>            name: (field_identifier) @font-lock-function-name-face)
>
> Please, take this analysis with a pinch of salt.  I'm not familiar with
> the code base.  But I hope it makes sense.

Thanks for the analysis, it's absolutely correct.  Manually re-evaluating
`go-ts-mode--font-lock-settings' after installing the grammar fixes this.

Thus we have to find a way to re-evaluate it automatically.
The same problem exists in some other ts-modes,
so the solution should be quite general.

One idea is to turn defvar into defun that memoizes its return value.