diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala index 765a1b254a..a1e8604410 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala @@ -1072,15 +1072,15 @@ class FormatWriter(formatOps: FormatOps) { } object WithBody { - def unapply(tree: Tree): Option[Tree] = + def unapply(tree: Tree): Option[(List[meta.Mod], Tree)] = tree match { - case p: Defn.Def => Some(p.body) - case p: Defn.Given => Some(p.templ) - case p: Defn.GivenAlias => Some(p.body) - case p: Defn.Val => Some(p.rhs) - case p: Defn.Trait => Some(p.templ) - case p: Defn.Class => Some(p.templ) - case p: Defn.Object => Some(p.templ) + case p: Defn.Def => Some(p.mods -> p.body) + case p: Defn.Given => Some(p.mods -> p.templ) + case p: Defn.GivenAlias => Some(p.mods -> p.body) + case p: Defn.Val => Some(p.mods -> p.rhs) + case p: Defn.Trait => Some(p.mods -> p.templ) + case p: Defn.Class => Some(p.mods -> p.templ) + case p: Defn.Object => Some(p.mods -> p.templ) case _ => None } } @@ -1104,10 +1104,12 @@ class FormatWriter(formatOps: FormatOps) { case Some(p @ (_: Case | _: Enumerator)) => if (isEarlierLine(p)) p else getAlignContainerParent(p) // containers that can be traversed further if lhs single-line - case Some(p @ AlignContainer.WithBody(b)) => + case Some(p @ AlignContainer.WithBody(mods, b)) => val keepGoing = (b.eq(child) || p.eq(child)) && { val ptokens = p.tokens - val beg = tokens.after(ptokens.head) + val beg = mods.lastOption.fold(tokens.after(ptokens.head)) { m => + tokens.next(tokens.tokenAfter(m)) + } val end = b.tokens.headOption .fold(tokens.before(ptokens.last))(tokens.justBefore) getLineDiff(locations, beg, end) == 0 diff --git a/scalafmt-tests/src/test/resources/align/DefaultWithAlign.stat b/scalafmt-tests/src/test/resources/align/DefaultWithAlign.stat index 1e34f10f64..e3307ea09e 100644 --- a/scalafmt-tests/src/test/resources/align/DefaultWithAlign.stat +++ b/scalafmt-tests/src/test/resources/align/DefaultWithAlign.stat @@ -1742,3 +1742,83 @@ enum Ship(val size: ShipSize) derives CanEqual: case Cruiser extends Ship(ShipSize(3)) case Battleship extends Ship(ShipSize(4)) case Carrier extends Ship(ShipSize(5)) +<<< scala3 align with annotation, multiline +runner.dialect = scala3 +align.multiline = true +=== +extension (y: YCoord) + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +>>> +extension (y: YCoord) + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +<<< scala3 align with annotation, !multiline +runner.dialect = scala3 +align.multiline = false +=== +extension (y: YCoord) + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +>>> +extension (y: YCoord) + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +<<< scala2 align with annotation, multiline +runner.dialect = scala213 +align.multiline = true +=== +class A(y: YCoord) { + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +} +>>> +class A(y: YCoord) { + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +} +<<< scala2 align with annotation, !multiline +runner.dialect = scala213 +align.multiline = false +=== +class A(y: YCoord) { + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +} +>>> +class A(y: YCoord) { + @targetName("addY") + def +(dy: Int): YCoord = YCoord(y + dy) + @targetName("addY") def -(dy: Int): YCoord = YCoord(y - dy) + def <(other: YCoord): Boolean = y < other + @targetName("addY") + def toInt: Int = y.toInt +}