Skip to content

Commit 00bc26f

Browse files
authored
Force rendering package object when a validated newtype is present (#1656)
1 parent c8d0364 commit 00bc26f

File tree

5 files changed

+65
-34
lines changed

5 files changed

+65
-34
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Thank you!
88
# 0.18.30
99

1010
* Add utilities for Service.Builder in [#1644](https://github.com/disneystreaming/smithy4s/pull/1644)
11+
* Use correct cross path for protobuf-runtime-scala in [#1648](https://github.com/disneystreaming/smithy4s/pull/1648)
12+
* Force rendering package object when a validated newtype is present in [#1656](https://github.com/disneystreaming/smithy4s/pull/1656)
1113

1214
# 0.18.29
1315

modules/codegen/src/smithy4s/codegen/internals/Renderer.scala

+37-34
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,17 @@ private[internals] object Renderer {
8181
def apply(unit: CompilationUnit): List[Result] = {
8282
val r = new Renderer(unit)
8383

84-
val pack = Result(
85-
unit.namespace,
86-
"package",
87-
r.renderPackageContents.list
88-
.map(_.segments.toList.map(_.show).mkString)
89-
.mkString(
90-
System.lineSeparator()
91-
)
92-
)
84+
val packageObjectFile = r.renderPackageContents.map { packageLines =>
85+
Result(
86+
unit.namespace,
87+
"package",
88+
packageLines.list
89+
.map(_.segments.toList.map(_.show).mkString)
90+
.mkString(
91+
System.lineSeparator()
92+
)
93+
)
94+
}
9395

9496
val classes = unit.declarations.map { decl =>
9597
val renderResult = r.renderDecl(decl) ++ newline
@@ -161,13 +163,7 @@ private[internals] object Renderer {
161163
Result(unit.namespace, decl.name, content)
162164
}
163165

164-
val packageApplicableDecls = unit.declarations.filter {
165-
case _: TypeAlias | _: Service => true
166-
case _ => false
167-
}
168-
169-
if (packageApplicableDecls.isEmpty) classes
170-
else pack :: classes
166+
packageObjectFile.toList ::: classes
171167
}
172168

173169
}
@@ -271,7 +267,7 @@ private[internals] class Renderer(compilationUnit: CompilationUnit) { self =>
271267
}
272268
}
273269

274-
def renderPackageContents: Lines = {
270+
def renderPackageContents: Option[Lines] = {
275271
val typeAliases = compilationUnit.declarations
276272
.collect {
277273
case TypeAlias(_, name, _, _, _, hints) =>
@@ -288,24 +284,31 @@ private[internals] class Renderer(compilationUnit: CompilationUnit) { self =>
288284
)
289285
}
290286

291-
val blk =
292-
block(
293-
line"package object ${compilationUnit.namespace.split('.').last}"
294-
)(
295-
compilationUnit.declarations.map(renderDeclPackageContents),
296-
newline,
297-
typeAliases,
298-
newline
299-
)
287+
val serviceAliases =
288+
compilationUnit.declarations.map(renderDeclPackageContents)
300289

301-
val parts = compilationUnit.namespace.split('.').filter(_.nonEmpty)
302-
if (parts.size > 1) {
303-
lines(
304-
line"package ${parts.dropRight(1).mkString(".")}",
305-
newline,
306-
blk
307-
)
308-
} else blk
290+
val packageContents = lines(serviceAliases, newline, typeAliases, newline)
291+
292+
packageContents.some
293+
.filterNot(_.isBlank)
294+
.map { contents =>
295+
block(
296+
line"package object ${compilationUnit.namespace.split('.').last}"
297+
)(
298+
contents
299+
)
300+
}
301+
.map { blk =>
302+
val parts = compilationUnit.namespace.split('.').filter(_.nonEmpty)
303+
304+
if (parts.size > 1) {
305+
lines(
306+
line"package ${parts.dropRight(1).mkString(".")}",
307+
newline,
308+
blk
309+
)
310+
} else blk
311+
}
309312
}
310313

311314
private def renderDeclPackageContents(decl: Decl): Lines = decl match {

modules/codegen/src/smithy4s/codegen/internals/ToLine.scala

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import cats.kernel.Monoid
2323
import java.util.UUID
2424

2525
import LineSegment._
26+
import cats.kernel.Eq
2627

2728
private[internals] trait ToLine[A] {
2829
def render(a: A): Line
@@ -168,5 +169,6 @@ private[internals] object Line {
168169
val space: Line = Line(" ")
169170
val dot: Line = Line(".")
170171
implicit val monoid: Monoid[Line] = Monoid.instance(empty, _ + _)
172+
implicit val eq: Eq[Line] = Eq.fromUniversalEquals
171173

172174
}

modules/codegen/src/smithy4s/codegen/internals/ToLines.scala

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ private[internals] object ToLines {
5858

5959
private[internals] case class Lines(list: List[Line]) {
6060
def isEmpty: Boolean = list.isEmpty
61+
def isBlank: Boolean = list.forall(_.isEmpty)
6162

6263
def block(l: LinesWithValue*): Lines = {
6364
val openBlock: List[Line] =

modules/codegen/test/src/smithy4s/codegen/internals/RendererSpec.scala

+23
Original file line numberDiff line numberDiff line change
@@ -686,4 +686,27 @@ final class RendererSpec extends munit.ScalaCheckSuite {
686686
)
687687
)
688688
}
689+
690+
// regression test for https://github.com/disneystreaming/smithy4s/issues/1655
691+
test("validated newtypes force creation of a package object") {
692+
val smithy =
693+
"""$version: "2"
694+
|
695+
|namespace smithy4s.example
696+
|
697+
|use smithy4s.meta#validateNewtype
698+
|
699+
|@validateNewtype
700+
|@length(min: 1)
701+
|string SomeValidatedNewtype
702+
|""".stripMargin
703+
704+
val files = generateScalaCode(smithy).keySet
705+
706+
assert(
707+
files.contains("smithy4s.example.package"),
708+
files.toString + " should contain smithy4s.example.package"
709+
)
710+
711+
}
689712
}

0 commit comments

Comments
 (0)