Skip to content

Commit 2ae97c1

Browse files
authored
fix: add @param use-site target for annotations on constructor params (#156)
1 parent fde56ad commit 2ae97c1

File tree

13 files changed

+61
-38
lines changed

13 files changed

+61
-38
lines changed

src/annotations/build-annotations.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,30 @@ export function buildAnnotations({
3636
config,
3737
definitionNode,
3838
typeMetadata,
39+
annotationPrefix = "@",
3940
}: {
4041
schema: GraphQLSchema;
4142
config: CodegenConfigWithDefaults;
4243
definitionNode: DefinitionNode;
4344
typeMetadata?: TypeMetadata;
45+
annotationPrefix?: string;
4446
}) {
4547
const description = definitionNode?.description?.value ?? "";
4648
const descriptionAnnotation = buildDescriptionAnnotation(
4749
description,
4850
definitionNode,
4951
config,
5052
typeMetadata,
53+
annotationPrefix,
5154
);
5255
const directiveAnnotations = buildDirectiveAnnotations(
5356
definitionNode,
5457
config,
5558
schema,
59+
annotationPrefix,
5660
);
5761
const unionAnnotation = typeMetadata?.unionAnnotation
58-
? `@${typeMetadata.unionAnnotation}\n`
62+
? `${annotationPrefix}${typeMetadata.unionAnnotation}\n`
5963
: "";
6064

6165
const annotations = [

src/annotations/build-description-annotation.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export function buildDescriptionAnnotation(
2222
definitionNode: DefinitionNode,
2323
config: CodegenConfigWithDefaults,
2424
typeMetadata?: TypeMetadata,
25+
annotationPrefix = "@",
2526
) {
2627
const trimmedDescription = trimDescription(description);
2728
const isDeprecatedDescription = trimmedDescription.startsWith(
@@ -30,11 +31,12 @@ export function buildDescriptionAnnotation(
3031
const isRequiredInputField =
3132
definitionNode.kind === Kind.INPUT_VALUE_DEFINITION &&
3233
definitionNode.type.kind === Kind.NON_NULL_TYPE;
34+
const deprecatedPrefix = "@"; // @Deprecated doesn't support @param:
3335
if (
3436
isDeprecatedDescription &&
3537
(typeMetadata?.unionAnnotation || isRequiredInputField)
3638
) {
37-
return `@GraphQLDescription("${trimmedDescription}")\n`;
39+
return `${annotationPrefix}GraphQLDescription("${trimmedDescription}")\n`;
3840
} else if (isDeprecatedDescription) {
3941
const descriptionValue = description.replace(
4042
deprecatedDescriptionPrefix,
@@ -56,12 +58,12 @@ export function buildDescriptionAnnotation(
5658
const trimmedDeprecatedReason = trimDescription(deprecatedReason);
5759

5860
if (deprecatedDirective && typeMetadata?.unionAnnotation) {
59-
return `@GraphQLDescription("${trimmedDeprecatedReason}")\n`;
61+
return `${annotationPrefix}GraphQLDescription("${trimmedDeprecatedReason}")\n`;
6062
} else if (deprecatedDirective) {
6163
const graphqlDescription = trimmedDescription
62-
? `@GraphQLDescription("${trimmedDescription}")\n`
64+
? `${annotationPrefix}GraphQLDescription("${trimmedDescription}")\n`
6365
: "";
64-
const deprecatedDescription = `@Deprecated("${trimmedDeprecatedReason}")\n`;
66+
const deprecatedDescription = `${deprecatedPrefix}Deprecated("${trimmedDeprecatedReason}")\n`;
6567
return `${graphqlDescription}${graphqlDescription ? indent(deprecatedDescription, 2) : deprecatedDescription}`;
6668
}
6769

@@ -70,7 +72,7 @@ export function buildDescriptionAnnotation(
7072
(config.unionGeneration === "MARKER_INTERFACE" ||
7173
definitionNode?.kind !== Kind.UNION_TYPE_DEFINITION)
7274
) {
73-
return `@GraphQLDescription("${trimmedDescription}")\n`;
75+
return `${annotationPrefix}GraphQLDescription("${trimmedDescription}")\n`;
7476
}
7577

7678
return "";

src/annotations/build-directive-annotations.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export function buildDirectiveAnnotations(
2323
definitionNode: DefinitionNode,
2424
config: CodegenConfigWithDefaults,
2525
schema: GraphQLSchema,
26+
annotationPrefix = "@",
2627
) {
2728
const name = sanitizeName(definitionNode.name.value);
2829
const potentialMatchingInputType = schema.getType(`${name}Input`);
@@ -36,7 +37,9 @@ export function buildDirectiveAnnotations(
3637
const directiveName = directive.name.value;
3738
const federationReplacement =
3839
getFederationDirectiveReplacement(directive);
39-
if (federationReplacement) return federationReplacement + "\n";
40+
if (federationReplacement) {
41+
return `${applyAnnotationPrefix(federationReplacement, annotationPrefix)}\n`;
42+
}
4043

4144
const directiveReplacementFromConfig = config.directiveReplacements?.find(
4245
({ directive, definitionType }) => {
@@ -53,24 +56,32 @@ export function buildDirectiveAnnotations(
5356
);
5457

5558
if (directiveReplacementFromConfig) {
56-
return (
57-
buildKotlinAnnotationsFromConfig(
58-
directive,
59-
directiveReplacementFromConfig.kotlinAnnotations,
60-
).join("\n") + "\n"
59+
const annotations = buildKotlinAnnotationsFromConfig(
60+
directive,
61+
directiveReplacementFromConfig.kotlinAnnotations,
62+
annotationPrefix,
6163
);
64+
return annotations.join("\n") + "\n";
6265
}
6366
const customDirectiveFromConfig = config.customDirectives?.find(
6467
(directive) => directive === directiveName,
6568
);
6669
if (customDirectiveFromConfig) {
67-
return buildCustomDirective(directive);
70+
const customDirective = buildCustomDirective(directive);
71+
return applyAnnotationPrefix(customDirective, annotationPrefix);
6872
}
6973
return "";
7074
})
7175
.join("");
7276
}
7377

78+
function applyAnnotationPrefix(annotation: string, prefix: string) {
79+
const annotationWithoutAt = annotation.startsWith("@")
80+
? annotation.substring(1)
81+
: annotation;
82+
return `${prefix}${annotationWithoutAt}`;
83+
}
84+
7485
function buildCustomDirective(directive: ConstDirectiveNode) {
7586
const directiveName = directive.name.value;
7687
return `@${titleCase(directiveName)}\n`;
@@ -81,9 +92,12 @@ function buildKotlinAnnotationsFromConfig(
8192
kotlinAnnotations: NonNullable<
8293
CodegenConfigWithDefaults["directiveReplacements"]
8394
>[number]["kotlinAnnotations"],
95+
annotationPrefix: string,
8496
) {
8597
return kotlinAnnotations.map((kotlinAnnotation) => {
86-
if (typeof kotlinAnnotation === "string") return kotlinAnnotation;
98+
if (typeof kotlinAnnotation === "string") {
99+
return applyAnnotationPrefix(kotlinAnnotation, annotationPrefix);
100+
}
87101
const directiveArguments = kotlinAnnotation.argumentsToRetain
88102
?.map((argumentToRetain) => {
89103
const argumentValueNode = directive.arguments?.find(
@@ -104,7 +118,7 @@ function buildKotlinAnnotationsFromConfig(
104118
return `${argumentToRetain} = ${argumentValue}`;
105119
})
106120
.join(", ");
107-
return `@${kotlinAnnotation.annotationName}(${directiveArguments})`;
121+
return `${annotationPrefix}${kotlinAnnotation.annotationName}(${directiveArguments})`;
108122
});
109123
}
110124

src/definitions/field.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export function buildObjectFieldDefinition({
7676
config,
7777
definitionNode: fieldNode,
7878
typeMetadata,
79+
annotationPrefix: shouldGenerateFunctions ? "@" : "@param:",
7980
});
8081
return `${annotations}${field}${shouldGenerateFunctions || isLastFieldInType(node, fieldNode) ? "" : ","}`;
8182
}
@@ -117,6 +118,7 @@ export function buildConstructorFieldDefinition({
117118
config,
118119
definitionNode: fieldNode,
119120
typeMetadata,
121+
annotationPrefix: "@param:",
120122
});
121123
const shouldGenerateFunctions = shouldGenerateFunctionsInClass(
122124
node,

src/definitions/input.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export function buildInputObjectDefinition(
4343
schema,
4444
config,
4545
definitionNode: field,
46+
annotationPrefix: "@param:",
4647
});
4748
return `${annotations}${indent(
4849
`val ${sanitizeName(field.name.value)}: ${typeToUse.typeName}${

test/unit/should_annotate_types_properly/expected.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import com.expediagroup.graphql.generator.annotations.*
66
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
77
data class TypeThatShouldBeProperlyAnnotated(
88
val field: String? = null,
9-
@GraphQLDescription("A description for fieldWithDescription")
9+
@param:GraphQLDescription("A description for fieldWithDescription")
1010
val fieldWithDescription: String? = null,
11-
@GraphQLDescription("A `weird` description for weirdDescription")
11+
@param:GraphQLDescription("A `weird` description for weirdDescription")
1212
val weirdDescription: String? = null,
1313
@Deprecated("Use something else instead")
1414
val deprecated1: String? = null,
@@ -22,7 +22,7 @@ data class TypeThatShouldBeProperlyAnnotated(
2222
val deprecated5: UnionThatShouldBeProperlyAnnotated? = null,
2323
@Deprecated("It uses the GraphQLDescription annotation for union types")
2424
val deprecated6: UnionThatShouldBeProperlyAnnotated? = null,
25-
@GraphQLDescription("When there is a description")
25+
@param:GraphQLDescription("When there is a description")
2626
@Deprecated("It uses the @Deprecated annotation for the reason")
2727
val deprecated7: UnionThatShouldBeProperlyAnnotated? = null,
2828
@Deprecated("Multiline reason")
@@ -35,6 +35,6 @@ interface UnionThatShouldBeProperlyAnnotated
3535
data class InputTypeThatShouldBeProperlyAnnotated(
3636
@Deprecated("this field is deprecated")
3737
val optionalField: String? = null,
38-
@GraphQLDescription("DEPRECATED: this field is deprecated")
38+
@param:GraphQLDescription("DEPRECATED: this field is deprecated")
3939
val requiredField: String
4040
)

test/unit/should_generate_custom_directives/expected.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ data class MyTypeWithCustomDirectiveOnObject(
2727

2828
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
2929
data class MyTypeWithCustomDirectiveOnField(
30-
@MyCustomDirective
30+
@param:MyCustomDirective
3131
val field: String? = null
3232
)
3333

@@ -39,6 +39,6 @@ data class MyInputWithCustomDirectiveOnObject(
3939

4040
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT])
4141
data class MyInputWithCustomDirectiveOnField(
42-
@MyCustomDirective
42+
@param:MyCustomDirective
4343
val field: String? = null
4444
)

test/unit/should_generate_input_types_properly/expected.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import com.expediagroup.graphql.generator.annotations.*
66
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT])
77
data class InputTypeThatShouldBeGeneratedProperly(
88
val field1: String? = null,
9-
@GraphQLDescription("A description for field2")
9+
@param:GraphQLDescription("A description for field2")
1010
val field2: String? = null
1111
)

test/unit/should_generate_union_list_types_properly/expected.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface UnionForGeneratingUnionListTypes
1818

1919
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
2020
data class MyUnionListType(
21-
@GraphQLDescription("A description for field")
21+
@param:GraphQLDescription("A description for field")
2222
val field: List<UnionForGeneratingUnionListTypes>? = null,
2323
val field2: List<UnionForGeneratingUnionListTypes?>? = null
2424
)

test/unit/should_generate_union_types_properly/expected.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface UnionForGeneratingUnionsProperly
1818

1919
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
2020
data class MyUnionType(
21-
@GraphQLDescription("A description for field")
21+
@param:GraphQLDescription("A description for field")
2222
val field: UnionForGeneratingUnionsProperly? = null,
2323
val field2: String? = null
2424
)

0 commit comments

Comments
 (0)