Subject: bug#60751: 30.0.50; Treesit indent rule with missing semi in java-ts-mode

From: Yuan Fu <[email-masked]>
Date: Fri, 13 Jan 2023 01:32:45 -0800

Theodor Thornhill <[email-masked]> writes:

> Hi Yuan!
>
> Consider this java code (point at |, and note the missing semi):
> ```
> class foo {
>     public void foo() {
>         var x = foo
>             .foo()|
>      }
> }
> ```
> If I press RET now, indent ends up here:
> ```
> class foo {
>     public void foo() {
>         var x = foo
>             .foo()
>         |
>      }
> }
> ```
>
> Matched rule is (which I'll change in a bit anyway):
>
> ```
> ((parent-is "block") (and parent parent-bol) java-ts-mode-indent-offset)
> ```
>
>
> and the parse tree is:
>
> ```
> (program
>  (class_declaration class name: (identifier)
>   body: 
>    (class_body {
>     (method_declaration
>      (modifiers public)
>      dimensions: (void_type) body: (identifier)
>      (formal_parameters ( ))
>      (block {
>       (local_variable_declaration type: (type_identifier)
>        declarator: 
>         (variable_declarator dimensions: (identifier) =
>          value: 
>           (method_invocation object: (identifier) . name: (identifier)
>            arguments: (argument_list ( ))))
>        type: ;)
>       }))
>     })))
> ```
>
>
> and when this is invoked at point:
>
> ```
> (treesit-node-at (point)) ;; #<treesit-node "}" in 90-91>
> (treesit-node-parent (treesit-node-at (point))) ;; #<treesit-node block in 35-91>
> ```
>
> In a way I would expect it to match either variable_declarator or
> local_variable_declaration.  I know this behavior has changed a couple
> of times the last year, wrt treesit-node-at and treesit-node-on, but
> it's a little over my head how this calcutation is done.

So when treesit-indent runs, it tries to get the largest node that
starts at BOL, where BOL is the first non-whitespace character of the
current line. In this case, there is no such node (because point is on
an empty line), so NODE is set to nil, and parent is set to the smallest
node that covers BOL, which is the (block) node.

> In this case the syntax tree has no errors, but the code won't compile.
> Do you have any suggestions for how to remedy this in java-ts-mode only,
> or is this something to be considered for treesit.el?  Or maybe even a
> bug in tree-sitter-java?

Compile? You mean byte-compiling java-ts-mode.el? What do you want to
accomplish? The indentation you showed looks alright to me.

> I see the tree-sitter playground [0] returns:
> ```
>
>
> program [0, 0] - [8, 0]
>   class_declaration [0, 0] - [6, 1]
>     name: identifier [0, 6] - [0, 9]
>     body: class_body [0, 10] - [6, 1]
>       method_declaration [1, 4] - [5, 6]
>         modifiers [1, 4] - [1, 10]
>         type: void_type [1, 11] - [1, 15]
>         name: identifier [1, 16] - [1, 19]
>         parameters: formal_parameters [1, 19] - [1, 21]
>         body: block [1, 22] - [5, 6]
>           local_variable_declaration [2, 8] - [3, 18]
>             type: type_identifier [2, 8] - [2, 11]
>             declarator: variable_declarator [2, 12] - [3, 18]
>               name: identifier [2, 12] - [2, 13]
>               value: method_invocation [2, 16] - [3, 18]
>                 object: identifier [2, 16] - [2, 19]
>                 name: identifier [3, 13] - [3, 16]
>                 arguments: argument_list [3, 16] - [3, 18]
>             MISSING ; [3, 18] - [3, 18]
> ```
>
> Which in turn could be something new not supported in the version I run?

The explorer probably did something wrong and added the "type:"
field name to the ";" node. Other than that I think the two parse tree
should agree with each other.

Yuan