From ae66fce69116b5c18450fe2bed0ebad0fca6f3ce Mon Sep 17 00:00:00 2001 From: Nick Price Date: Tue, 7 Jun 2022 21:36:16 +0100 Subject: [PATCH] Config to control if a space is added after Constructor Annotation Fixes #3260, allowing users to opt-out from the change made by #1516 for #618 --- docs/configuration.md | 12 ++++++++++ .../scala/org/scalafmt/config/Spaces.scala | 6 ++++- .../scala/org/scalafmt/internal/Router.scala | 3 ++- .../spaces/AfterConstructorAnnotation.stat | 24 +++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 scalafmt-tests/src/test/resources/spaces/AfterConstructorAnnotation.stat diff --git a/docs/configuration.md b/docs/configuration.md index 4231b682e2..048830555b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4035,6 +4035,18 @@ spaces.afterSymbolicDefs=true def +++(a: A): F[A] ``` +### `spaces.afterConstructorAnnotation` + +```scala mdoc:defaults +spaces.afterConstructorAnnotation +``` + +```scala mdoc:scalafmt +spaces.afterConstructorAnnotation=true +--- +class A @Inject() (param1: B) +``` + ## Literals > Since v2.5.0. diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala index 77af28af2a..08efed6dff 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Spaces.scala @@ -43,6 +43,9 @@ import metaconfig._ * @param afterSymbolicDefs * If true, adds a single space after an operator method. For example: * {{{def <=> [T](that: T): Boolean}}} + * @param afterConstructorAnnotation + * If true, adds a single space after a constructor annotation. For example: + * {{{class MyClass @Inject() (param1: SomeType)}}} */ case class Spaces( beforeContextBoundColon: Spaces.BeforeContextBound = @@ -54,7 +57,8 @@ case class Spaces( neverAroundInfixTypes: Seq[String] = Nil, afterKeywordBeforeParen: Boolean = true, inByNameTypes: Boolean = true, - afterSymbolicDefs: Boolean = false + afterSymbolicDefs: Boolean = false, + afterConstructorAnnotation: Boolean = true ) { def isSpaceAfterKeyword(tokenAfter: Token): Boolean = afterKeywordBeforeParen || !tokenAfter.is[Token.LeftParen] diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala index de8c0b3601..298fe00d94 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/Router.scala @@ -674,7 +674,8 @@ class Router(formatOps: FormatOps) { // see: // https://github.com/scalameta/scalafmt/pull/1516 // https://github.com/scalameta/scalafmt/issues/1528 - case init: Init if init.parent.forall(_.is[Mod.Annot]) => Space + case init: Init if init.parent.forall(_.is[Mod.Annot]) => + Space(style.spaces.afterConstructorAnnotation) case t: Term.Name if style.spaces.afterTripleEquals && t.value == "===" => Space diff --git a/scalafmt-tests/src/test/resources/spaces/AfterConstructorAnnotation.stat b/scalafmt-tests/src/test/resources/spaces/AfterConstructorAnnotation.stat new file mode 100644 index 0000000000..f998283786 --- /dev/null +++ b/scalafmt-tests/src/test/resources/spaces/AfterConstructorAnnotation.stat @@ -0,0 +1,24 @@ +spaces.afterConstructorAnnotation = true +<<< Space between annotation and ctor argument list +class A @Inject()(b: C) +>>> +class A @Inject() (b: C) + +<<< Space between annotation and ctor argument list (with multiple argument list) +class MyComponent @Inject()(ctx: Context)(ws: WSClient) +>>> +class MyComponent @Inject() (ctx: Context)(ws: WSClient) + +<<< No space between annotation and ctor argument list +spaces.afterConstructorAnnotation = false +=== +class A @Inject() (b: C) +>>> +class A @Inject()(b: C) + +<<< No space between annotation and ctor argument list (with multiple argument list) +spaces.afterConstructorAnnotation = false +=== +class MyComponent @Inject() (ctx: Context)(ws: WSClient) +>>> +class MyComponent @Inject()(ctx: Context)(ws: WSClient)