From 11541103448e5fad39e4419b0738148b0064f6db Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 17 Nov 2023 12:45:21 +0100 Subject: [PATCH] do not warn in generated code --- .../adapter/ImplementationAdapterBuilder.kt | 12 +++--- .../codegen/kotlin/adapter/InputAdapter.kt | 8 ++-- .../kotlin/adapter/VariablesAdapter.kt | 6 +-- .../codegen/kotlin/file/EnumAsEnumBuilder.kt | 4 +- .../kotlin/file/EnumAsSealedBuilder.kt | 6 +-- .../kotlin/file/MainResolverBuilder.kt | 4 +- .../compiler/codegen/kotlin/helpers/KDoc.kt | 38 +++++++++++++++---- .../build.gradle.kts | 7 ---- .../kotlin/com/example/MyRequiresOptIn.kt | 2 +- .../src/test/kotlin/test/RequiresOptInTest.kt | 9 ++++- 10 files changed, 59 insertions(+), 37 deletions(-) diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/ImplementationAdapterBuilder.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/ImplementationAdapterBuilder.kt index 35b79fb0338..617053f1e67 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/ImplementationAdapterBuilder.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/ImplementationAdapterBuilder.kt @@ -4,7 +4,7 @@ import com.apollographql.apollo3.compiler.applyIf import com.apollographql.apollo3.compiler.codegen.Identifier import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinContext import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinSymbols -import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.suppressDeprecationAnnotationSpec +import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.addSuppressions import com.apollographql.apollo3.compiler.ir.IrModel import com.squareup.kotlinpoet.AnnotationSpec import com.squareup.kotlinpoet.ClassName @@ -128,15 +128,17 @@ internal class ImplementationAdapterBuilder( .addParameter( ParameterSpec.builder(Identifier.adapterContext, KotlinSymbols.CompositeAdapterContext) .applyIf(addTypenameArgument) { - addAnnotation(AnnotationSpec.builder(KotlinSymbols.Suppress).addMember("%S", "UNUSED_PARAMETER").build()) + addSuppressions(unusedParameter = true) } .build() ) .addCode(writeToResponseCodeBlock(model, context)) .apply { - if (model.properties.any { it.info.deprecationReason != null }) { - addAnnotation(suppressDeprecationAnnotationSpec) - } + addSuppressions( + deprecation = model.properties.any { it.info.deprecationReason != null }, + optInUsage = model.properties.any { it.info.optInFeature != null } + ) + if (!addTypenameArgument) { addModifiers(KModifier.OVERRIDE) } diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/InputAdapter.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/InputAdapter.kt index a3835f41cbe..af14b08f936 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/InputAdapter.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/InputAdapter.kt @@ -12,8 +12,8 @@ import com.apollographql.apollo3.compiler.codegen.Identifier.writer import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinContext import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinSymbols import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.NamedType +import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.addSuppressions import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.requiresOptInAnnotation -import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.suppressDeprecationAnnotationSpec import com.apollographql.apollo3.compiler.ir.isOptional import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock @@ -33,9 +33,9 @@ internal fun List.inputAdapterTypeSpec( .addFunction(notImplementedFromResponseFunSpec(adaptedTypeName)) .addFunction(writeToResponseFunSpec(context, adaptedTypeName)) .apply { - if (this@inputAdapterTypeSpec.any { it.deprecationReason != null }) { - addAnnotation(suppressDeprecationAnnotationSpec) - } + addSuppressions( + deprecation = this@inputAdapterTypeSpec.any { it.deprecationReason != null } + ) if (any { it.optInFeature != null }) { val requiresOptInAnnotation = context.resolver.resolveRequiresOptInAnnotation() if (requiresOptInAnnotation != null) { diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/VariablesAdapter.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/VariablesAdapter.kt index 578668cf83d..5bf7987c0be 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/VariablesAdapter.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/adapter/VariablesAdapter.kt @@ -8,8 +8,8 @@ import com.apollographql.apollo3.compiler.codegen.Identifier.writer import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinContext import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinSymbols import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.NamedType +import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.addSuppressions import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.requiresOptInAnnotation -import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.suppressDeprecationAnnotationSpec import com.apollographql.apollo3.compiler.ir.IrBooleanValue import com.apollographql.apollo3.compiler.ir.isOptional import com.squareup.kotlinpoet.AnnotationSpec @@ -26,9 +26,7 @@ internal fun List.variablesAdapterTypeSpec( return TypeSpec.objectBuilder(adapterName) .addFunction(serializeVariablesFunSpec(context, adaptedTypeName)) .apply { - if (this@variablesAdapterTypeSpec.any { it.deprecationReason != null }) { - addAnnotation(suppressDeprecationAnnotationSpec) - } + addSuppressions(this@variablesAdapterTypeSpec.any { it.deprecationReason != null }) if (any { it.optInFeature != null }) { val requiresOptInAnnotation = context.resolver.resolveRequiresOptInAnnotation() if (requiresOptInAnnotation != null) { diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsEnumBuilder.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsEnumBuilder.kt index 1b6a4602d7a..b69336bd2f1 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsEnumBuilder.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsEnumBuilder.kt @@ -7,12 +7,12 @@ import com.apollographql.apollo3.compiler.codegen.kotlin.CgFile import com.apollographql.apollo3.compiler.codegen.kotlin.CgFileBuilder import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinContext import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinSymbols +import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.addSuppressions import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.deprecatedAnnotation import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddDeprecation import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddDescription import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddOptIn import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddRequiresOptIn -import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeSuppressDeprecation import com.apollographql.apollo3.compiler.ir.IrEnum import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock @@ -97,7 +97,7 @@ internal class EnumAsEnumBuilder( private fun IrEnum.knownEntriesPropertySpec(): PropertySpec { return PropertySpec.builder(Identifier.knownEntries, KotlinSymbols.List.parameterizedBy(selfClassName)) .addKdoc("All [%T] known at compile time", selfClassName) - .maybeSuppressDeprecation(enum.values) + .addSuppressions(enum.values.any { it.deprecationReason != null }) .maybeAddOptIn(context.resolver, enum.values) .getter( FunSpec.getterBuilder() diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsSealedBuilder.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsSealedBuilder.kt index a9ed11a07a2..f7e68918989 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsSealedBuilder.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/EnumAsSealedBuilder.kt @@ -6,11 +6,11 @@ import com.apollographql.apollo3.compiler.codegen.kotlin.CgFile import com.apollographql.apollo3.compiler.codegen.kotlin.CgFileBuilder import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinContext import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinSymbols +import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.addSuppressions import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddDeprecation import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddDescription import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddOptIn import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeAddRequiresOptIn -import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.maybeSuppressDeprecation import com.apollographql.apollo3.compiler.ir.IrEnum import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock @@ -121,7 +121,7 @@ internal class EnumAsSealedBuilder( private fun IrEnum.safeValueOfFunSpec(): FunSpec { return FunSpec.builder(safeValueOf) .addKdoc("Returns the [%T] that represents the specified [rawValue].\n", selfClassName) - .maybeSuppressDeprecation(enum.values) + .addSuppressions(enum.values.any { it.deprecationReason != null }) .maybeAddOptIn(context.resolver, enum.values) .addParameter("rawValue", KotlinSymbols.String) .returns(selfClassName) @@ -139,7 +139,7 @@ internal class EnumAsSealedBuilder( private fun IrEnum.knownValuesFunSpec(): FunSpec { return FunSpec.builder(knownValues) .addKdoc("Returns all [%T] known at compile time", selfClassName) - .maybeSuppressDeprecation(enum.values) + .addSuppressions(enum.values.any { it.deprecationReason != null }) .maybeAddOptIn(context.resolver, enum.values) .returns(KotlinSymbols.Array.parameterizedBy(selfClassName)) .addCode( diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/MainResolverBuilder.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/MainResolverBuilder.kt index ff4e9cf7778..7dfae241109 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/MainResolverBuilder.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/file/MainResolverBuilder.kt @@ -5,7 +5,7 @@ import com.apollographql.apollo3.compiler.codegen.kotlin.CgFile import com.apollographql.apollo3.compiler.codegen.kotlin.CgFileBuilder import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinContext import com.apollographql.apollo3.compiler.codegen.kotlin.KotlinSymbols -import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.suppressDeprecationAnnotationSpec +import com.apollographql.apollo3.compiler.codegen.kotlin.helpers.addSuppressions import com.apollographql.apollo3.compiler.ir.IrExecutionContextTargetArgument import com.apollographql.apollo3.compiler.ir.IrGraphqlTargetArgument import com.apollographql.apollo3.compiler.ir.IrOptionalType @@ -52,7 +52,7 @@ internal class MainResolverBuilder( .addProperty(resolversPropertySpec()) .addFunction(typenameFunSpec()) .addFunction(resolveFunSpec()) - .addAnnotation(suppressDeprecationAnnotationSpec) + .addSuppressions(deprecation = true) .build() } diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/helpers/KDoc.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/helpers/KDoc.kt index d9fbdac1326..d739248778a 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/helpers/KDoc.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/codegen/kotlin/helpers/KDoc.kt @@ -114,14 +114,6 @@ internal fun FunSpec.Builder.maybeAddRequiresOptIn(resolver: KotlinResolver, opt return addAnnotation(AnnotationSpec.builder(annotation).build()) } -internal val suppressDeprecationAnnotationSpec = AnnotationSpec.builder(KotlinSymbols.Suppress) - .addMember("%S", "DEPRECATION") - .build() - -internal fun > T.maybeSuppressDeprecation(enumValues: List): T = applyIf(enumValues.any { !it.deprecationReason.isNullOrBlank() }) { - addAnnotation(suppressDeprecationAnnotationSpec) -} - internal fun requiresOptInAnnotation(annotation: ClassName): AnnotationSpec { return AnnotationSpec.builder(KotlinSymbols.OptIn) .addMember(CodeBlock.of("%T::class", annotation)) @@ -135,3 +127,33 @@ internal fun > T.maybeAddOptIn( val annotation = resolver.resolveRequiresOptInAnnotation() ?: return@applyIf addAnnotation(requiresOptInAnnotation(annotation)) } + +/** + * Add suppressions for generated code. + * This is code the user has no control over and it should not generate warnings + */ +internal fun > T.addSuppressions( + deprecation: Boolean = false, + optInUsage: Boolean = false, + unusedParameter: Boolean = false +): T = apply { + if (!deprecation && !optInUsage && !unusedParameter) { + return@apply + } + + addAnnotation( + AnnotationSpec.builder(KotlinSymbols.Suppress) + .apply { + if (deprecation) { + addMember("%S", "DEPRECATION") + } + if (optInUsage) { + addMember("%S", "OPT_IN_USAGE") + } + if (unusedParameter) { + addMember("%S", "UNUSED_PARAMETER") + } + } + .build() + ) +} diff --git a/tests/deprecated-requires-opt-in/build.gradle.kts b/tests/deprecated-requires-opt-in/build.gradle.kts index f8079c06ac8..e2072ff3cc1 100644 --- a/tests/deprecated-requires-opt-in/build.gradle.kts +++ b/tests/deprecated-requires-opt-in/build.gradle.kts @@ -11,13 +11,6 @@ dependencies { testImplementation(libs.junit) } -/** - * Because of: - * - * w: GetNewFieldQuery_ResponseAdapter.kt:50:82 Apollo: This symbol requires opt-in - */ -allWarningsAsErrors(false) - apollo { service("default") { srcDir("graphql") diff --git a/tests/deprecated-requires-opt-in/src/main/kotlin/com/example/MyRequiresOptIn.kt b/tests/deprecated-requires-opt-in/src/main/kotlin/com/example/MyRequiresOptIn.kt index 160714f2064..c021b1d19ab 100644 --- a/tests/deprecated-requires-opt-in/src/main/kotlin/com/example/MyRequiresOptIn.kt +++ b/tests/deprecated-requires-opt-in/src/main/kotlin/com/example/MyRequiresOptIn.kt @@ -2,7 +2,7 @@ package com.example @RequiresOptIn( level = RequiresOptIn.Level.WARNING, - message = "Apollo: This symbol requires opt-in" + message = "MyRequiresOptIn: This symbol requires opt-in" ) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY) annotation class MyRequiresOptIn \ No newline at end of file diff --git a/tests/deprecated-requires-opt-in/src/test/kotlin/test/RequiresOptInTest.kt b/tests/deprecated-requires-opt-in/src/test/kotlin/test/RequiresOptInTest.kt index b5c56b74a16..52fee308f67 100644 --- a/tests/deprecated-requires-opt-in/src/test/kotlin/test/RequiresOptInTest.kt +++ b/tests/deprecated-requires-opt-in/src/test/kotlin/test/RequiresOptInTest.kt @@ -14,6 +14,7 @@ import default.type.SomeInput as SomeInputDefault import none.GetNewFieldQuery as GetNewFieldQueryNone import none.type.Direction as DirectionNone import none.type.SomeInput as SomeInputNone +import com.example.MyRequiresOptIn @Suppress("DEPRECATION") class RequiresOptInTest { @@ -21,7 +22,6 @@ class RequiresOptInTest { * Visual test: this allows to see how the annotation is used but doesn't actually test anything */ @Test - @OptIn(ApolloRequiresOptIn::class) fun visualTest() { SomeInputNone( newInputField = Optional.Present(9), @@ -31,6 +31,7 @@ class RequiresOptInTest { newInputField } + @OptIn(ApolloRequiresOptIn::class) SomeInputDefault( newInputField = Optional.Present(9), oldInputField = Optional.Present(0), @@ -39,6 +40,7 @@ class RequiresOptInTest { newInputField } + @OptIn(MyRequiresOptIn::class) SomeInputCustom( newInputField = Optional.Present(9), oldInputField = Optional.Present(0), @@ -54,6 +56,8 @@ class RequiresOptInTest { oldField newField } + + @OptIn(ApolloRequiresOptIn::class) GetNewFieldQueryDefault.Data( newField = DirectionDefault.NORTH, oldField = DirectionDefault.SOUTH @@ -61,6 +65,8 @@ class RequiresOptInTest { oldField newField } + + @OptIn(MyRequiresOptIn::class) GetNewFieldQueryCustom.Data( newField = DirectionCustom.NORTH, oldField = DirectionCustom.SOUTH @@ -90,6 +96,7 @@ class RequiresOptInTest { assertTrue(customInputAnnotationsMethod?.declaredAnnotations?.any { it.annotationClass.simpleName == "MyRequiresOptIn"} == true) assertFalse(DirectionDefault.NORTH.javaClass.getField("NORTH").declaredAnnotations.any { it.annotationClass.simpleName == "ApolloRequiresOptIn"}) + @OptIn(MyRequiresOptIn::class) assertTrue(DirectionCustom.NORTH.javaClass.getField("NORTH").declaredAnnotations.any { it.annotationClass.simpleName == "MyRequiresOptIn"}) val noneClass = GetNewFieldQueryNone.Data::class.java