Add support for directives on directive definitions#9930
Merged
Conversation
## Summary - Adds the "directives on directive definitions" feature to the core type system: applying directives to directive definitions and their arguments, `extend directive`, `@deprecated` on directives, the `DIRECTIVE_DEFINITION` location, and code-first descriptor support (`.Directive(...)`, `.Deprecated(...)`). - Surfaces the new metadata through introspection: `__Directive.isDeprecated`/`deprecationReason`, `__Schema.directives(includeDeprecated:)`, and `DIRECTIVE_DEFINITION` in `__DirectiveLocation`. - Rejects a directive that references itself (on its definition or its arguments) in both the runtime and the abstract validation layers, and documents the feature in the website docs. ## Test plan - Schema-first, code-first, introspection, pruning, and self-reference validation are covered by unit tests in `Types.Tests`, `Execution.Tests`, and `Types.Validation.Tests`. - Core-wide sweep: `HotChocolate.Core.slnx` builds clean and all snapshot-bearing Core test projects pass (one unrelated pre-existing net9.0 `@defer` failure is tracked separately). Part of the directives on directive definitions effort (#4625); second of three stacked PRs (Language, Core, and Mutable round-trip).
Contributor
There was a problem hiding this comment.
Pull request overview
Implements GraphQL’s “directives on directive definitions” across HotChocolate’s language layer, core type system (including introspection + validation), and the mutable/Fusion round-trip, with accompanying docs and test updates.
Changes:
- Adds SDL/AST/parser/printer/visitor support for directives on directive definitions plus
extend directive. - Extends core directive type system to store applied directives + deprecation, exposes new introspection fields/arguments/locations, and adds direct self-reference validation.
- Updates mutable schema model + formatter/parser and Fusion composition plumbing to round-trip the new directive surfaces.
Reviewed changes
Copilot reviewed 100 out of 102 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| website/src/docs/hotchocolate/v16/defining-a-schema/directives.md | Adds v16 docs for directives-on-directives and troubleshooting |
| src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionFormatter.cs | Updates directive definition AST construction for new directives parameter |
| src/HotChocolate/Primitives/test/Primitives.Tests/DirectiveLocationUtilsTests.cs | Adds unit tests for DIRECTIVE_DEFINITION location mapping |
| src/HotChocolate/Primitives/src/Primitives/Types/DirectiveLocationUtils.cs | Adds DIRECTIVE_DEFINITION mapping/formatting support |
| src/HotChocolate/Primitives/src/Primitives/Types/DirectiveLocation.cs | Adds DirectiveDefinition enum flag + TypeSystem aggregate |
| src/HotChocolate/Primitives/src/Primitives/ErrorCodes.cs | Adds schema error code for unknown directive extension target |
| src/HotChocolate/Mutable/test/Types.Mutable.Tests/ToSyntaxNodeTests.cs | Tests directive definition ToSyntaxNode with directives/deprecation |
| src/HotChocolate/Mutable/test/Types.Mutable.Tests/ToStringTests.cs | Tests schema printing for directives-on-directives and extensions |
| src/HotChocolate/Mutable/test/Types.Mutable.Tests/SchemaParserTests.cs | Tests parsing/merging of directive extensions + deprecation |
| src/HotChocolate/Mutable/test/Types.Mutable.Tests/MutableDirectiveDefinitionTests.cs | Adds tests for mutable directive definition directives/deprecation |
| src/HotChocolate/Mutable/src/Types.Mutable/Serialization/SchemaParser.cs | Parses directives on directive definitions and extend directive |
| src/HotChocolate/Mutable/src/Types.Mutable/MutableDirectiveDefinition.cs | Adds directives + deprecation state to mutable directive definitions |
| src/HotChocolate/Mutable/src/Types.Mutable/Extensions/FeatureCollectionExtensions.cs | Allows extension-marker for directives via broader type constraint |
| src/HotChocolate/Mutable/src/Types.Mutable/Extensions/DirectiveLocationExtensions.cs | Adds DIRECTIVE_DEFINITION mapping in mutable layer |
| src/HotChocolate/Mutable/src/Types.Mutable/BuiltIns/DeprecatedMutableDirectiveDefinition.cs | Adds DIRECTIVE_DEFINITION to built-in @deprecated locations |
| src/HotChocolate/Language/test/Language.Tests/Visitors/SyntaxVisitorTests.cs | Adds visitor coverage for DirectiveExtensionNode |
| src/HotChocolate/Language/test/Language.Tests/Visitors/SyntaxRewriterTests.cs | Adds rewriter coverage for directives in DirectiveExtensionNode |
| src/HotChocolate/Language/test/Language.Tests/Parser/DirectiveParserTests.cs | Adds parser tests for DIRECTIVE_DEFINITION, directives-on-defs, extensions |
| src/HotChocolate/Language/test/Language.Tests/Parser/snapshots/KitchenSinkParserTests.ParseFacebookKitchenSinkSchema.snap | Updates kitchen sink AST snapshot for new Directives field |
| src/HotChocolate/Language/test/Language.SyntaxTree.Tests/Utilities/SchemaSyntaxPrinterTests.cs | Adds printer round-trip tests for new syntax |
| src/HotChocolate/Language/test/Language.SyntaxTree.Tests/Utilities/snapshots/SchemaSyntaxPrinterTests.Serialize_DirectiveDefWithDirectivesAndExtension_OutHasIndentation.snap | Adds snapshot for directive def + extension printing |
| src/HotChocolate/Language/test/Language.SyntaxTree.Tests/DirectiveExtensionNodeTests.cs | Adds syntax node tests for DirectiveExtensionNode |
| src/HotChocolate/Language/test/Language.SyntaxTree.Tests/DirectiveDefinitionNodeTests.cs | Updates/extends tests for DirectiveDefinitionNode directives support |
| src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Leave.cs | Adds walker leave support for DirectiveExtensionNode (generic) |
| src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker~1.Enter.cs | Adds walker enter support for DirectiveExtensionNode (generic) |
| src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Leave.cs | Adds walker leave support for DirectiveExtensionNode |
| src/HotChocolate/Language/src/Language.Visitors/SyntaxWalker.Enter.cs | Adds walker enter support for DirectiveExtensionNode |
| src/HotChocolate/Language/src/Language.Visitors/SyntaxVisitor~1.VisitationMap.cs | Adds child-visitation logic for directive def directives + directive extension |
| src/HotChocolate/Language/src/Language.Visitors/SyntaxRewriter~1.cs | Adds rewriting support for directives on directive defs and extensions |
| src/HotChocolate/Language/src/Language.Visitors/DefaultSyntaxNavigator.cs | Ensures coordinates work for directive extensions |
| src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Extensions.cs | Parses extend directive as a type-system extension |
| src/HotChocolate/Language/src/Language.Utf8/Utf8GraphQLParser.Directives.cs | Parses directives applied to directive definitions |
| src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.SchemaSyntax.cs | Prints directives on directive definitions + directive extensions |
| src/HotChocolate/Language/src/Language.SyntaxTree/Utilities/SyntaxSerializer.cs | Wires DirectiveExtensionNode into serializer dispatch |
| src/HotChocolate/Language/src/Language.SyntaxTree/SyntaxKind.cs | Adds DirectiveExtension syntax kind |
| src/HotChocolate/Language/src/Language.SyntaxTree/SyntaxEqualityComparer.cs | Adds equality/hash support for directives on defs + directive extensions |
| src/HotChocolate/Language/src/Language.SyntaxTree/DirectiveLocation.cs | Adds string-based DIRECTIVE_DEFINITION directive location |
| src/HotChocolate/Language/src/Language.SyntaxTree/DirectiveExtensionNode.cs | Introduces DirectiveExtensionNode AST type |
| src/HotChocolate/Language/src/Language.SyntaxTree/DirectiveDefinitionNode.cs | Adds directives collection + IHasDirectives support |
| src/HotChocolate/Fusion/src/Fusion.Execution.Types/Completion/CompositeSchemaContext.cs | Updates built-in directive AST construction for new parameter |
| src/HotChocolate/Fusion/src/Fusion.Execution.Types/Completion/CompositeSchemaBuilder.cs | Updates built-in directive AST construction for new parameter |
| src/HotChocolate/Core/test/Types.Validation.Tests/Rules/DirectiveDefinitionNoSelfReferenceRuleTests.cs | Adds abstract validation tests for directive self-reference |
| src/HotChocolate/Core/test/Types.Tests/Types/DirectiveTypeTests.cs | Adds directive type tests for applied directives + deprecation + location errors |
| src/HotChocolate/Core/test/Types.Tests/Types/snapshots/DirectiveTypeTests.DirectiveType_DirectiveWithoutDirectiveDefinitionLocation_Errors.snap | Adds snapshot for directive location validation error |
| src/HotChocolate/Core/test/Types.Tests/SchemaFirstTests.cs | Adds schema-first coverage for directives-on-directives + extend directive |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.SchemaFirst_ExtendDirectiveUnknownTarget_Errors.snap | Adds snapshot for unknown directive extension target |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.SchemaFirst_ExtendDirectiveNonRepeatableDuplicate_Errors.snap | Adds snapshot for non-repeatable duplicate via extension |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.SchemaFirst_DirectivesOnDirectiveDefinition_RoundTripInSdl.graphql | Adds SDL snapshot for round-tripped directive definitions |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.SchemaFirst_DirectiveOnDirectiveDefinitionWrongLocation_Errors.snap | Adds snapshot for wrong-location directive-on-directive error |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.SchemaFirst_DirectiveDefinitionSelfApplication_Errors.snap | Adds snapshot for direct self-reference error |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.SchemaFirst_DirectiveDefinitionArgumentSelfApplication_Errors.snap | Adds snapshot for argument-level self-reference error |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.Interfaces_Impl_Interfaces_Are_Correctly_Exposed_Through_Introspection.snap | Updates introspection snapshots for new directive fields/args/locations |
| src/HotChocolate/Core/test/Types.Tests/snapshots/SchemaFirstTests.DescriptionsAreCorrectlyRead.snap | Updates introspection snapshots for new directive fields/args/locations |
| src/HotChocolate/Core/test/Execution.Tests/IntrospectionTests.cs | Adds runtime tests for directive deprecation + filtering + location exposure |
| src/HotChocolate/Core/test/Execution.Tests/Integration/StarWarsCodeFirst/snapshots/StarWarsCodeFirstTests.Ensure_Benchmark_Query_LargeQuery.snap | Updates large introspection snapshot for new fields/args/locations |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery.snap | Updates GraphiQL introspection snapshot for new fields/args/locations |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery_ToJson.snap | Updates GraphiQL JSON snapshot for new fields/args/locations |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DirectiveIntrospection_SomeDirectives_Internal.snap | Updates directive introspection snapshot shape |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DirectiveIntrospection_AllDirectives_Public.snap | Updates directive introspection snapshot shape |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DirectiveIntrospection_AllDirectives_Public_When_DisableInternalDirectives_Is_True.snap | Updates directive introspection snapshot shape |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DirectiveIntrospection_AllDirectives_Internal.snap | Updates directive introspection snapshot shape |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DirectiveDeprecationIsExposed.snap | Adds snapshot for __Directive.isDeprecated/deprecationReason |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DirectiveDefinitionLocationIsExposed.snap | Adds snapshot for DIRECTIVE_DEFINITION in introspection |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DeprecatedDirectivesAreFilteredByDefault.snap | Adds snapshot for includeDeprecated behavior |
| src/HotChocolate/Core/test/Execution.Tests/snapshots/IntrospectionTests.DefaultValueIsInputObject.snap | Updates introspection snapshot for new directive fields/args/locations |
| src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs | Adds schema error helper for directive self-application |
| src/HotChocolate/Core/src/Types/Types/Introspection/__Schema.cs | Adds includeDeprecated argument to __Schema.directives |
| src/HotChocolate/Core/src/Types/Types/Introspection/__DirectiveLocation.cs | Adds DIRECTIVE_DEFINITION enum value in introspection |
| src/HotChocolate/Core/src/Types/Types/Introspection/__Directive.cs | Adds isDeprecated + deprecationReason to __Directive |
| src/HotChocolate/Core/src/Types/Types/Helpers/DirectiveHelper.cs | Infers DirectiveDefinition location for directive types |
| src/HotChocolate/Core/src/Types/Types/Factories/SdlToTypeSystemHelper.cs | Adds directive-level deprecation reason helper + skips @deprecated in directives |
| src/HotChocolate/Core/src/Types/Types/Factories/SchemaSyntaxVisitorContext.cs | Tracks directive extensions in schema syntax visitor context |
| src/HotChocolate/Core/src/Types/Types/Factories/SchemaSyntaxVisitor.cs | Collects directive extension directives into feature state |
| src/HotChocolate/Core/src/Types/Types/Factories/SchemaFirstTypeInterceptor.cs | Applies extend directive directives + throws on unknown targets |
| src/HotChocolate/Core/src/Types/Types/Factories/DirectiveTypeFactory.cs | Binds directive definition deprecation + applied directives from SDL |
| src/HotChocolate/Core/src/Types/Types/DirectiveType.Initialization.cs | Completes directive type deprecation + applied directives collection |
| src/HotChocolate/Core/src/Types/Types/DirectiveType.cs | Adds runtime properties for directives + deprecation |
| src/HotChocolate/Core/src/Types/Types/Directives/DirectiveTypeInterceptor.cs | Registers directive usage for directive definitions themselves |
| src/HotChocolate/Core/src/Types/Types/Directives/DeprecatedDirectiveType.cs | Allows @deprecated on directive definitions |
| src/HotChocolate/Core/src/Types/Types/Descriptors/DirectiveTypeDescriptor~1.cs | Adds fluent Deprecated/Directive APIs returning generic descriptor |
| src/HotChocolate/Core/src/Types/Types/Descriptors/DirectiveTypeDescriptor.cs | Adds directive-level Deprecated/Directive APIs + obsolete inference |
| src/HotChocolate/Core/src/Types/Types/Descriptors/Contracts/IDirectiveTypeDescriptor~1.cs | Adds new APIs to directive type descriptor contract (generic) |
| src/HotChocolate/Core/src/Types/Types/Descriptors/Contracts/IDirectiveTypeDescriptor.cs | Adds new APIs to directive type descriptor contract |
| src/HotChocolate/Core/src/Types/Types/Descriptors/Configurations/DirectiveTypeConfiguration.cs | Adds deprecation + applied directives storage to directive configs |
| src/HotChocolate/Core/src/Types/SchemaBuilder.Setup.cs | Plumbs directive extension collection through schema document parsing |
| src/HotChocolate/Core/src/Types/Properties/TypeResources.resx | Adds localized strings for directive extensions + directive definition location |
| src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs | Regenerates strongly-typed resources for new strings |
| src/HotChocolate/Core/src/Types/Internal/TypeDependencyHelper.cs | Adds completion dependencies for directives on directive definitions |
| src/HotChocolate/Core/src/Types/Configuration/Validation/DirectiveValidationRule.cs | Adds runtime validation for directive definition self-application |
| src/HotChocolate/Core/src/Types/Configuration/Features/TypeSystemFeature.cs | Adds feature state for directive extensions |
| src/HotChocolate/Core/src/Types.Validation/SchemaValidator.cs | Registers new abstract validation rule + publishes directive events |
| src/HotChocolate/Core/src/Types.Validation/Rules/DirectiveDefinitionNoSelfReferenceRule.cs | Adds abstract rule preventing direct self-reference |
| src/HotChocolate/Core/src/Types.Validation/Properties/ValidationResources.resx | Adds localized rule message for self-reference |
| src/HotChocolate/Core/src/Types.Validation/Properties/ValidationResources.Designer.cs | Regenerates strongly-typed resources for validation messages |
| src/HotChocolate/Core/src/Types.Validation/Logging/LogEntryHelper.cs | Adds log entry builder for directive self-application |
| src/HotChocolate/Core/src/Types.Validation/Logging/LogEntryCodes.cs | Adds new validation code for self-reference |
| src/HotChocolate/Core/src/Types.Abstractions/Types/IDirectiveDefinition.cs | Extends directive definition abstraction with deprecation + directives provider |
| src/HotChocolate/Core/src/Types.Abstractions/Serialization/SemanticNonNullSchemaRewriter.cs | Updates directive definition node construction for new directives parameter |
| src/HotChocolate/Core/src/Types.Abstractions/Serialization/SchemaFormatter.cs | Prints directives on directive definitions and emits extend directive |
| src/HotChocolate/Core/src/Types.Abstractions/Serialization/SchemaDebugFormatter.cs | Includes directive definition directives + synthesized @deprecated in debug output |
| src/HotChocolate/Core/src/Abstractions/GraphQLDeprecatedAttribute.cs | Allows deprecating directive definition CLR types via attribute targets |
| dictionary.txt | Adds “reparsed” to dictionary |
Files not reviewed (2)
- src/HotChocolate/Core/src/Types.Validation/Properties/ValidationResources.Designer.cs: Generated file
- src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Code Coverage OverviewLanguages: C# C# / code-coverage/dotnetThe overall coverage in the branch remains at 49%, unchanged from the branch. Show a code coverage summary of the most impacted files.
Updated |
This was referenced Jun 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
extend directive,@deprecatedon directives, theDIRECTIVE_DEFINITIONlocation, and the matching introspection surface (__Directive.isDeprecated/deprecationReason,__Schema.directives(includeDeprecated:), andDIRECTIVE_DEFINITIONin__DirectiveLocation).Test plan
main, the branch was re-verified — Core, Mutable, and Fusion solutions build with 0 errors, and the feature suites pass on net10.0: Language (384), Primitives (16), Types (3392), Execution (617), Types.Validation (99), Types.Mutable (79), Fusion.Composition (517).Closes #4625