tree-sitter / tree-sitter-go

Go grammar for tree-sitter
MIT License
310 stars 65 forks source link

Multiple return values not parsed correctly #107

Closed edkolev closed 1 year ago

edkolev commented 1 year ago

I've run into the following issue: multiples return values of functions are not always parsed correctly.

For example:

To reproduce:

func notOk() (int, map[int]int) { return 0, nil }

- inspect the tree, I use `M-x treesit-explore-mode` in emacs. The whole tree is pasted below. EDIT: below in a comment is the tree produced by `tree-sitter parse ...`.

- the first function "ok" is as expected - `([]int, map[int]int)` is parsed into one `parameter_list` with two `parameter_declaration` branches:

result: (parameter_list ( (parameter_declaration type: (slice_type [ ] element: (type_identifier))) , (parameter_declaration type: (map_type map [ key: (type_identifier) ] value: (type_identifier))) ))

- the second function "notOk" is **not** parsed as expected - `(int, map[int]int)` is parsed into one `parameter_list` with **one** `parameter_declaration` branches, I expect **two** `parameter_declaration` branches.

result: (parameter_list ( (parameter_declaration name: (identifier) name: , type: (identifier) (array_type [ length: (identifier) ] element: (type_identifier))) ))


-----------------------------------------
Full tree:

(source_file (package_clause package (package_identifier)) \n (comment) (function_declaration func name: (identifier) parameters: (parameter_list ( )) result: (parameter_list ( (parameter_declaration type: (slice_type [ ] element: (type_identifier))) , (parameter_declaration type: (map_type map [ key: (type_identifier) ] value: (type_identifier))) )) body: (block { (return_statement return (expression_list (nil) , (nil))) \n })) \n (function_declaration func name: (identifier) parameters: (parameter_list ( )) result: (parameter_list ( (parameter_declaration name: (identifier) name: , type: (identifier) (array_type [ length: (identifier) ] element: (type_identifier))) )) body: (block { (return_statement return (expression_list (int_literal) , (nil))) \n })) \n)

edkolev commented 1 year ago

Here's a minimalistic example:

  1. with input
    func notOk() (int, map[int]int) {}
  2. output by tree-sitter parse ...
    (source_file [0, 0] - [1, 0]
    (function_declaration [0, 0] - [0, 34]
    name: (identifier [0, 5] - [0, 10])
    parameters: (parameter_list [0, 10] - [0, 12])
    result: (parameter_list [0, 13] - [0, 31]
      (parameter_declaration [0, 14] - [0, 30]
        name: (identifier [0, 14] - [0, 17])
        name: (identifier [0, 19] - [0, 22])
        type: (array_type [0, 22] - [0, 30]
          length: (identifier [0, 23] - [0, 26])
          element: (type_identifier [0, 27] - [0, 30]))))
    body: (block [0, 32] - [0, 34])))
  3. you can see the "bad" array_type in the output

Attached is a screenshot of log.html

Screenshot 2023-02-07 at 7 05 35