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

Enforce newline before first def within class with extensions #1975

Closed
jalaziz opened this issue May 18, 2020 · 2 comments · Fixed by #2484
Closed

Enforce newline before first def within class with extensions #1975

jalaziz opened this issue May 18, 2020 · 2 comments · Fixed by #2484

Comments

@jalaziz
Copy link

jalaziz commented May 18, 2020

  • Version: 2.5.2
  • Integration: IntelliJ
  • Configuration:
version = 2.5.2
preset = IntelliJ
align.preset = some
assumeStandardLibraryStripMargin = true
continuationIndent.defnSite = 2
continuationIndent.extendSite = 2
continuationIndent.withSiteRelativeToExtends = 0
danglingParentheses.exclude = []
docstrings = ScalaDoc
maxColumn = 100
newlines.topLevelStatements = [before]
optIn.configStyleArguments = true
rewrite.rules = [AvoidInfix, SortModifiers, PreferCurlyFors]
rewrite.sortModifiers.order = [
  "`override`"
  "`private`"
  "`protected`"
  "`implicit`"
  "`final`"
  "`sealed`"
  "`abstract`"
  "`lazy`"
]
spaces.inImportCurlyBraces = true
trailingCommas = multiple
verticalMultiline.newlineAfterOpenParen = true
verticalMultiline.excludeDanglingParens = []

Steps

Given code like this:

trait Bar {}
trait Baz {}
case class Foo(
  a: String,
  b: String,
  c: String,
) extends Bar with Baz {
  def foo(): Int = 1
}

When I run scalafmt like this:

sbt scalafmtAll

Problem

Scalafmt formats code like this:

trait Bar {}
trait Baz {}

case class Foo(
  a: String,
  b: String,
  c: String,
) extends Bar
  with Baz {
  def foo(): Int = 1
}

Expectation

I would like the formatted output to look like this:

trait Bar {}
trait Baz {}

case class Foo(
  a: String,
  b: String,
  c: String,
) extends Bar
  with Baz {

  def foo(): Int = 1
}

Notes

The main issue is I'm trying to achieve the formatting recommended by the official scala style guide for classes.

The docs provide two examples. The first without an extends statement:

class Person(name: String, age: Int) {
  …
}

class Person(
  name: String,
  age: Int,
  birthdate: Date,
  astrologicalSign: String,
  shoeSize: Int,
  favoriteColor: java.awt.Color,
) {
  def firstMethod: Foo = …
}

The second, with extends:

class Person(
  name: String,
  age: Int,
  birthdate: Date,
  astrologicalSign: String,
  shoeSize: Int,
  favoriteColor: java.awt.Color,
) extends Entity
  with Logging
  with Identifiable
  with Serializable {

  def firstMethod: Foo = …
}

The exact wording is:

If a class/object/trait extends anything, the same general rule applies, put it on one line unless it goes over about 100 characters, and then put each item on its own line with trailing commas; closing parenthesis provides visual separation between constructor arguments and extensions; empty line should be added to further separate extensions from class implementation:

I believe this is related to issues brought up in #1653. In that issue, it was proposed to add a newlines.alwaysInsideTopLevelStatements configuration option.

The style guide seems to suggest adding the empty line for visual separation when extensions are added to the class.

Unfortunately, newlines.topLevelStatements only seems to focus on spacing between the top level elements and only when newlines.topLevelStatementsMinBreaks is meant. While I could partially achieve the desired result by setting newlines.topLevelStatementsMinBreaks to 0, it's not ideal because:

  1. Everything ends up being separated by a newline
  2. It violates the first example where a newline isn't needed when there is no extensions

I think what's needed is something along the lines of newlines.alwaysAfterClassExtension.

@kitbellew
Copy link
Collaborator

See #1542 and #1546. #1653 is different.

@jalaziz
Copy link
Author

jalaziz commented May 19, 2020

Thanks, did not see those!

I would say this is similar, but different than #1542. In particular, the style guide only suggests the newline if there are class extensions.

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 a pull request may close this issue.

2 participants