Skip to content

Commit

Permalink
Don't render parens for case objects in union member nodes (#1600)
Browse files Browse the repository at this point in the history
  • Loading branch information
kubukoz authored Sep 30, 2024
1 parent 5f97dc1 commit 00f6531
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Thank you!

# 0.18.25

* Fixes an issue in which union members targetting Unit would fail to compile when used as traits (see [#1600](https://github.com/disneystreaming/smithy4s/pull/1600)).
* Make the `transform` method in generated `*Gen` algebras final. This should make it possible to derive e.g. `FunctorK` instances in cats-tagless automatically (see [#1588](https://github.com/disneystreaming/smithy4s/pull/1588)).

# 0.18.24
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package smithy4s.example

import smithy4s.Hints
import smithy4s.Newtype
import smithy4s.Schema
import smithy4s.ShapeId
import smithy4s.schema.Schema.bijection
import smithy4s.schema.Schema.string

object HasUnionUnitCaseTrait extends Newtype[String] {
val id: ShapeId = ShapeId("smithy4s.example", "HasUnionUnitCaseTrait")
val hints: Hints = Hints(
smithy4s.example.UnionTraitWithUnitCase.UCase.widen,
).lazily
val underlyingSchema: Schema[String] = string.withId(id).addHints(hints)
implicit val schema: Schema[HasUnionUnitCaseTrait] = bijection(underlyingSchema, asBijection)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package smithy4s.example

import UnionTraitWithUnitCase.UCaseAlt
import smithy4s.Hints
import smithy4s.Schema
import smithy4s.ShapeId
import smithy4s.ShapeTag
import smithy4s.schema.Schema.bijection
import smithy4s.schema.Schema.recursive
import smithy4s.schema.Schema.string
import smithy4s.schema.Schema.union

sealed trait UnionTraitWithUnitCase extends scala.Product with scala.Serializable { self =>
@inline final def widen: UnionTraitWithUnitCase = this
def $ordinal: Int

object project {
def u: Option[UnionTraitWithUnitCase.UCase.type] = UCaseAlt.project.lift(self)
def s: Option[String] = UnionTraitWithUnitCase.SCase.alt.project.lift(self).map(_.s)
}

def accept[A](visitor: UnionTraitWithUnitCase.Visitor[A]): A = this match {
case value: UnionTraitWithUnitCase.UCase.type => visitor.u(value)
case value: UnionTraitWithUnitCase.SCase => visitor.s(value.s)
}
}
object UnionTraitWithUnitCase extends ShapeTag.Companion[UnionTraitWithUnitCase] {

def u(): UnionTraitWithUnitCase = UnionTraitWithUnitCase.UCase
def s(s: String): UnionTraitWithUnitCase = SCase(s)

val id: ShapeId = ShapeId("smithy4s.example", "unionTraitWithUnitCase")

val hints: Hints = Hints(
smithy.api.Trait(selector = None, structurallyExclusive = None, conflicts = None, breakingChanges = None),
).lazily

case object UCase extends UnionTraitWithUnitCase { final def $ordinal: Int = 0 }
private val UCaseAlt = Schema.constant(UnionTraitWithUnitCase.UCase).oneOf[UnionTraitWithUnitCase]("u").addHints(hints)
final case class SCase(s: String) extends UnionTraitWithUnitCase { final def $ordinal: Int = 1 }

object SCase {
val hints: Hints = Hints.empty
val schema: Schema[UnionTraitWithUnitCase.SCase] = bijection(string.addHints(hints), UnionTraitWithUnitCase.SCase(_), _.s)
val alt = schema.oneOf[UnionTraitWithUnitCase]("s")
}

trait Visitor[A] {
def u(value: UnionTraitWithUnitCase.UCase.type): A
def s(value: String): A
}

object Visitor {
trait Default[A] extends Visitor[A] {
def default: A
def u(value: UnionTraitWithUnitCase.UCase.type): A = default
def s(value: String): A = default
}
}

implicit val schema: Schema[UnionTraitWithUnitCase] = recursive(union(
UCaseAlt,
UnionTraitWithUnitCase.SCase.alt,
){
_.$ordinal
}.withId(id).addHints(hints))
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ package object example {
type ExtraData = smithy4s.example.ExtraData.Type
type FancyList = smithy4s.example.FancyList.Type
type FreeForm = smithy4s.example.FreeForm.Type
type HasUnionUnitCaseTrait = smithy4s.example.HasUnionUnitCaseTrait.Type
type Ingredients = smithy4s.example.Ingredients.Type
/** @param member
* listFoo
Expand Down
4 changes: 4 additions & 0 deletions modules/codegen/src/smithy4s/codegen/internals/IR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import TypedNode.FieldTN.OptionalSomeTN
import TypedNode.FieldTN.RequiredTN
import TypedNode.AltValueTN.ProductAltTN
import TypedNode.AltValueTN.TypeAltTN
import TypedNode.AltValueTN.UnitAltTN
import UnionMember._
import LineSegment.{NameDef, NameRef}

Expand Down Expand Up @@ -426,6 +427,7 @@ private[internals] object TypedNode {
def map[B](f: A => B): AltValueTN[B] = this match {
case ProductAltTN(value) => ProductAltTN(f(value))
case TypeAltTN(value) => TypeAltTN(f(value))
case UnitAltTN => UnitAltTN
}
}
object AltValueTN {
Expand All @@ -437,6 +439,7 @@ private[internals] object TypedNode {
fa match {
case ProductAltTN(value) => f(value).map(ProductAltTN(_))
case TypeAltTN(value) => f(value).map(TypeAltTN(_))
case UnitAltTN => Applicative[G].pure(UnitAltTN)
}
def foldLeft[A, B](fa: AltValueTN[A], b: B)(f: (B, A) => B): B = ???
def foldRight[A, B](fa: AltValueTN[A], lb: Eval[B])(
Expand All @@ -446,6 +449,7 @@ private[internals] object TypedNode {

case class ProductAltTN[A](value: A) extends AltValueTN[A]
case class TypeAltTN[A](value: A) extends AltValueTN[A]
case object UnitAltTN extends AltValueTN[Nothing]
}

implicit val typedNodeTraverse: Traverse[TypedNode] =
Expand Down
3 changes: 3 additions & 0 deletions modules/codegen/src/smithy4s/codegen/internals/Renderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,9 @@ private[internals] class Renderer(compilationUnit: CompilationUnit) { self =>
case AltTN(ref, altName, AltValueTN.TypeAltTN(alt)) =>
line"${ref.show}.${altName.capitalize}Case(${alt.runDefault}).widen".write

case AltTN(ref, altName, AltValueTN.UnitAltTN) =>
line"${ref.show}.${altName.capitalize}Case.widen".write

case AltTN(_, _, AltValueTN.ProductAltTN(alt)) =>
alt.runDefault.write

Expand Down
28 changes: 14 additions & 14 deletions modules/codegen/src/smithy4s/codegen/internals/SmithyToIR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,9 @@ private[codegen] class SmithyToIR(
maybeTypeclassesHint(shape)
}

case class AltInfo(name: String, tpe: Type, isAdtMember: Boolean)
case class AltInfo(name: String, tpe: Type, isAdtMember: Boolean) {
def isUnit: Boolean = tpe == Type.unit
}

implicit class ShapeExt(shape: Shape) {
def name = shape.getId().getName()
Expand Down Expand Up @@ -1151,21 +1153,17 @@ private[codegen] class SmithyToIR(
shape
.members()
.asScala
.map { member =>
val memberTarget =
model.expectShape(member.getTarget)
if (isPartOfAdt(memberTarget)) {
(member.getMemberName(), member.tpe.map(Left(_)))
} else {
(member.getMemberName(), member.tpe.map(Right(_)))
.flatMap { member =>
member.tpe.map { tpe =>
val memberTarget = model.expectShape(member.getTarget)

AltInfo(
member.getMemberName(),
tpe,
isAdtMember = isPartOfAdt(memberTarget)
)
}
}
.collect {
case (name, Some(Left(tpe))) =>
AltInfo(name, tpe, isAdtMember = true)
case (name, Some(Right(tpe))) =>
AltInfo(name, tpe, isAdtMember = false)
}
.toList
}

Expand Down Expand Up @@ -1302,6 +1300,8 @@ private[codegen] class SmithyToIR(
val a = if (alt.isAdtMember) {
val t = NodeAndType(node, alt.tpe)
TypedNode.AltValueTN.ProductAltTN(t)
} else if (alt.isUnit) {
TypedNode.AltValueTN.UnitAltTN
} else {
val t = NodeAndType(node, alt.tpe)
TypedNode.AltValueTN.TypeAltTN(t)
Expand Down
11 changes: 11 additions & 0 deletions sampleSpecs/misc.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ structure RangeCheck {
// face with sunglasses emoji
@pattern("^\\uD83D\\uDE0E$")
string UnicodeRegexString

@trait
union unionTraitWithUnitCase {
u: Unit
s: String
}

@unionTraitWithUnitCase(u: {

})
string HasUnionUnitCaseTrait

0 comments on commit 00f6531

Please sign in to comment.