Skip to content

Commit 132ac23

Browse files
committed
Add GraphQLIgnore annotation
Add GraphQLIgnore to be able to ignore fields, classes and interfaces
1 parent c697c5e commit 132ac23

File tree

5 files changed

+37
-21
lines changed

5 files changed

+37
-21
lines changed

apollo-execution-processor/src/main/kotlin/com/apollographql/execution/processor/ApolloProcessor.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ class ApolloProcessor(
2323
private fun getRootSymbol(resolver: Resolver, annotationName: String): KSClassDeclaration? {
2424
val ret = getSymbolsWithAnnotation(resolver, annotationName).toList()
2525

26-
if (ret.size > 1) {
26+
if (ret.size > 1 && annotationName != KotlinSymbols.GraphQLIgnore.canonicalName) {
2727
val locations = ret.map { it.location }.joinToString("\n")
2828
logger.error("There can be only one '$annotationName' annotated class, found ${ret.size}:\n$locations", ret.first())
2929
return null
3030
}
3131

3232
ret.forEach {
33-
if (it !is KSClassDeclaration || it.isAbstract()) {
33+
if ((it !is KSClassDeclaration || it.isAbstract()) && annotationName != KotlinSymbols.GraphQLIgnore.canonicalName) {
3434
logger.error("'$annotationName' cannot be set on node $it", it)
3535
return null
3636
}
@@ -53,6 +53,13 @@ class ApolloProcessor(
5353
done = true
5454

5555
val query = getRootSymbol(resolver, KotlinSymbols.GraphQLQuery.canonicalName)
56+
57+
val ignoreQuery = getRootSymbol(resolver, KotlinSymbols.GraphQLIgnore.canonicalName)
58+
59+
if (ignoreQuery != null) {
60+
logger.warn("Ignoring due to GraphQLIgnore annotation")
61+
}
62+
5663
if (query == null) {
5764
logger.error("No '@GraphQLQuery' class found")
5865
return emptyList()
@@ -63,6 +70,7 @@ class ApolloProcessor(
6370
query,
6471
getRootSymbol(resolver, KotlinSymbols.GraphQLMutation.canonicalName),
6572
getRootSymbol(resolver, KotlinSymbols.GraphQLSubscription.canonicalName),
73+
ignoreQuery != null
6674
)
6775
val definitions = result.definitions
6876

apollo-execution-processor/src/main/kotlin/com/apollographql/execution/processor/codegen/KotlinSymbols.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ internal object KotlinSymbols {
2121
val GraphQLQuery = ClassName(annotationPackageName, "GraphQLQuery")
2222
val GraphQLMutation = ClassName(annotationPackageName, "GraphQLMutation")
2323
val GraphQLSubscription = ClassName(annotationPackageName, "GraphQLSubscription")
24+
val GraphQLIgnore = ClassName(annotationPackageName, "GraphQLIgnore")
2425

2526
val AstDocument = ClassName(apolloAstPackageName, "GQLDocument")
2627
val AstScalarTypeDefinition = ClassName(apolloAstPackageName, "GQLScalarTypeDefinition")

apollo-execution-processor/src/main/kotlin/com/apollographql/execution/processor/definitions.kt

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.apollographql.execution.processor
22

33
import com.apollographql.apollo.ast.*
4+
import com.apollographql.execution.processor.codegen.KotlinSymbols.GraphQLIgnore
45
import com.apollographql.execution.processor.sir.*
56
import com.apollographql.execution.processor.sir.Instantiation
67
import com.apollographql.execution.processor.sir.SirArgumentDefinition
@@ -19,10 +20,7 @@ import com.apollographql.execution.processor.sir.SirObjectDefinition
1920
import com.apollographql.execution.processor.sir.SirType
2021
import com.apollographql.execution.processor.sir.SirTypeDefinition
2122
import com.apollographql.execution.processor.sir.SirUnionDefinition
22-
import com.google.devtools.ksp.getAllSuperTypes
23-
import com.google.devtools.ksp.getDeclaredProperties
24-
import com.google.devtools.ksp.isConstructor
25-
import com.google.devtools.ksp.isPublic
23+
import com.google.devtools.ksp.*
2624
import com.google.devtools.ksp.processing.KSPLogger
2725
import com.google.devtools.ksp.symbol.*
2826

@@ -36,12 +34,14 @@ internal fun doTraversal(
3634
query: KSClassDeclaration,
3735
mutation: KSClassDeclaration?,
3836
subscription: KSClassDeclaration?,
37+
hasIgnoreQuery: Boolean
3938
): TraversalResults {
40-
return TypeDefinitionContext(logger).walk(query, mutation, subscription)
39+
return TypeDefinitionContext(logger, hasIgnoreQuery).walk(query, mutation, subscription)
4140
}
4241

4342
private class TypeDefinitionContext(
4443
val logger: KSPLogger,
44+
val hasIgnoreQuery: Boolean
4545
) {
4646
/**
4747
* key is qualifiedName
@@ -172,11 +172,6 @@ private class TypeDefinitionContext(
172172
}
173173
usedTypeNames.add(name)
174174

175-
if (declaration.typeParameters.isNotEmpty()) {
176-
logger.error("Generic classes are not supported")
177-
return null
178-
}
179-
180175
if (declaration is KSTypeAlias) {
181176
return declaration.toSirScalarDefinition(qualifiedName)
182177
}
@@ -378,7 +373,6 @@ private class TypeDefinitionContext(
378373
logger.error("Cannot map to a GraphQL output type", this)
379374
return null
380375
}
381-
382376
val usedNames = mutableSetOf<String>()
383377
val allFields = declarations.filter { it.isPublic() }.mapNotNull {
384378
val name = it.graphqlName()
@@ -434,8 +428,12 @@ private class TypeDefinitionContext(
434428
}
435429

436430
ClassKind.INTERFACE -> {
437-
if (!modifiers.contains(Modifier.SEALED)) {
438-
logger.error("Interfaces and unions must be sealed interfaces", this)
431+
val isIgnored = hasIgnoreQuery
432+
if (!modifiers.contains(Modifier.SEALED) || !isIgnored) {
433+
logger.error(
434+
"Interfaces and unions must be sealed interfaces or you can use @GraphQLIgnore to ignore the interface generation $isIgnored",
435+
this
436+
)
439437
return null
440438
}
441439

@@ -503,10 +501,7 @@ private class TypeDefinitionContext(
503501
private fun KSClassDeclaration.interfaces(objectName: String?): List<String> {
504502
return getAllSuperTypes().mapNotNull {
505503
val declaration = it.declaration
506-
if (it.arguments.isNotEmpty()) {
507-
logger.error("Generic interfaces are not supported", this)
508-
null
509-
} else if (declaration is KSClassDeclaration) {
504+
if (declaration is KSClassDeclaration) {
510505
if (declaration.asClassName().asString() == "kotlin.Any") {
511506
// kotlin.Any is a super type of everything, just ignore it
512507
null
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.apollographql.execution.annotation
2+
3+
@Retention(AnnotationRetention.SOURCE)
4+
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
5+
annotation class GraphQLIgnore

tests/federation/src/main/kotlin/graphql.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import com.apollographql.execution.annotation.GraphQLQuery
2+
import com.apollographql.execution.annotation.GraphQLIgnore
23
import com.apollographql.execution.subgraph.GraphQLKey
34

5+
@GraphQLIgnore
6+
interface SomeGenericInterface<T>
7+
48
@GraphQLQuery
5-
class Query {
9+
class Query : SomeGenericInterface<String>{
610
fun products(): List<Product> {
711
return products
812
}
13+
14+
@GraphQLIgnore
15+
fun internalFields(): Int = 1
916
}
1017

1118
class Product(
@@ -23,4 +30,4 @@ class Product(
2330
val products = listOf(
2431
Product("1", "foo"),
2532
Product("2", "bar")
26-
)
33+
)

0 commit comments

Comments
 (0)