Skip to content

Commit

Permalink
Merge pull request #424 from yonatang/generated-annotation
Browse files Browse the repository at this point in the history
Adding option to create @generated annotation on generated code
  • Loading branch information
srinivasankavitha authored Jul 20, 2022
2 parents 0c9f695 + cb029db commit 278b1da
Show file tree
Hide file tree
Showing 25 changed files with 222 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ data class CodeGenConfig(
val snakeCaseConstantNames: Boolean = false,
val generateInterfaceSetters: Boolean = true,
var javaGenerateAllConstructor: Boolean = true,
val implementSerializable: Boolean = false
val implementSerializable: Boolean = false,
val addGeneratedAnnotation: Boolean = false
) {
val packageNameClient: String = "$packageName.$subPackageNameClient"

Expand All @@ -437,6 +438,7 @@ data class CodeGenConfig(
${if (skipEntityQueries) "--skip-entities" else ""}
${typeMapping.map { "--type-mapping ${it.key}=${it.value}" }.joinToString("\n")}
${if (shortProjectionNames) "--short-projection-names" else ""}
${if (addGeneratedAnnotation) "--add-generated-annotation" else ""}
${schemas.joinToString(" ")}
""".trimIndent()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
private fun createQueryClass(it: FieldDefinition, operation: String, methodNames: MutableSet<String>): JavaFile {
val methodName = generateMethodName(it.name.capitalized(), operation.lowercase(), methodNames)
val javaType = TypeSpec.classBuilder(methodName)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC).superclass(ClassName.get(GraphQLQuery::class.java))

if (it.description != null) {
Expand All @@ -101,6 +102,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
val setOfStringType = ParameterizedTypeName.get(setType, ClassName.get(String::class.java))

val builderClass = TypeSpec.classBuilder("Builder").addModifiers(Modifier.STATIC, Modifier.PUBLIC)
.addOptionalGeneratedAnnotation(config)
.addMethod(
MethodSpec.methodBuilder("build")
.addModifiers(Modifier.PUBLIC)
Expand Down Expand Up @@ -213,6 +215,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
private fun createRootProjection(type: TypeDefinition<*>, prefix: String): CodeGenResult {
val clazzName = "${prefix}ProjectionRoot"
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC).superclass(ClassName.get(BaseProjectionNode::class.java))

if (generatedClasses.contains(clazzName)) return CodeGenResult() else generatedClasses.add(clazzName)
Expand Down Expand Up @@ -318,6 +321,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
private fun createEntitiesRootProjection(federatedTypes: List<ObjectTypeDefinition>): CodeGenResult {
val clazzName = "EntitiesProjectionRoot"
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC).superclass(ClassName.get(BaseProjectionNode::class.java))

if (generatedClasses.contains(clazzName)) return CodeGenResult() else generatedClasses.add(clazzName)
Expand Down Expand Up @@ -446,6 +450,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
val clazzName = "${prefix}Projection"
if (generatedClasses.contains(clazzName)) return null else generatedClasses.add(clazzName)
val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)
.superclass(ParameterizedTypeName.get(className, ClassName.get(getPackageName(), parent.name), ClassName.get(getPackageName(), root.name)))
.addMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import javax.lang.model.element.Modifier
class ConstantsGenerator(private val config: CodeGenConfig, private val document: Document) {
fun generate(): CodeGenResult {
val javaType = TypeSpec.classBuilder("DgsConstants")
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)

document.definitions.filterIsInstance<ObjectTypeDefinition>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ abstract class BaseDataTypeGenerator(
description: Description? = null
): CodeGenResult {
val javaType = TypeSpec.classBuilder(name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)

if (config.implementSerializable) {
Expand Down Expand Up @@ -215,6 +216,7 @@ abstract class BaseDataTypeGenerator(

internal fun generateInterface(name: String, superInterfaces: List<Type<*>>, fields: List<Field>): CodeGenResult {
val javaType = TypeSpec.interfaceBuilder(name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)

superInterfaces.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class DatafetcherGenerator(private val config: CodeGenConfig, private val docume
.addStatement("return $returnValue")

val javaType = TypeSpec.classBuilder(clazzName)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)
.addAnnotation(DgsComponent::class.java)
.addMethod(methodSpec.build())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class EnumTypeGenerator(private val config: CodeGenConfig) {
TypeSpec
.enumBuilder(definition.name)
.addModifiers(Modifier.PUBLIC)
.addOptionalGeneratedAnnotation(config)

if (definition.description != null) {
javaType.addJavadoc(definition.description.sanitizeJavaDoc())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class InterfaceGenerator(private val config: CodeGenConfig, private val document

logger.info("Generating type ${definition.name}")
val javaType = TypeSpec.interfaceBuilder(definition.name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)

if (definition.description != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ package com.netflix.graphql.dgs.codegen.generators.java

import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.netflix.graphql.dgs.codegen.CodeGen
import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.generators.shared.generatedAnnotationClassName
import com.netflix.graphql.dgs.codegen.generators.shared.generatedDate
import com.squareup.javapoet.AnnotationSpec
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.TypeName
import com.squareup.javapoet.TypeSpec
import com.squareup.javapoet.WildcardTypeName
import graphql.introspection.Introspection.TypeNameMetaFieldDef
import graphql.language.Description
Expand Down Expand Up @@ -121,6 +126,24 @@ fun String.toTypeName(isGenericParam: Boolean = false): TypeName {
}
}

@Suppress("DuplicatedCode") // not duplicated - this is JavaPoet, the other is KotlinPoet
private fun generatedAnnotation(): AnnotationSpec? {
val generatedAnnotation = generatedAnnotationClassName
?.let { ClassName.bestGuess(it) }
?: return null
return AnnotationSpec.builder(generatedAnnotation)
.addMember("value", "${'$'}S", CodeGen::class.qualifiedName!!)
.addMember("date", "${'$'}S", generatedDate)
.build()
}

fun TypeSpec.Builder.addOptionalGeneratedAnnotation(config: CodeGenConfig): TypeSpec.Builder =
apply {
if (config.addGeneratedAnnotation) {
generatedAnnotation()?.also { it -> addAnnotation(it) }
}
}

private fun typeClassBestGuess(name: String): TypeName {
return when (name) {
"String" -> ClassName.get("java.lang", "String")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class UnionTypeGenerator(private val config: CodeGenConfig) {
}

val javaType = TypeSpec.interfaceBuilder(definition.name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(Modifier.PUBLIC)

val memberTypes = definition.memberTypes.plus(extensions.flatMap { it.memberTypes }).asSequence()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import graphql.language.*
class KotlinConstantsGenerator(private val config: CodeGenConfig, private val document: Document) {
fun generate(): CodeGenResult {
val baseConstantsType = TypeSpec.objectBuilder("DgsConstants")
.addOptionalGeneratedAnnotation(config)

document.definitions.filterIsInstance<ObjectTypeDefinition>()
.excludeSchemaTypeExtension()
Expand Down Expand Up @@ -121,6 +122,7 @@ class KotlinConstantsGenerator(private val config: CodeGenConfig, private val do
}

return TypeSpec.objectBuilder(className)
.addOptionalGeneratedAnnotation(config)
}

private fun addFieldName(constantsType: TypeSpec.Builder, name: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ abstract class AbstractKotlinDataTypeGenerator(
description: Description? = null
): CodeGenResult {
val kotlinType = TypeSpec.classBuilder(name)
.addOptionalGeneratedAnnotation(config)

if (config.implementSerializable) {
kotlinType.addSuperinterface(ClassName.bestGuess(Serializable::class.java.name))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class KotlinEnumTypeGenerator(private val config: CodeGenConfig) {

logger.info("Generating enum type ${definition.name}")

val kotlinType = TypeSpec.classBuilder(definition.name).addModifiers(KModifier.ENUM)
val kotlinType = TypeSpec.classBuilder(definition.name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(KModifier.ENUM)

if (definition.description != null) {
kotlinType.addKdoc("%L", definition.description.sanitizeKdoc())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class KotlinInterfaceTypeGenerator(private val config: CodeGenConfig, private va
logger.info("Generating type {}", definition.name)

val interfaceBuilder = TypeSpec.interfaceBuilder(definition.name)
.addOptionalGeneratedAnnotation(config)
if (definition.description != null) {
interfaceBuilder.addKdoc("%L", definition.description.sanitizeKdoc())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder
import com.netflix.graphql.dgs.codegen.CodeGen
import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.generators.shared.generatedAnnotationClassName
import com.netflix.graphql.dgs.codegen.generators.shared.generatedDate
import com.squareup.kotlinpoet.*
import graphql.introspection.Introspection
import graphql.language.Description
Expand Down Expand Up @@ -125,6 +129,18 @@ fun jsonBuilderAnnotation(): AnnotationSpec {
.build()
}

@Suppress("DuplicatedCode") // not duplicated - this is KotlinPoet, the other is JavaPoet
private fun generatedAnnotation(): AnnotationSpec? {
val generatedAnnotation = generatedAnnotationClassName
?.let { ClassName.bestGuess(it) }
?: return null

return AnnotationSpec.builder(generatedAnnotation)
.addMember("value = [%S]", CodeGen::class.qualifiedName!!)
.addMember("date = %S", generatedDate)
.build()
}

/**
* Generate a [JsonProperty] annotation for the supplied
* field name.
Expand Down Expand Up @@ -218,3 +234,10 @@ fun FunSpec.Builder.addControlFlow(
fun TypeSpec.Builder.addEnumConstants(enumSpecs: Iterable<TypeSpec>): TypeSpec.Builder = apply {
enumSpecs.map { addEnumConstant(it.name!!, it) }
}

fun TypeSpec.Builder.addOptionalGeneratedAnnotation(config: CodeGenConfig): TypeSpec.Builder =
apply {
if (config.addGeneratedAnnotation) {
generatedAnnotation()?.also { addAnnotation(it) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class KotlinUnionTypeGenerator(private val config: CodeGenConfig) {
}

val interfaceBuilder = TypeSpec.interfaceBuilder(definition.name)
.addOptionalGeneratedAnnotation(config)

val memberTypes = definition.memberTypes.plus(extensions.flatMap { it.memberTypes }).asSequence()
.filterIsInstance<TypeName>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.GraphQLProjection
import com.netflix.graphql.dgs.codegen.filterSkipped
import com.netflix.graphql.dgs.codegen.generators.kotlin.ReservedKeywordFilter
import com.netflix.graphql.dgs.codegen.generators.kotlin.addOptionalGeneratedAnnotation
import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils
import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension
import com.netflix.graphql.dgs.codegen.shouldSkip
Expand Down Expand Up @@ -135,6 +136,7 @@ fun generateKotlin2ClientTypes(

// create the projection class
val typeSpec = TypeSpec.classBuilder(typeName)
.addOptionalGeneratedAnnotation(config)
.superclass(GraphQLProjection::class)
// we can't ask for `__typename` on a `Subscription` object
.apply {
Expand Down Expand Up @@ -167,6 +169,7 @@ fun generateKotlin2ClientTypes(
.plus(extensionTypes.flatMap { it.memberTypes })

val typeSpec = TypeSpec.classBuilder(typeName)
.addOptionalGeneratedAnnotation(config)
.superclass(GraphQLProjection::class)
.addFunctions(
implementations.map { subclass ->
Expand All @@ -183,6 +186,7 @@ fun generateKotlin2ClientTypes(
val topLevelTypes = typeLookup.operations.filterKeys { typeLookup.objectTypeNames.contains(it) }

val clientSpec = TypeSpec.objectBuilder("DgsClient")
.addOptionalGeneratedAnnotation(config)
.addFunctions(
topLevelTypes.map { (type, op) ->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.filterSkipped
import com.netflix.graphql.dgs.codegen.generators.kotlin.ReservedKeywordFilter
import com.netflix.graphql.dgs.codegen.generators.kotlin.addControlFlow
import com.netflix.graphql.dgs.codegen.generators.kotlin.addOptionalGeneratedAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.disableJsonTypeInfoAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonBuilderAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonDeserializeAnnotation
Expand Down Expand Up @@ -112,6 +113,7 @@ fun generateKotlin2DataTypes(
// create a builder for this class; default to lambda that throws if accessed
val builderClassName = ClassName(config.packageNameTypes, typeDefinition.name, "Builder")
val builder = TypeSpec.classBuilder("Builder")
.addOptionalGeneratedAnnotation(config)
.addAnnotation(jsonBuilderAnnotation())
.addAnnotation(jsonIgnorePropertiesAnnotation("__typename"))
// add a backing property for each field
Expand Down Expand Up @@ -150,6 +152,7 @@ fun generateKotlin2DataTypes(

// create the data class
val typeSpec = TypeSpec.classBuilder(typeDefinition.name)
.addOptionalGeneratedAnnotation(config)
// add docs if available
.apply {
if (typeDefinition.description != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package com.netflix.graphql.dgs.codegen.generators.kotlin2

import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.generators.kotlin.addEnumConstants
import com.netflix.graphql.dgs.codegen.generators.kotlin.addOptionalGeneratedAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc
import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findEnumExtensions
import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension
Expand Down Expand Up @@ -54,6 +55,7 @@ fun generateKotlin2EnumTypes(

// create the enum class
val enumSpec = TypeSpec.classBuilder(enumDefinition.name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(KModifier.ENUM)
// add docs if available
.apply {
Expand All @@ -65,6 +67,7 @@ fun generateKotlin2EnumTypes(
.addEnumConstants(
fields.map { field ->
TypeSpec.enumBuilder(field.name)
.addOptionalGeneratedAnnotation(config)
.apply {
if (field.description != null) {
addKdoc("%L", field.description.sanitizeKdoc())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package com.netflix.graphql.dgs.codegen.generators.kotlin2
import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.GraphQLInput
import com.netflix.graphql.dgs.codegen.generators.kotlin.ReservedKeywordFilter
import com.netflix.graphql.dgs.codegen.generators.kotlin.addOptionalGeneratedAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc
import com.netflix.graphql.dgs.codegen.generators.shared.SchemaExtensionsUtils.findInputExtensions
import com.netflix.graphql.dgs.codegen.generators.shared.excludeSchemaTypeExtension
Expand Down Expand Up @@ -69,6 +70,7 @@ fun generateKotlin2InputTypes(

// create the input class
val typeSpec = TypeSpec.classBuilder(typeName)
.addOptionalGeneratedAnnotation(config)
// add docs if available
.apply {
if (inputDefinition.description != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package com.netflix.graphql.dgs.codegen.generators.kotlin2

import com.netflix.graphql.dgs.codegen.CodeGenConfig
import com.netflix.graphql.dgs.codegen.filterSkipped
import com.netflix.graphql.dgs.codegen.generators.kotlin.addOptionalGeneratedAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonSubTypesAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.jsonTypeInfoAnnotation
import com.netflix.graphql.dgs.codegen.generators.kotlin.sanitizeKdoc
Expand Down Expand Up @@ -80,6 +81,7 @@ fun generateKotlin2Interfaces(

// create the interface
val interfaceSpec = TypeSpec.interfaceBuilder(interfaceDefinition.name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(KModifier.SEALED)
// add docs if available
.apply {
Expand Down Expand Up @@ -142,6 +144,7 @@ fun generateKotlin2Interfaces(

// create the interface
val interfaceSpec = TypeSpec.interfaceBuilder(unionDefinition.name)
.addOptionalGeneratedAnnotation(config)
.addModifiers(KModifier.SEALED)
// add docs if available
.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.netflix.graphql.dgs.codegen.generators.kotlin2.logger
import graphql.language.Document
import graphql.language.ScalarTypeDefinition
import graphql.language.StringValue
import java.time.Instant

internal sealed class GenericSymbol(open val index: Int) {
class OpenBracket(str: String, startFrom: Int = 0) : GenericSymbol(str.indexOf("<", startFrom))
Expand Down Expand Up @@ -155,3 +156,12 @@ internal fun findSchemaTypeMapping(document: Document, typeName: String): String
}
return null
}

internal val generatedAnnotationClassName: String? = runCatching {
Class.forName("javax.annotation.processing.Generated").canonicalName
}.getOrElse {
runCatching {
Class.forName("javax.annotation.Generated").canonicalName
}.getOrNull()
}
internal val generatedDate: String = Instant.now().toString()
Loading

0 comments on commit 278b1da

Please sign in to comment.