From 9ce4569564c689e3f63e5f2eed4d441504c20496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E5=A2=83=E8=BF=B7=E7=A6=BB?= <568845948@qq.com> Date: Tue, 29 Dec 2020 11:42:04 +0800 Subject: [PATCH] Support message for deprecated directive (#471) --- .../codegen/java/JavaGraphQLTypeMapper.java | 28 ++++++++++ .../EnumDefinitionToDataModelMapper.java | 10 ++-- .../FieldDefinitionToParameterMapper.java | 4 +- ...dDefinitionsToResolverDataModelMapper.java | 4 +- .../codegen/mapper/GraphQLTypeMapper.java | 31 +++++------ ...InputValueDefinitionToParameterMapper.java | 2 +- ...stResponseDefinitionToDataModelMapper.java | 2 +- .../codegen/model/DeprecatedDefinition.java | 39 +++++++++++++ .../codegen/model/EnumValueDefinition.java | 6 +- .../graphql/codegen/model/MappingContext.java | 2 +- .../model/MultiLanguageDeprecated.java | 33 +++++++++++ .../codegen/model/OperationDefinition.java | 6 +- .../codegen/model/ParameterDefinition.java | 10 ++-- .../model/ProjectionParameterDefinition.java | 6 +- .../definitions/ExtendedFieldDefinition.java | 15 +++-- .../java-lang/javaClassGraphqlEnum.ftl | 4 +- .../java-lang/javaClassGraphqlInterface.ftl | 4 +- .../java-lang/javaClassGraphqlOperations.ftl | 4 +- .../javaClassGraphqlParametrizedInput.ftl | 8 +-- .../java-lang/javaClassGraphqlRequest.ftl | 8 +-- .../java-lang/javaClassGraphqlResponse.ftl | 4 +- .../javaClassGraphqlResponseProjection.ftl | 4 +- .../java-lang/javaClassGraphqlType.ftl | 16 +++--- .../kotlin-lang/kotlinClassGraphqlEnum.ftl | 4 +- .../kotlinClassGraphqlInterface.ftl | 6 +- .../kotlinClassGraphqlOperations.ftl | 4 +- .../kotlinClassGraphqlParametrizedInput.ftl | 4 +- .../kotlin-lang/kotlinClassGraphqlRequest.ftl | 10 ++-- .../kotlinClassGraphqlResponse.ftl | 4 +- .../kotlinClassGraphqlResponseProjection.ftl | 4 +- .../kotlin-lang/kotlinClassGraphqlType.ftl | 8 +-- .../scala-lang/scalaClassGraphqlEnum.ftl | 4 +- .../scala-lang/scalaClassGraphqlInterface.ftl | 4 +- .../scalaClassGraphqlOperations.ftl | 4 +- .../scalaClassGraphqlParametrizedInput.ftl | 4 +- .../scala-lang/scalaClassGraphqlRequest.ftl | 8 +-- .../scala-lang/scalaClassGraphqlResponse.ftl | 4 +- .../scalaClassGraphqlResponseProjection.ftl | 4 +- .../scala-lang/scalaClassGraphqlType.ftl | 8 +-- .../kotlin/GraphQLCodegenDeprecatedTest.java | 55 +++++++++++++++++++ .../scala/GraphQLCodegenDeprecatedTest.java | 55 +++++++++++++++++++ .../CreateEventMutationResolver.kt.txt | 14 +++++ .../kt/deprecated/Event.kt.txt | 18 ++++++ .../kt/deprecated/EventInput.kt.txt | 13 +++++ .../kt/deprecated/EventsQueryResolver.kt.txt | 14 +++++ .../kt/deprecated/MutationResolver.kt.txt | 14 +++++ .../kt/deprecated/Node.kt.txt | 13 +++++ .../kt/deprecated/PinnableItem.kt.txt | 10 ++++ .../kt/deprecated/QueryResolver.kt.txt | 14 +++++ .../kt/deprecated/Status.kt.txt | 12 ++++ .../kt/interfaces/BarBar.kt.txt | 2 +- .../kt/restricted-words/Super.kt.txt | 4 +- .../CreateEventMutationResolver.scala.txt | 15 +++++ .../scala/deprecated/Event.scala.txt | 22 ++++++++ .../scala/deprecated/EventInput.scala.txt | 16 ++++++ .../deprecated/EventsQueryResolver.scala.txt | 15 +++++ .../deprecated/MutationResolver.scala.txt | 15 +++++ .../scala/deprecated/Node.scala.txt | 14 +++++ .../scala/deprecated/PinnableItem.scala.txt | 10 ++++ .../scala/deprecated/QueryResolver.scala.txt | 15 +++++ .../scala/deprecated/Status.scala.txt | 15 +++++ .../schemas/deprecated-with-msg.graphqls | 37 +++++++++++++ 62 files changed, 626 insertions(+), 120 deletions(-) create mode 100644 src/main/java/com/kobylynskyi/graphql/codegen/model/DeprecatedDefinition.java create mode 100644 src/main/java/com/kobylynskyi/graphql/codegen/model/MultiLanguageDeprecated.java create mode 100644 src/test/java/com/kobylynskyi/graphql/codegen/kotlin/GraphQLCodegenDeprecatedTest.java create mode 100644 src/test/java/com/kobylynskyi/graphql/codegen/scala/GraphQLCodegenDeprecatedTest.java create mode 100644 src/test/resources/expected-classes/kt/deprecated/CreateEventMutationResolver.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/Event.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/EventInput.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/EventsQueryResolver.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/MutationResolver.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/Node.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/PinnableItem.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/QueryResolver.kt.txt create mode 100644 src/test/resources/expected-classes/kt/deprecated/Status.kt.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/CreateEventMutationResolver.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/Event.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/EventInput.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/EventsQueryResolver.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/MutationResolver.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/Node.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/PinnableItem.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/QueryResolver.scala.txt create mode 100644 src/test/resources/expected-classes/scala/deprecated/Status.scala.txt create mode 100644 src/test/resources/schemas/deprecated-with-msg.graphqls diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java index 00dfeb301..e4bea7083 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java @@ -1,5 +1,6 @@ package com.kobylynskyi.graphql.codegen.java; +import com.kobylynskyi.graphql.codegen.mapper.DataModelMapper; import com.kobylynskyi.graphql.codegen.mapper.GraphQLTypeMapper; import com.kobylynskyi.graphql.codegen.mapper.ValueMapper; import com.kobylynskyi.graphql.codegen.model.MappingContext; @@ -9,6 +10,7 @@ import graphql.language.Argument; import java.util.HashSet; +import java.util.Map; import java.util.Set; import static java.util.Arrays.asList; @@ -87,4 +89,30 @@ public String mapDirectiveArgumentValue(MappingContext mappingContext, Argument return valueMapper.map(mappingContext, dirArg.getValue(), null, argumentValueFormatter); } + @Override + public NamedDefinition getLanguageType(MappingContext mappingContext, String graphQLType, String name, + String parentTypeName, boolean mandatory, boolean collection) { + Map customTypesMapping = mappingContext.getCustomTypesMapping(); + Set serializeFieldsUsingObjectMapper = mappingContext.getUseObjectMapperForRequestSerialization(); + String langTypeName; + boolean primitiveCanBeUsed = !collection; + boolean serializeUsingObjectMapper = false; + if (name != null && parentTypeName != null && customTypesMapping.containsKey(parentTypeName + "." + name)) { + langTypeName = customTypesMapping.get(parentTypeName + "." + name); + primitiveCanBeUsed = false; + } else if (customTypesMapping.containsKey(graphQLType)) { + langTypeName = customTypesMapping.get(graphQLType); + } else { + langTypeName = DataModelMapper.getModelClassNameWithPrefixAndSuffix(mappingContext, graphQLType); + } + if (serializeFieldsUsingObjectMapper.contains(graphQLType) || + (name != null && parentTypeName != null && + serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name))) { + serializeUsingObjectMapper = true; + } + + return new NamedDefinition(langTypeName, graphQLType, mappingContext.getInterfacesName().contains(graphQLType), + mandatory, primitiveCanBeUsed, serializeUsingObjectMapper); + } + } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/EnumDefinitionToDataModelMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/EnumDefinitionToDataModelMapper.java index d2ddf0d9a..8fc1a0987 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/EnumDefinitionToDataModelMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/EnumDefinitionToDataModelMapper.java @@ -1,12 +1,12 @@ package com.kobylynskyi.graphql.codegen.mapper; +import com.kobylynskyi.graphql.codegen.model.DeprecatedDefinition; import com.kobylynskyi.graphql.codegen.model.EnumValueDefinition; import com.kobylynskyi.graphql.codegen.model.MappingContext; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedEnumTypeDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedUnionTypeDefinition; import com.kobylynskyi.graphql.codegen.utils.Utils; import graphql.language.Comment; -import graphql.language.Directive; import graphql.language.DirectivesContainer; import java.util.Collections; @@ -50,10 +50,8 @@ private static Set getUnionInterfaces(MappingContext mappingContext, .collect(Collectors.toSet()); } - private static boolean isDeprecated(DirectivesContainer directivesContainer) { - return directivesContainer.getDirectives().stream() - .map(Directive::getName) - .anyMatch(Deprecated.class.getSimpleName()::equalsIgnoreCase); + public DeprecatedDefinition getDeprecated(MappingContext mappingContext, DirectivesContainer directivesContainer) { + return graphQLTypeMapper.getDeprecated(mappingContext, directivesContainer); } private static List getJavaDoc(graphql.language.EnumValueDefinition def) { @@ -101,7 +99,7 @@ private List map(MappingContext mappingContext, List getOperationParameters(MappingContext mappingC if (!Utils.isGraphqlOperation(parentTypeName)) { String parentObjectParamType = graphQLTypeMapper.getLanguageType(mappingContext, new TypeName(parentTypeName)); String parentObjectParamName = dataModelMapper.capitalizeIfRestricted(mappingContext, Utils.uncapitalize(parentObjectParamType)); - parameters.add(new ParameterDefinition(parentObjectParamType, parentObjectParamName, parentObjectParamName, null, emptyList(), emptyList(), resolvedField.isDeprecated(), false)); + parameters.add(new ParameterDefinition(parentObjectParamType, parentObjectParamName, parentObjectParamName, null, emptyList(), emptyList(), resolvedField.getDeprecated(mappingContext), false)); } // 2. Next parameters are input values diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java index 0fc8ff63b..3a8289fd3 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java @@ -1,24 +1,14 @@ package com.kobylynskyi.graphql.codegen.mapper; -import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage; +import com.kobylynskyi.graphql.codegen.model.DeprecatedDefinition; import com.kobylynskyi.graphql.codegen.model.MappingContext; +import com.kobylynskyi.graphql.codegen.model.MultiLanguageDeprecated; import com.kobylynskyi.graphql.codegen.model.NamedDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDefinition; import com.kobylynskyi.graphql.codegen.utils.Utils; -import graphql.language.Argument; -import graphql.language.Directive; -import graphql.language.DirectivesContainer; -import graphql.language.ListType; -import graphql.language.NamedNode; -import graphql.language.NonNullType; -import graphql.language.Type; -import graphql.language.TypeName; +import graphql.language.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * Map GraphQL type to language-specific type (java/scala/kotlin/etc) @@ -213,9 +203,7 @@ default NamedDefinition getLanguageType(MappingContext mappingContext, String gr if (name != null && parentTypeName != null && customTypesMapping.containsKey(parentTypeName + "." + name)) { langTypeName = customTypesMapping.get(parentTypeName + "." + name); primitiveCanBeUsed = false; - } else if (mandatory && customTypesMapping.containsKey(getMandatoryType(graphQLType)) && - !mappingContext.getGeneratedLanguage().equals(GeneratedLanguage.JAVA)){ - //Java primitive types can't be used as generic parameters this, but Scala/Kotlin can + } else if (mandatory && customTypesMapping.containsKey(getMandatoryType(graphQLType))) { langTypeName = customTypesMapping.get(getMandatoryType(graphQLType)); } else if (customTypesMapping.containsKey(graphQLType)) { langTypeName = customTypesMapping.get(graphQLType); @@ -330,5 +318,14 @@ default String getTypeConsideringPrimitive(MappingContext mappingContext, return computedTypeName; } + default DeprecatedDefinition getDeprecated(MappingContext mappingContext, DirectivesContainer directivesContainer) { + return directivesContainer.getDirectives() + .stream() + .filter(d -> d.getName().equalsIgnoreCase(Deprecated.class.getSimpleName())) + .findFirst() + .map(directive -> MultiLanguageDeprecated.getLanguageDeprecated(mappingContext.getGeneratedLanguage(), directive)) + .orElse(null); + } + } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index 129d7f0f5..68d876f96 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -67,7 +67,7 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit parameter.setType(graphQLTypeMapper.getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName())); parameter.setDefaultValue(valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType())); parameter.setAnnotations(graphQLTypeMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), inputValueDefinition, parentTypeName, false)); - parameter.setDeprecated(isDeprecated(inputValueDefinition)); + parameter.setDeprecated(graphQLTypeMapper.getDeprecated(mappingContext, inputValueDefinition)); parameter.setSerializeUsingObjectMapper(namedDefinition.isSerializeUsingObjectMapper()); return parameter; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/RequestResponseDefinitionToDataModelMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/RequestResponseDefinitionToDataModelMapper.java index 9eea97d7b..4454b8b03 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/RequestResponseDefinitionToDataModelMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/RequestResponseDefinitionToDataModelMapper.java @@ -191,7 +191,7 @@ public Map mapResponse(MappingContext mappingContext, dataModel.put(ANNOTATIONS, graphQLTypeMapper.getAnnotations(mappingContext, className)); dataModel.put(CLASS_NAME, className); dataModel.put(JAVA_DOC, operationDef.getJavaDoc()); - dataModel.put(DEPRECATED, operationDef.isDeprecated()); + dataModel.put(DEPRECATED, operationDef.getDeprecated(mappingContext)); dataModel.put(OPERATION_NAME, operationDef.getName()); dataModel.put(METHOD_NAME, dataModelMapper.capitalizeMethodNameIfRestricted(mappingContext, operationDef.getName())); dataModel.put(RETURN_TYPE_NAME, javaType); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/DeprecatedDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/DeprecatedDefinition.java new file mode 100644 index 000000000..bc18546f9 --- /dev/null +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/DeprecatedDefinition.java @@ -0,0 +1,39 @@ +package com.kobylynskyi.graphql.codegen.model; + +/** + * @author 梦境迷离 + * @version 1.0, 2020/12/28 + */ +public class DeprecatedDefinition { + + private final static String DEFAULT_MSG = "No longer supported"; + + // For different languages, real implementation. + private final String annotation; + private final String reason; + + public DeprecatedDefinition(String annotation) { + this.annotation = annotation; + this.reason = DEFAULT_MSG; + } + + /** + * field reason Only support in Scala/Kotlin. + * + * @param annotation Definitions in different languages + * @param reason Description in graphql schema Directive + */ + public DeprecatedDefinition(String annotation, String reason) { + this.annotation = annotation; + this.reason = reason == null ? DEFAULT_MSG : reason; + } + + public String getAnnotation() { + return annotation; + } + + public String getReason() { + return reason; + } + +} diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/EnumValueDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/EnumValueDefinition.java index 8fa213999..7eb9eb48d 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/EnumValueDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/EnumValueDefinition.java @@ -12,9 +12,9 @@ public class EnumValueDefinition { private final String javaName; private final String graphqlName; private final List javaDoc; - private final boolean deprecated; + private final DeprecatedDefinition deprecated; - public EnumValueDefinition(String javaName, String graphqlName, List javaDoc, boolean deprecated) { + public EnumValueDefinition(String javaName, String graphqlName, List javaDoc, DeprecatedDefinition deprecated) { this.javaName = javaName; this.graphqlName = graphqlName; this.javaDoc = javaDoc; @@ -33,7 +33,7 @@ public List getJavaDoc() { return javaDoc; } - public boolean isDeprecated() { + public DeprecatedDefinition getDeprecated() { return deprecated; } } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java index 3dcff65d6..b18596eda 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java @@ -282,7 +282,7 @@ public GeneratedInformation getGeneratedInformation() { public Set getEnumImportItSelfInScala() { // Only for scala if (GeneratedLanguage.SCALA.equals(this.config.getGeneratedLanguage()) && enumImportItSelfInScala == null) { - enumImportItSelfInScala = this.document.getEnumDefinitions().parallelStream().map(this::getModelClassNameWithPrefixAndSuffix).collect(Collectors.toSet()); + enumImportItSelfInScala = this.document.getEnumDefinitions().stream().map(this::getModelClassNameWithPrefixAndSuffix).collect(Collectors.toSet()); } return enumImportItSelfInScala; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MultiLanguageDeprecated.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MultiLanguageDeprecated.java new file mode 100644 index 000000000..1f0a896d5 --- /dev/null +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MultiLanguageDeprecated.java @@ -0,0 +1,33 @@ +package com.kobylynskyi.graphql.codegen.model; + +import graphql.language.Directive; +import graphql.language.StringValue; + +/** + * @author liguobin@growingio.com + * @version 1.0, 2020/12/28 + */ +public class MultiLanguageDeprecated { + + private final static String REASON = "reason"; + private final static String SCALA_ANNOTATION = "deprecated"; + private final static String JAVA_ANNOTATION = "Deprecated"; + private final static String KOTLIN_ANNOTATION = "Deprecated"; + + public static DeprecatedDefinition getLanguageDeprecated(GeneratedLanguage generatedLanguage, Directive directive) { + String msg = null; + if (directive.getArguments().stream().anyMatch(argument -> argument.getName().equals(REASON))) { + msg = ((StringValue) directive.getArgument(REASON).getValue()).getValue(); + } + switch (generatedLanguage) { + case KOTLIN: + return new DeprecatedDefinition(KOTLIN_ANNOTATION, msg); + case SCALA: + return new DeprecatedDefinition(SCALA_ANNOTATION, msg); + //ignore msg + case JAVA: + default: + return new DeprecatedDefinition(JAVA_ANNOTATION); + } + } +} diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/OperationDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/OperationDefinition.java index 7644276de..4db4df2fa 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/OperationDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/OperationDefinition.java @@ -24,7 +24,7 @@ public class OperationDefinition { private List annotations = new ArrayList<>(); private List parameters = new ArrayList<>(); private List javaDoc = new ArrayList<>(); - private boolean deprecated; + private DeprecatedDefinition deprecated; private boolean throwsException; public String getName() { @@ -75,11 +75,11 @@ public void setJavaDoc(List javaDoc) { this.javaDoc = javaDoc; } - public boolean isDeprecated() { + public DeprecatedDefinition getDeprecated() { return deprecated; } - public void setDeprecated(boolean deprecated) { + public void setDeprecated(DeprecatedDefinition deprecated) { this.deprecated = deprecated; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java index 768db2a35..62050705b 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java @@ -16,7 +16,7 @@ public class ParameterDefinition { public static final ParameterDefinition DATA_FETCHING_ENVIRONMENT = new ParameterDefinition( - DataFetchingEnvironment.class.getName(), "env", "env", null, emptyList(), emptyList(), false, false); + DataFetchingEnvironment.class.getName(), "env", "env", null, emptyList(), emptyList(), null, false); private String type; /** @@ -30,7 +30,7 @@ public class ParameterDefinition { private String defaultValue; private List annotations = new ArrayList<>(); private List javaDoc = new ArrayList<>(); - private boolean deprecated; + private DeprecatedDefinition deprecated; private boolean serializeUsingObjectMapper; public ParameterDefinition() { @@ -38,7 +38,7 @@ public ParameterDefinition() { public ParameterDefinition(String type, String name, String originalName, String defaultValue, List annotations, List javaDoc, - boolean deprecated, boolean serializeUsingObjectMapper) { + DeprecatedDefinition deprecated, boolean serializeUsingObjectMapper) { this.type = type; this.name = name; this.originalName = originalName; @@ -97,11 +97,11 @@ public void setJavaDoc(List javaDoc) { this.javaDoc = javaDoc; } - public boolean isDeprecated() { + public DeprecatedDefinition getDeprecated() { return deprecated; } - public void setDeprecated(boolean deprecated) { + public void setDeprecated(DeprecatedDefinition deprecated) { this.deprecated = deprecated; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/ProjectionParameterDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/ProjectionParameterDefinition.java index d74f70f0e..da6a53977 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/ProjectionParameterDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/ProjectionParameterDefinition.java @@ -10,7 +10,7 @@ public class ProjectionParameterDefinition { private String type; private String name; private String methodName; - private boolean deprecated; + private DeprecatedDefinition deprecated; private String parametrizedInputClassName; public String getType() { @@ -37,11 +37,11 @@ public void setMethodName(String methodName) { this.methodName = methodName; } - public boolean isDeprecated() { + public DeprecatedDefinition getDeprecated() { return deprecated; } - public void setDeprecated(boolean deprecated) { + public void setDeprecated(DeprecatedDefinition deprecated) { this.deprecated = deprecated; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedFieldDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedFieldDefinition.java index 429ba2c4d..cd83ea197 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedFieldDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedFieldDefinition.java @@ -1,9 +1,11 @@ package com.kobylynskyi.graphql.codegen.model.definitions; +import com.kobylynskyi.graphql.codegen.model.DeprecatedDefinition; +import com.kobylynskyi.graphql.codegen.model.MappingContext; +import com.kobylynskyi.graphql.codegen.model.MultiLanguageDeprecated; import com.kobylynskyi.graphql.codegen.utils.Utils; import graphql.language.Comment; import graphql.language.Description; -import graphql.language.Directive; import graphql.language.FieldDefinition; import java.util.Collections; @@ -24,10 +26,13 @@ protected ExtendedFieldDefinition(FieldDefinition f, boolean fromExtension) { this.fromExtension = fromExtension; } - public boolean isDeprecated() { - return getDirectives().stream() - .map(Directive::getName) - .anyMatch(Deprecated.class.getSimpleName()::equalsIgnoreCase); + public DeprecatedDefinition getDeprecated(MappingContext mappingContext) { + return getDirectives() + .stream() + .filter(d -> d.getName().equalsIgnoreCase(Deprecated.class.getSimpleName())) + .findFirst() + .map(directive -> MultiLanguageDeprecated.getLanguageDeprecated(mappingContext.getGeneratedLanguage(), directive)) + .orElse(null); } public List getJavaDoc() { diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlEnum.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlEnum.ftl index 2d13f6654..9c28deebb 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlEnum.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlEnum.ftl @@ -29,8 +29,8 @@ public enum ${className}<#if implements?has_content> implements <#list implement */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} ${field.javaName}("${field.graphqlName}")<#if field_has_next>,<#else>; diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlInterface.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlInterface.ftl index 9a0b5e5eb..0090b600d 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlInterface.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlInterface.ftl @@ -35,8 +35,8 @@ public interface ${className} <#if implements?has_content>extends <#list impleme */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} <#list field.annotations as annotation> @${annotation} diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlOperations.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlOperations.ftl index 7c105d8bb..08ede514d 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlOperations.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlOperations.ftl @@ -29,8 +29,8 @@ public interface ${className}<#if implements?has_content> extends <#list impleme */ -<#if operation.deprecated> - @Deprecated +<#if operation.deprecated?has_content> + @${operation.deprecated.annotation} <#list operation.annotations as annotation> @${annotation} diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlParametrizedInput.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlParametrizedInput.ftl index 21ba8cb40..77e456a60 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlParametrizedInput.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlParametrizedInput.ftl @@ -30,8 +30,8 @@ public class ${className} implements GraphQLParametrizedInput { <#if fields?has_content> <#list fields as field> -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} <#list field.annotations as annotation> @${annotation} @@ -60,8 +60,8 @@ public class ${className} implements GraphQLParametrizedInput { */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public ${className} ${field.name}(${field.type} ${field.name}) { this.${field.name} = ${field.name}; diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlRequest.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlRequest.ftl index 894375915..5f9a14350 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlRequest.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlRequest.ftl @@ -50,8 +50,8 @@ public class ${className} implements GraphQLOperationRequest { */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public void set${field.name?cap_first}(${field.type} ${field.name}) { this.input.put("${field.originalName}", ${field.name}); @@ -137,8 +137,8 @@ public class ${className} implements GraphQLOperationRequest { */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public Builder set${field.name?cap_first}(${field.type} ${field.name}) { this.${field.name} = ${field.name}; diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlResponse.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlResponse.ftl index 3cd222da9..ce9308b41 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlResponse.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlResponse.ftl @@ -35,8 +35,8 @@ public class ${className} extends GraphQLResult> */ -<#if deprecated> - @Deprecated +<#if deprecated?has_content> + @${deprecated.annotation} public ${returnTypeName} ${methodName}() { Map data = getData(); diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlResponseProjection.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlResponseProjection.ftl index 246e62c87..5282e8cd8 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlResponseProjection.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlResponseProjection.ftl @@ -62,8 +62,8 @@ public class ${className} extends GraphQLResponseProjection { */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public ${className} ${field.methodName}(<#if field.type?has_content>${field.type} subProjection) { return ${field.methodName}(<#if field.parametrizedInputClassName?has_content>(String)null<#if field.type?has_content>, subProjection); diff --git a/src/main/resources/templates/java-lang/javaClassGraphqlType.ftl b/src/main/resources/templates/java-lang/javaClassGraphqlType.ftl index 037d1c696..f4016bdf5 100644 --- a/src/main/resources/templates/java-lang/javaClassGraphqlType.ftl +++ b/src/main/resources/templates/java-lang/javaClassGraphqlType.ftl @@ -38,8 +38,8 @@ public class ${className} implements java.io.Serializable<#if implements?has_con <#if fields?has_content> <#list fields as field> -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} <#list field.annotations as annotation> @${annotation} @@ -68,8 +68,8 @@ public class ${className} implements java.io.Serializable<#if implements?has_con */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public ${field.type} get${field.name?cap_first}() { return ${field.name}; @@ -82,8 +82,8 @@ public class ${className} implements java.io.Serializable<#if implements?has_con */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public void set${field.name?cap_first}(${field.type} ${field.name}) { this.${field.name} = ${field.name}; @@ -176,8 +176,8 @@ public class ${className} implements java.io.Serializable<#if implements?has_con */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation} public Builder set${field.name?cap_first}(${field.type} ${field.name}) { this.${field.name} = ${field.name}; diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlEnum.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlEnum.ftl index 68fe22fc6..73d189631 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlEnum.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlEnum.ftl @@ -29,8 +29,8 @@ enum class ${className}(val graphqlName: String)<#if implements?has_content> : < */ -<#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") ${field.javaName}("${field.graphqlName}")<#if field_has_next>, <#else> diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlInterface.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlInterface.ftl index 708192bcb..689ce4e2f 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlInterface.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlInterface.ftl @@ -24,7 +24,7 @@ import ${import}.* <#list annotations as annotation> @${annotation} -interface ${className} <#if implements?has_content> : <#list implements as interface>${interface}<#if interface_has_next>, { +interface ${className}<#if implements?has_content> : <#list implements as interface>${interface}<#if interface_has_next>, { <#if fields?has_content> <#list fields as field> @@ -35,8 +35,8 @@ interface ${className} <#if implements?has_content> : <#list implements as inter */ - <#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") <#list field.annotations as annotation> @get:${annotation} diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlOperations.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlOperations.ftl index 3a4e0c907..af0bf0668 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlOperations.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlOperations.ftl @@ -29,8 +29,8 @@ interface ${className}<#if implements?has_content> : <#list implements as interf */ -<#if operation.deprecated> - @Deprecated("this is deprecated in GraphQL") +<#if operation.deprecated?has_content> + @${operation.deprecated.annotation}(message = "${operation.deprecated.reason}") <#list operation.annotations as annotation> @${annotation} diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlParametrizedInput.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlParametrizedInput.ftl index ef8f4a9ce..b7e9f6cca 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlParametrizedInput.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlParametrizedInput.ftl @@ -28,8 +28,8 @@ class ${className}() : GraphQLParametrizedInput { data class ${className}( <#if fields?has_content> <#list fields as field> - <#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") <#list field.annotations as annotation>@get:${annotation} val ${field.name}: ${field.type}<#if field.defaultValue?has_content> = ${field.defaultValue}<#if field_has_next>, diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlRequest.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlRequest.ftl index dcd5fbd14..9a9a21d0c 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlRequest.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlRequest.ftl @@ -49,8 +49,8 @@ open class ${className}(private val alias: String?) : GraphQLOperationRequest { */ -<#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") fun set${field.name?replace("`", "")?cap_first}(${field.name}: ${field.type}) { this.input["${field.originalName}"] = ${field.name} @@ -124,9 +124,9 @@ open class ${className}(private val alias: String?) : GraphQLOperationRequest { */ - <#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") - + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") + fun set${field.name?replace("`", "")?cap_first}(${field.name}: ${field.type}): Builder { this.${field.name} = ${field.name} return this diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponse.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponse.ftl index 56c56a4c2..9b2000111 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponse.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponse.ftl @@ -33,8 +33,8 @@ open class ${className} : GraphQLResult>() */ -<#if deprecated> - @Deprecated("this is deprecated in GraphQL") +<#if deprecated?has_content> + @${deprecated.annotation}(message = "${deprecated.reason}") fun ${methodName}(): ${returnTypeName} { val data: MutableMap = super.getData() diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponseProjection.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponseProjection.ftl index 99b69dc5c..f333516ca 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponseProjection.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlResponseProjection.ftl @@ -55,8 +55,8 @@ open class ${className} : GraphQLResponseProjection() { */ -<#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") fun ${field.methodName}(<#if field.type?has_content>subProjection: ${field.type}): ${className} = ${field.methodName}(<#if field.parametrizedInputClassName?has_content>null<#if field.type?has_content>, subProjection) diff --git a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlType.ftl b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlType.ftl index 38d604f4c..e29274122 100755 --- a/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlType.ftl +++ b/src/main/resources/templates/kotlin-lang/kotlinClassGraphqlType.ftl @@ -59,8 +59,8 @@ class ${className}()<#if implements?has_content> : <#list implements as interfac data class ${className}( <#if fields?has_content> <#list fields as field> - <#if field.deprecated> - @Deprecated("this is deprecated in GraphQL")<#-- Custom messages should be supported in the future --> + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") <#-- Properties of multiple interfaces should not have duplicate names --> <#if parentInterfaces?has_content><#list parentInterfaces as parent><#if parent == field.name>override <#if !immutableModels><#list field.annotations as annotation>@get:${annotation} @@ -142,8 +142,8 @@ data class ${className}( */ - <#if field.deprecated> - @Deprecated("this is deprecated in GraphQL") + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") fun set${field.name?replace("`", "")?cap_first}(${field.name}: ${field.type}): Builder { this.${field.name} = ${field.name} diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlEnum.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlEnum.ftl index ef8c87bb4..9debc1eda 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlEnum.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlEnum.ftl @@ -31,8 +31,8 @@ object ${className} extends Enumeration<#if implements?has_content> with<#list i */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") val ${field.javaName}: Value = Value("${field.graphqlName}") diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlInterface.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlInterface.ftl index 3c4b0be3e..e9fb6efe9 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlInterface.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlInterface.ftl @@ -52,8 +52,8 @@ trait ${className}<#if implements?has_content> extends<#list implements as inter */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") <#list field.annotations as annotation> @${annotation} diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlOperations.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlOperations.ftl index 0204e4168..c9501be56 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlOperations.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlOperations.ftl @@ -61,8 +61,8 @@ trait ${className}<#if implements?has_content> extends <#list implements as inte */ -<#if operation.deprecated> - @Deprecated +<#if operation.deprecated?has_content> + @${operation.deprecated.annotation}(message = "${operation.deprecated.reason}") <#list operation.annotations as annotation> @${annotation} diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlParametrizedInput.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlParametrizedInput.ftl index bacb2ba62..db31e8942 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlParametrizedInput.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlParametrizedInput.ftl @@ -42,8 +42,8 @@ import ${enum}._ case class ${className}( <#if fields?has_content> <#list fields as field> - <#if field.deprecated> - @Deprecated + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") <#list field.annotations as annotation> @${annotation} diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlRequest.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlRequest.ftl index a7b9b49e3..eefc4bc1d 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlRequest.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlRequest.ftl @@ -58,8 +58,8 @@ class ${className}(alias: String) extends GraphQLOperationRequest { */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") def set${field.name?replace("`", "")?cap_first}(${field.name}: ${field.type}): Unit = { <#if MapperUtil.isScalaPrimitive(field.type)> @@ -138,8 +138,8 @@ object ${className} { */ - <#if field.deprecated> - @Deprecated + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") def set${field.name?replace("`", "")?cap_first}(${field.name}: ${field.type}): Builder = { this.${field.name} = ${field.name} diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlResponse.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlResponse.ftl index 254381949..befa6e718 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlResponse.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlResponse.ftl @@ -31,8 +31,8 @@ class ${className} extends GraphQLResult[JMap[String, ${returnTypeName}]] { */ -<#if deprecated> - @Deprecated +<#if deprecated?has_content> + @${deprecated.annotation}(message = "${deprecated.reason}") def ${methodName}(): ${returnTypeName} = { val data: JMap[String, ${returnTypeName}] = getData diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlResponseProjection.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlResponseProjection.ftl index 3b2384c1a..7e4467df3 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlResponseProjection.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlResponseProjection.ftl @@ -55,8 +55,8 @@ class ${className} extends GraphQLResponseProjection { */ -<#if field.deprecated> - @Deprecated +<#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") def ${field.methodName}(<#if field.type?has_content>subProjection: ${field.type}): ${className} = { ${field.methodName}(<#if field.parametrizedInputClassName?has_content>null.asInstanceOf[String]<#if field.type?has_content>, subProjection) diff --git a/src/main/resources/templates/scala-lang/scalaClassGraphqlType.ftl b/src/main/resources/templates/scala-lang/scalaClassGraphqlType.ftl index 306869122..b3011166a 100644 --- a/src/main/resources/templates/scala-lang/scalaClassGraphqlType.ftl +++ b/src/main/resources/templates/scala-lang/scalaClassGraphqlType.ftl @@ -71,8 +71,8 @@ import ${enum}._ case class ${className}( <#if fields?has_content> <#list fields as field> - <#if field.deprecated> - @Deprecated + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") <#list field.annotations as annotation> @${annotation} @@ -117,8 +117,8 @@ object ${className} { */ - <#if field.deprecated> - @Deprecated + <#if field.deprecated?has_content> + @${field.deprecated.annotation}(message = "${field.deprecated.reason}") def set${field.name?replace("`", "")?cap_first}(${field.name}: ${field.type}): Builder = { this.${field.name} = ${field.name} diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/kotlin/GraphQLCodegenDeprecatedTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/kotlin/GraphQLCodegenDeprecatedTest.java new file mode 100644 index 000000000..547eed890 --- /dev/null +++ b/src/test/java/com/kobylynskyi/graphql/codegen/kotlin/GraphQLCodegenDeprecatedTest.java @@ -0,0 +1,55 @@ +package com.kobylynskyi.graphql.codegen.kotlin; + +import com.kobylynskyi.graphql.codegen.TestUtils; +import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage; +import com.kobylynskyi.graphql.codegen.model.MappingConfig; +import com.kobylynskyi.graphql.codegen.utils.Utils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.kobylynskyi.graphql.codegen.TestUtils.assertSameTrimmedContent; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class GraphQLCodegenDeprecatedTest { + + private final MappingConfig mappingConfig = new MappingConfig(); + + private final File outputBuildDir = new File("build/generated"); + private final File outputJavaClassesDir = new File("build/generated/com/github/graphql"); + + @BeforeEach + void init() { + mappingConfig.setGenerateParameterizedFieldsResolvers(false); + mappingConfig.setPackageName("com.github.graphql"); + mappingConfig.setGeneratedLanguage(GeneratedLanguage.KOTLIN); + } + + @AfterEach + void cleanup() { + Utils.deleteDir(outputBuildDir); + } + + @Test + void generate_deprecated() throws Exception { + new KotlinGraphQLCodegen(Collections.singletonList("src/test/resources/schemas/deprecated-with-msg.graphqls"), outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); + + File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); + List generatedFileNames = Arrays.stream(files).map(File::getName).sorted().collect(toList()); + assertEquals(Arrays.asList("CreateEventMutationResolver.kt", "Event.kt", "EventInput.kt", "EventsQueryResolver.kt", + "MutationResolver.kt", "Node.kt", "PinnableItem.kt", "QueryResolver.kt", "Status.kt"), generatedFileNames); + + for (File file : files) { + assertSameTrimmedContent( + new File(String.format("src/test/resources/expected-classes/kt/deprecated/%s.txt", file.getName())), + file); + } + } +} diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/scala/GraphQLCodegenDeprecatedTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/scala/GraphQLCodegenDeprecatedTest.java new file mode 100644 index 000000000..aa9057d72 --- /dev/null +++ b/src/test/java/com/kobylynskyi/graphql/codegen/scala/GraphQLCodegenDeprecatedTest.java @@ -0,0 +1,55 @@ +package com.kobylynskyi.graphql.codegen.scala; + +import com.kobylynskyi.graphql.codegen.TestUtils; +import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage; +import com.kobylynskyi.graphql.codegen.model.MappingConfig; +import com.kobylynskyi.graphql.codegen.utils.Utils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.kobylynskyi.graphql.codegen.TestUtils.assertSameTrimmedContent; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class GraphQLCodegenDeprecatedTest { + + private final MappingConfig mappingConfig = new MappingConfig(); + + private final File outputBuildDir = new File("build/generated"); + private final File outputJavaClassesDir = new File("build/generated/com/github/graphql"); + + @BeforeEach + void init() { + mappingConfig.setGenerateParameterizedFieldsResolvers(false); + mappingConfig.setPackageName("com.github.graphql"); + mappingConfig.setGeneratedLanguage(GeneratedLanguage.SCALA); + } + + @AfterEach + void cleanup() { + Utils.deleteDir(outputBuildDir); + } + + @Test + void generate_deprecated() throws Exception { + new ScalaGraphQLCodegen(Collections.singletonList("src/test/resources/schemas/deprecated-with-msg.graphqls"), outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); + + File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); + List generatedFileNames = Arrays.stream(files).map(File::getName).sorted().collect(toList()); + assertEquals(Arrays.asList("CreateEventMutationResolver.scala", "Event.scala", "EventInput.scala", "EventsQueryResolver.scala", + "MutationResolver.scala", "Node.scala", "PinnableItem.scala", "QueryResolver.scala", "Status.scala"), generatedFileNames); + + for (File file : files) { + assertSameTrimmedContent( + new File(String.format("src/test/resources/expected-classes/scala/deprecated/%s.txt", file.getName())), + file); + } + } +} diff --git a/src/test/resources/expected-classes/kt/deprecated/CreateEventMutationResolver.kt.txt b/src/test/resources/expected-classes/kt/deprecated/CreateEventMutationResolver.kt.txt new file mode 100644 index 000000000..72a56e919 --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/CreateEventMutationResolver.kt.txt @@ -0,0 +1,14 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +interface CreateEventMutationResolver { + + @Deprecated(message = "test deprecated with msg") + @Throws(Exception::class) + fun createEvent(input: EventInput): Event + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/Event.kt.txt b/src/test/resources/expected-classes/kt/deprecated/Event.kt.txt new file mode 100644 index 000000000..903bd2a46 --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/Event.kt.txt @@ -0,0 +1,18 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +data class Event( + @Deprecated(message = "test deprecated with msg") + val status: Status, + @Deprecated(message = "test deprecated with msg") + val createdDateTime: String, + @Deprecated(message = "test deprecated with msg") + override + val id: String +) : PinnableItem, Node { + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/EventInput.kt.txt b/src/test/resources/expected-classes/kt/deprecated/EventInput.kt.txt new file mode 100644 index 000000000..8779e7d2b --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/EventInput.kt.txt @@ -0,0 +1,13 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +data class EventInput( + @Deprecated(message = "test deprecated with msg") + val status: Status +) { + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/EventsQueryResolver.kt.txt b/src/test/resources/expected-classes/kt/deprecated/EventsQueryResolver.kt.txt new file mode 100644 index 000000000..bb99fcac6 --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/EventsQueryResolver.kt.txt @@ -0,0 +1,14 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +interface EventsQueryResolver { + + @Deprecated(message = "No longer supported") + @Throws(Exception::class) + fun events(): List? + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/MutationResolver.kt.txt b/src/test/resources/expected-classes/kt/deprecated/MutationResolver.kt.txt new file mode 100644 index 000000000..a143a14c9 --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/MutationResolver.kt.txt @@ -0,0 +1,14 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +interface MutationResolver { + + @Deprecated(message = "test deprecated with msg") + @Throws(Exception::class) + fun createEvent(input: EventInput): Event + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/Node.kt.txt b/src/test/resources/expected-classes/kt/deprecated/Node.kt.txt new file mode 100644 index 000000000..bb211949b --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/Node.kt.txt @@ -0,0 +1,13 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +interface Node { + + @Deprecated(message = "test deprecated with msg") + val id: String + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/PinnableItem.kt.txt b/src/test/resources/expected-classes/kt/deprecated/PinnableItem.kt.txt new file mode 100644 index 000000000..44abd0676 --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/PinnableItem.kt.txt @@ -0,0 +1,10 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +interface PinnableItem { + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/QueryResolver.kt.txt b/src/test/resources/expected-classes/kt/deprecated/QueryResolver.kt.txt new file mode 100644 index 000000000..f2fc069c8 --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/QueryResolver.kt.txt @@ -0,0 +1,14 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +interface QueryResolver { + + @Deprecated(message = "No longer supported") + @Throws(Exception::class) + fun events(): List? + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/deprecated/Status.kt.txt b/src/test/resources/expected-classes/kt/deprecated/Status.kt.txt new file mode 100644 index 000000000..0e753a48f --- /dev/null +++ b/src/test/resources/expected-classes/kt/deprecated/Status.kt.txt @@ -0,0 +1,12 @@ +package com.github.graphql + +@javax.annotation.Generated( + value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], + date = "2020-12-31T23:59:59-0500" +) +enum class Status(val graphqlName: String) { + + @Deprecated(message = "test deprecated with msg") + CREATED("CREATED"), + IN_PROGRESS("IN_PROGRESS") +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/kt/interfaces/BarBar.kt.txt b/src/test/resources/expected-classes/kt/interfaces/BarBar.kt.txt index b7e2b2cca..b380ecbcb 100644 --- a/src/test/resources/expected-classes/kt/interfaces/BarBar.kt.txt +++ b/src/test/resources/expected-classes/kt/interfaces/BarBar.kt.txt @@ -5,7 +5,7 @@ package com.kobylynskyi.graphql.interfaces value = ["com.kobylynskyi.graphql.codegen.GraphQLCodegen"], date = "2020-12-31T23:59:59-0500" ) -interface BarBar : Bar{ +interface BarBar : Bar { val id: String diff --git a/src/test/resources/expected-classes/kt/restricted-words/Super.kt.txt b/src/test/resources/expected-classes/kt/restricted-words/Super.kt.txt index 826c58765..cdb0f999b 100644 --- a/src/test/resources/expected-classes/kt/restricted-words/Super.kt.txt +++ b/src/test/resources/expected-classes/kt/restricted-words/Super.kt.txt @@ -8,7 +8,7 @@ import java.util.StringJoiner date = "2020-12-31T23:59:59-0500" ) data class Super( - @Deprecated("this is deprecated in GraphQL") + @Deprecated(message = "We have decided that this is not canon") val `is`: String?, val `in`: Char?, val Int: Super?, @@ -44,7 +44,7 @@ data class Super( private var Int: Super? = null private var date: String? = null - @Deprecated("this is deprecated in GraphQL") + @Deprecated(message = "We have decided that this is not canon") fun setIs(`is`: String?): Builder { this.`is` = `is` return this diff --git a/src/test/resources/expected-classes/scala/deprecated/CreateEventMutationResolver.scala.txt b/src/test/resources/expected-classes/scala/deprecated/CreateEventMutationResolver.scala.txt new file mode 100644 index 000000000..6fe26224a --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/CreateEventMutationResolver.scala.txt @@ -0,0 +1,15 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +trait CreateEventMutationResolver { + + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + @throws[Exception] + def createEvent(input: EventInput): Event + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/Event.scala.txt b/src/test/resources/expected-classes/scala/deprecated/Event.scala.txt new file mode 100644 index 000000000..42cc66a18 --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/Event.scala.txt @@ -0,0 +1,22 @@ +package com.github.graphql + +import scala.collection.JavaConverters._ +import Status._ + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +case class Event( + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + status: Status, + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + createdDateTime: String, + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + override val id: String +) extends PinnableItem with Node { + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/EventInput.scala.txt b/src/test/resources/expected-classes/scala/deprecated/EventInput.scala.txt new file mode 100644 index 000000000..ad774af7b --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/EventInput.scala.txt @@ -0,0 +1,16 @@ +package com.github.graphql + +import scala.collection.JavaConverters._ +import Status._ + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +case class EventInput( + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + status: Status +) { + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/EventsQueryResolver.scala.txt b/src/test/resources/expected-classes/scala/deprecated/EventsQueryResolver.scala.txt new file mode 100644 index 000000000..f72ba401c --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/EventsQueryResolver.scala.txt @@ -0,0 +1,15 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +trait EventsQueryResolver { + + @deprecated(message = "No longer supported") + @javax.validation.constraints.NotNull + @throws[Exception] + def events(): Seq[Event] + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/MutationResolver.scala.txt b/src/test/resources/expected-classes/scala/deprecated/MutationResolver.scala.txt new file mode 100644 index 000000000..eb0c342d1 --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/MutationResolver.scala.txt @@ -0,0 +1,15 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +trait MutationResolver { + + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + @throws[Exception] + def createEvent(input: EventInput): Event + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/Node.scala.txt b/src/test/resources/expected-classes/scala/deprecated/Node.scala.txt new file mode 100644 index 000000000..526dd761c --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/Node.scala.txt @@ -0,0 +1,14 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +trait Node { + + @deprecated(message = "test deprecated with msg") + @javax.validation.constraints.NotNull + val id: String + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/PinnableItem.scala.txt b/src/test/resources/expected-classes/scala/deprecated/PinnableItem.scala.txt new file mode 100644 index 000000000..2f7648368 --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/PinnableItem.scala.txt @@ -0,0 +1,10 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +trait PinnableItem { + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/QueryResolver.scala.txt b/src/test/resources/expected-classes/scala/deprecated/QueryResolver.scala.txt new file mode 100644 index 000000000..cba7fce5e --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/QueryResolver.scala.txt @@ -0,0 +1,15 @@ +package com.github.graphql + + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +trait QueryResolver { + + @deprecated(message = "No longer supported") + @javax.validation.constraints.NotNull + @throws[Exception] + def events(): Seq[Event] + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/scala/deprecated/Status.scala.txt b/src/test/resources/expected-classes/scala/deprecated/Status.scala.txt new file mode 100644 index 000000000..fcbcd89e9 --- /dev/null +++ b/src/test/resources/expected-classes/scala/deprecated/Status.scala.txt @@ -0,0 +1,15 @@ +package com.github.graphql + +@javax.annotation.Generated( + value = Array("com.kobylynskyi.graphql.codegen.GraphQLCodegen"), + date = "2020-12-31T23:59:59-0500" +) +object Status extends Enumeration { + + type Status = Value + + @deprecated(message = "test deprecated with msg") + val CREATED: Value = Value("CREATED") + val IN_PROGRESS: Value = Value("IN_PROGRESS") + +} \ No newline at end of file diff --git a/src/test/resources/schemas/deprecated-with-msg.graphqls b/src/test/resources/schemas/deprecated-with-msg.graphqls new file mode 100644 index 000000000..fc816e735 --- /dev/null +++ b/src/test/resources/schemas/deprecated-with-msg.graphqls @@ -0,0 +1,37 @@ +# A GraphQL schema provides a root type for each kind of operation. +schema { + query: Query + mutation: Mutation +} + + +type Query { + events: [Event!] @deprecated +} + + +type Mutation { + createEvent(input: EventInput! @deprecated(reason: "test deprecated with msg")): Event! @deprecated(reason: "test deprecated with msg") +} + +type Event implements Node { + status: Status! @deprecated(reason: "test deprecated with msg") + createdDateTime: DateTime! @deprecated(reason: "test deprecated with msg") +} + +input EventInput { + status: Status! @deprecated(reason: "test deprecated with msg") +} + +enum Status { + CREATED @deprecated(reason: "test deprecated with msg") + IN_PROGRESS +} + +interface Node { + id: ID! @deprecated(reason: "test deprecated with msg") +} + +union PinnableItem = Event + +scalar DateTime