Skip to content
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

Don't insert semicolons in conditions unless indented #12801

Merged
merged 1 commit into from Jun 16, 2021

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jun 12, 2021

In a statement like this

if foo
    (bar)
then

we would never expect a semicolon to be inserted between foo and bar. The foo
would need to be indented itself for this to happen.

So, the following is OK

if
  val x = ...
  x > 0
then

But the following is not:

if val x = ...
  x > 0

Fixes #12757

In a statement like this
```scala
if foo
    (bar)
then
```
we would never expect a semicolon to be inserted between `foo` and `bar`. The `foo`
would need to be indented itself for this to happen.

So, the following is OK
```scala
if
  val x = ...
  x > 0
then
```
But the following is not:
```scala
if val x = ...
  x > 0
```

Fixes scala#12757
Copy link
Contributor

@tgodzik tgodzik left a comment

Choose a reason for hiding this comment

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

Looks good, though I have a question about:

def f =
   if
      x.exists
         (x => x == 10) then
      println("Yes")
   else
      println("No")

Do we ignore the indentation after if if we have a single statement?

@odersky
Copy link
Contributor Author

odersky commented Jun 16, 2021

@tgodzik I don't think there's a special rule for single statements. Your example would parse like this with indent/unindent tokens added:

def f = <INDENT>
   if <INDENT>
      x.exists
         (x => x == 10) <UNINDENT> then <INDENT>
      println("Yes") <UNINDENT>
   else <INDENT>
      println("No") <UNINDENT> <UNINDENT>

In fact you can test this yourself by uncommenting this line in Parser.scala:

    // in.debugTokenStream = true    // uncomment to see the token stream of the standard scanner, but not syntax highlighting

Notes:

  1. The then forces an <UNINDENT> to be inserted since otherwise we cannot continue to parse.
  2. The reason an <INDENT> is inserted after the then is that the previous indentation region started at width 3, and the new indentation is at 6, so it is indented more. This holds even though the immediately preceding line is indented more.

@odersky odersky closed this Jun 16, 2021
@odersky odersky reopened this Jun 16, 2021
@tgodzik
Copy link
Contributor

tgodzik commented Jun 16, 2021

Ok, I kind of assumed that:

An <outdent> is also inserted if the next token following a statement sequence starting with an <indent> closes an indentation region, i.e. is one of then, else, do, catch, finally, yield, }, ), ] or case.

is also at line break, but that is actually not mentioned in the paragraph. We should be able to fix that.

@tgodzik
Copy link
Contributor

tgodzik commented Jun 16, 2021

Fixing it here scalameta/scalameta#2384

@odersky odersky merged commit bace3e6 into scala:master Jun 16, 2021
@odersky odersky deleted the fix-12757 branch June 16, 2021 16:34
@Kordyjan Kordyjan added this to the 3.0.2 milestone Aug 2, 2023
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.

Clarification of intended ’if … then’ new control syntax interaction with newlines
3 participants