Skip to content

Allow for catch and finally in try expression to be on a new line #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 12, 2021

Conversation

ckipp01
Copy link
Collaborator

@ckipp01 ckipp01 commented Mar 7, 2021

I noticed that try_expressions weren't quite looking right when they were on a new line. However, I'm having a hard time understanding exactly how to actually take the new line into account.

To give an example.

def main() = {
  try {
   doThing()
  } catch {
    case _: Throwable => 3
  }
}

This parses correctly and the finally_clause is recognized as part of the try_expression.

(compilation_unit [0, 0] - [7, 0]
  (function_definition [0, 0] - [6, 1]
    name: (identifier [0, 4] - [0, 8])
    parameters: (parameters [0, 8] - [0, 10])
    body: (block [0, 13] - [6, 1]
      (try_expression [1, 2] - [5, 3]
        body: (block [1, 6] - [3, 3]
          (call_expression [2, 3] - [2, 12]
            function: (identifier [2, 3] - [2, 10])
            arguments: (arguments [2, 10] - [2, 12])))
        (catch_clause [3, 4] - [5, 3]
          (case_block [3, 10] - [5, 3]
            (case_clause [4, 4] - [5, 2]
              pattern: (typed_pattern [4, 9] - [4, 21]
                pattern: (wildcard [4, 9] - [4, 10])
                type: (type_identifier [4, 12] - [4, 21]))
              body: (number [4, 25] - [4, 26]))))))))

However, if you simply bump the catch down a line to create:

def main() = {
  try {
   doThing()
  }
  catch {
    case _: Throwable => 3
  }
}

I then totally misses the catch_clause.

(compilation_unit [0, 0] - [8, 0]
  (function_definition [0, 0] - [7, 1]
    name: (identifier [0, 4] - [0, 8])
    parameters: (parameters [0, 8] - [0, 10])
    body: (block [0, 13] - [7, 1]
      (try_expression [1, 2] - [3, 3]
        body: (block [1, 6] - [3, 3]
          (call_expression [2, 3] - [2, 12]
            function: (identifier [2, 3] - [2, 10])
            arguments: (arguments [2, 10] - [2, 12]))))
      (ERROR [4, 2] - [4, 7]
        (identifier [4, 2] - [4, 7]))
      (case_block [4, 8] - [6, 3]
        (case_clause [5, 4] - [6, 2]
          pattern: (typed_pattern [5, 9] - [5, 21]
            pattern: (wildcard [5, 9] - [5, 10])
            type: (type_identifier [5, 12] - [5, 21]))
          body: (number [5, 25] - [5, 26]))))))

This happen when using finally as well on a newline.

So this seems to make sense to me:

try_expression: $ => prec.right(seq(
'try',
field('body', $._expression),
optional($.catch_clause),
optional($.finally_clause)
)),

Although I'm not really sure how that works with newlines. Do you maybe have any pointers or insights into what I'm missing here? I'd love to get a better understanding of what's going on here and start tackling some of these missing features for the Scala grammar. I'm increasingly wanting a complete grammar as all the great stuff around Neovim and tree-sitter is happening, and I feel like Scala is missing out!

@maxbrunsfeld
Copy link
Contributor

I think that what's needed is a change to the external scanner's logic for inserting automatic_semicolon tokens, implemented here.

We need to do the same thing for catch and finally that is already done for else: prevent automatic semicolons for lines that begin with else/finally/catch.

@maxbrunsfeld
Copy link
Contributor

This describes Scala's rules for automatic semicolon insertion.

In short, a line ending is treated as a semicolon unless one of the following conditions is true:

  1. The line in question ends in a word that would not be legal as the end of a statement, such as a period or an infix operator.
  2. The next line begins with a word that cannot start a statement.
  3. The line ends while inside parentheses(...) or brackets[...], because these cannot contain multiple statements anyway.

@ckipp01 ckipp01 force-pushed the try_expression branch 2 times, most recently from f37efab to e0b0381 Compare March 10, 2021 18:46
@ckipp01 ckipp01 marked this pull request as ready for review March 10, 2021 19:10
@ckipp01
Copy link
Collaborator Author

ckipp01 commented Mar 10, 2021

Cool, thanks a lot for the pointers @maxbrunsfeld. I think this should be ready to go!

@ckipp01
Copy link
Collaborator Author

ckipp01 commented Mar 11, 2021

I'm not sure if this isn't trigger the build. It may be since this was already opened when the actions pr was merged that it doesn't register. Do you by chance want me to close this and reopen to try and trigger it?

EDIT: Tried and that didn't work. I think I have a fix included for it an a commit here.

Comment on lines +5 to +6
- master
pull_request:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxbrunsfeld maxbrunsfeld merged commit 63f103c into tree-sitter:master Mar 12, 2021
@maxbrunsfeld
Copy link
Contributor

Thanks!

@ckipp01 ckipp01 deleted the try_expression branch March 12, 2021 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants