Skip to content

Commit

Permalink
Make enum as sealed class Unknown constructor opt-in (#5813)
Browse files Browse the repository at this point in the history
* Make enum as sealed class Unknown constructor opt-in

* Introduce ApolloEnumConstructor

* Update libraries/apollo-annotations/src/commonMain/kotlin/com/apollographql/apollo3/annotations/ApolloEnumConstructor.kt

Co-authored-by: Martin Bonnin <[email protected]>

* Update libraries/apollo-annotations/src/commonMain/kotlin/com/apollographql/apollo3/annotations/ApolloEnumConstructor.kt

Co-authored-by: Martin Bonnin <[email protected]>

---------

Co-authored-by: Martin Bonnin <[email protected]>
  • Loading branch information
BoD and martinbonnin authored Apr 16, 2024
1 parent 626f66f commit cf6359f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 16 deletions.
3 changes: 3 additions & 0 deletions libraries/apollo-annotations/api/apollo-annotations.api
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public final class com/apollographql/apollo3/annotations/ApolloDeprecatedSince$V
public static fun values ()[Lcom/apollographql/apollo3/annotations/ApolloDeprecatedSince$Version;
}

public abstract interface annotation class com/apollographql/apollo3/annotations/ApolloEnumConstructor : java/lang/annotation/Annotation {
}

public abstract interface annotation class com/apollographql/apollo3/annotations/ApolloExperimental : java/lang/annotation/Annotation {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.apollographql.apollo3.annotations

@RequiresOptIn(
level = RequiresOptIn.Level.WARNING,
message = "The `UNKNOWN__` class represents GraphQL enums that are not present in the schema and whose `rawValue` cannot be checked at build time. You may want to update your schema instead of calling this constructor directly."
)
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CONSTRUCTOR)
annotation class ApolloEnumConstructor
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ internal object KotlinSymbols {

val ApolloAdaptableWith = ClassName(ClassNames.apolloAnnotationsPackageName, "ApolloAdaptableWith")
val ApolloExperimental = ClassName(ClassNames.apolloAnnotationsPackageName, "ApolloExperimental")
val ApolloEnumConstructor = ClassName(ClassNames.apolloAnnotationsPackageName, "ApolloEnumConstructor")

val JsExport = ClassName("kotlin.js", "JsExport")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ internal class EnumAsSealedBuilder(

private fun IrEnum.unknownValueTypeSpec(): TypeSpec {
return TypeSpec.classBuilder("UNKNOWN__")
.addKdoc("%L", "An enum value that wasn't known at compile time.\n")
.primaryConstructor(primaryConstructorSpec)
.addKdoc("An enum value that wasn't known at compile time.\nConstructor is annotated with [%T] to prevent instantiation outside of this file.", KotlinSymbols.ApolloEnumConstructor)
.primaryConstructor(unknownValuePrimaryConstructorSpec)
.superclass(selfClassName)
.addSuperclassConstructorParameter("rawValue·=·rawValue")
.addFunction(
Expand Down Expand Up @@ -132,7 +132,7 @@ internal class EnumAsSealedBuilder(
.map { CodeBlock.of("%S·->·%T", it.name, it.valueClassName()) }
.joinToCode(separator = "\n", suffix = "\n")
)
.addCode("else -> %T(rawValue)\n", unknownValueClassName())
.addCode("else -> @OptIn(%T::class) %T(rawValue)\n", KotlinSymbols.ApolloEnumConstructor, unknownValueClassName())
.endControlFlow()
.build()
}
Expand Down Expand Up @@ -167,19 +167,20 @@ internal class EnumAsSealedBuilder(
return ClassName(selfClassName.packageName, selfClassName.simpleName, "UNKNOWN__")
}

private val primaryConstructorSpec =
FunSpec.constructorBuilder()
.addParameter("rawValue", KotlinSymbols.String)
.build()
private val unknownValuePrimaryConstructorSpec =
FunSpec.constructorBuilder()
.addAnnotation(KotlinSymbols.ApolloEnumConstructor)
.addParameter("rawValue", KotlinSymbols.String)
.build()

private val primaryConstructorWithOverriddenParamSpec =
FunSpec.constructorBuilder()
.addParameter("rawValue", KotlinSymbols.String)
.build()
FunSpec.constructorBuilder()
.addParameter("rawValue", KotlinSymbols.String)
.build()

private val rawValuePropertySpec =
PropertySpec.builder("rawValue", KotlinSymbols.String)
.initializer("rawValue")
.build()
PropertySpec.builder("rawValue", KotlinSymbols.String)
.initializer("rawValue")
.build()

}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit cf6359f

Please sign in to comment.