Skip to content

Commit

Permalink
Merge pull request #385 from disneystreaming/initialization-bug
Browse files Browse the repository at this point in the history
fix init ordering bug
  • Loading branch information
daddykotex committed Aug 19, 2022
2 parents a51fc4a + 097b526 commit 71d70db
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
lazy val root = (project in file("."))
.enablePlugins(Smithy4sCodegenPlugin)
.settings(
scalaVersion := "2.13.6",
scalaVersion := "2.13.8",
libraryDependencies += "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2021-2022 Disney Streaming
*
* Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://disneystreaming.github.io/TOST-1.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package demo

object Main extends App {
try {
println(smithy.api.NonEmptyString("nope").value)
} catch {
case _: java.lang.ExceptionInInitializerError =>
println("failed")
sys.exit(1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
> compile
$ exists target/scala-2.13/src_managed/main/smithy4s/example/ObjectService.scala
$ exists target/scala-2.13/resource_managed/main/smithy4s.example.ObjectService.json

# check if code can run, this can reveal runtime issues
# such as initialization errors
> run
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ object CollisionAvoidance {
recursive,
hints.map(modHint)
)
case TypeAlias(name, originalName, tpe, isUnwrapped, hints) =>
case TypeAlias(name, originalName, tpe, isUnwrapped, rec, hints) =>
TypeAlias(
protect(name.capitalize),
originalName,
modType(tpe),
isUnwrapped,
rec,
hints.map(modHint)
)
case Enumeration(name, originalName, values, hints) =>
Expand Down
1 change: 1 addition & 0 deletions modules/codegen/src/smithy4s/codegen/IR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ case class TypeAlias(
originalName: String,
tpe: Type,
isUnwrapped: Boolean,
recursive: Boolean = false,
hints: List[Hint] = Nil
) extends Decl

Expand Down
13 changes: 9 additions & 4 deletions modules/codegen/src/smithy4s/codegen/Renderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,16 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
case p: Product => renderProduct(p)
case union @ Union(_, originalName, alts, recursive, hints) =>
renderUnion(union.nameRef, originalName, alts, recursive, hints)
case ta @ TypeAlias(_, originalName, tpe, _, hints) =>
renderTypeAlias(ta.nameRef, originalName, tpe, hints)
case ta @ TypeAlias(_, originalName, tpe, _, recursive, hints) =>
renderTypeAlias(ta.nameRef, originalName, tpe, recursive, hints)
case enumeration @ Enumeration(_, originalName, values, hints) =>
renderEnum(enumeration.nameRef, originalName, values, hints)
case _ => Lines.empty
}

def renderPackageContents: Lines = {
val typeAliases = compilationUnit.declarations.collect {
case TypeAlias(name, _, _, _, _) =>
case TypeAlias(name, _, _, _, _, _) =>
line"type $name = ${compilationUnit.namespace}.${name}.Type"
}

Expand Down Expand Up @@ -691,17 +691,22 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
name: NameRef,
originalName: String,
tpe: Type,
recursive: Boolean,
hints: List[Hint]
): Lines = {
val definition =
if (recursive) line"$recursive_("
else Line.empty
val trailingCalls =
line".withId(id).addHints(hints)${renderConstraintValidation(hints)}"
val closing = if (recursive) ")" else ""
lines(
obj(name, line"$Newtype_[$tpe]")(
renderId(originalName),
renderHintsVal(hints),
line"val underlyingSchema : $Schema_[$tpe] = ${tpe.schemaRef}$trailingCalls",
lines(
line"implicit val schema : $Schema_[$name] = $bijection_(underlyingSchema, asBijection)"
line"implicit val schema : $Schema_[$name] = $definition$bijection_(underlyingSchema, asBijection)$closing"
)
)
)
Expand Down
24 changes: 19 additions & 5 deletions modules/codegen/src/smithy4s/codegen/SmithyToIR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,25 @@ private[codegen] class SmithyToIR(model: Model, namespace: String) {
private def getDefault(shape: Shape): Option[Decl] = {
val hints = traitsToHints(shape.getAllTraits().asScala.values.toList)

val recursive = hints.exists {
case Hint.Trait => true
case _ => false
}

shape.tpe.flatMap {
case Type.Alias(_, name, tpe: Type.ExternalType, isUnwrapped) =>
val newHints = hints.filterNot(_ == tpe.refinementHint)
TypeAlias(name, name, tpe, isUnwrapped, newHints).some
TypeAlias(name, name, tpe, isUnwrapped, recursive, newHints).some
case Type.Alias(_, name, tpe, isUnwrapped) =>
TypeAlias(name, name, tpe, isUnwrapped, hints).some
TypeAlias(name, name, tpe, isUnwrapped, recursive, hints).some
case Type.PrimitiveType(_) => None
case other =>
TypeAlias(
shape.name,
shape.name,
other,
isUnwrapped = false,
recursive,
hints
).some
}
Expand Down Expand Up @@ -143,9 +149,13 @@ private[codegen] class SmithyToIR(model: Model, namespace: String) {
)

override def structureShape(shape: StructureShape): Option[Decl] = {
val rec = isRecursive(shape.getId())

val hints = traitsToHints(shape.getAllTraits().asScala.values.toList)
val isTrait = hints.exists {
case Hint.Trait => true
case _ => false
}
val rec = isRecursive(shape.getId()) || isTrait

val mixins = shape.getMixins.asScala.flatMap(_.tpe).toList
val isMixin = shape.hasTrait(classOf[MixinTrait])
val p =
Expand All @@ -167,8 +177,12 @@ private[codegen] class SmithyToIR(model: Model, namespace: String) {
val rec = isRecursive(shape.getId())

val hints = traitsToHints(shape.getAllTraits().asScala.values.toList)
val isTrait = hints.exists {
case Hint.Trait => true
case _ => false
}
NonEmptyList.fromList(shape.alts).map { case alts =>
Union(shape.name, shape.name, alts, rec, hints)
Union(shape.name, shape.name, alts, rec || isTrait, hints)
}
}

Expand Down
3 changes: 2 additions & 1 deletion modules/example/src/smithy4s/example/ArbitraryData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package smithy4s.example
import smithy4s.Schema
import smithy4s.Hints
import smithy4s.ShapeId
import smithy4s.schema.Schema.recursive
import smithy4s.schema.Schema.bijection
import smithy4s.Document
import smithy4s.Newtype
Expand All @@ -14,5 +15,5 @@ object ArbitraryData extends Newtype[Document] {
smithy.api.Trait(None, None, None, None),
)
val underlyingSchema : Schema[Document] = document.withId(id).addHints(hints)
implicit val schema : Schema[ArbitraryData] = bijection(underlyingSchema, asBijection)
implicit val schema : Schema[ArbitraryData] = recursive(bijection(underlyingSchema, asBijection))
}
5 changes: 3 additions & 2 deletions modules/example/src/smithy4s/example/TestTrait.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import smithy4s.Schema
import smithy4s.Hints
import smithy4s.ShapeId
import smithy4s.schema.Schema.struct
import smithy4s.schema.Schema.recursive
import smithy4s.ShapeTag

case class TestTrait(orderType: Option[OrderType] = None)
Expand All @@ -14,9 +15,9 @@ object TestTrait extends ShapeTag.Companion[TestTrait] {
smithy.api.Trait(None, None, None, None),
)

implicit val schema: Schema[TestTrait] = struct(
implicit val schema: Schema[TestTrait] = recursive(struct(
OrderType.schema.optional[TestTrait]("orderType", _.orderType),
){
TestTrait.apply
}.withId(id).addHints(hints)
}.withId(id).addHints(hints))
}

0 comments on commit 71d70db

Please sign in to comment.