DSL markers without explicit targets
DSL_MARKER_WITHOUT_EXPLICIT_TARGETS reports a @DslMarker annotation class that declares no
explicit @Target.
| Diagnostic | DSL_MARKER_WITHOUT_EXPLICIT_TARGETS |
| Default severity | Error |
| Gradle property | dslMarkerWithoutExplicitTargets |
| Exemption | @IntentionallyWrongDslMarkerTargetsForBackwardsCompatibility |
What it reports
Any annotation class annotated with @DslMarker that has no @Target of its own:
/** Marks DSL receivers. */@DslMarkerpublic annotation class DefaultTargetsDsl
Rationale
DSL marker scope control
only reacts to a marker found on a classifier declaration (CLASS, ANNOTATION_CLASS), a type
usage (TYPE), or a type alias (TYPEALIAS). The default target set includes CLASS, but omits
TYPE and TYPEALIAS while allowing parameters, properties, functions, and other positions where
the marker has no effect. An explicit target set makes the effective placements available without
advertising ineffective ones.
Don't
/** Marks HTML DSL receivers. */@DslMarkerpublic annotation class HtmlDsl
Do
/** Marks HTML DSL receivers. */@DslMarker@Target(AnnotationTarget.CLASS,AnnotationTarget.ANNOTATION_CLASS,AnnotationTarget.TYPE,AnnotationTarget.TYPEALIAS,)public annotation class HtmlDsl// A narrower, still-effective subset is fine too/** Marks Ktor DSL receivers. */@DslMarker@Target(AnnotationTarget.CLASS)public annotation class KtorDsl
Notes
ANNOTATION_CLASSis also effective because it is a classifier declaration, likeCLASS.- A marker with an explicit
@Targetthat lists no-op targets is covered by the separate, related DSL markers with no-op targets check. - A plain annotation class without
@DslMarkeris outside the scope of this check, regardless of its@Target.
Exemption
For an already-published marker, adding a @Target at all is a breaking change: it rejects
user code that currently applies the marker to a now-disallowed target. Acknowledge the legacy
shape with @IntentionallyWrongDslMarkerTargetsForBackwardsCompatibility instead of fixing it:
/** Marks HTML DSL receivers with default targets retained for compatibility. */@IntentionallyWrongDslMarkerTargetsForBackwardsCompatibility(description = "Published without targets in 1.0.",)@DslMarkerpublic annotation class HtmlDsl
Wrong marker targets are never good API design, so this annotation bakes its only accepted
reason - backwards compatibility - into its name: it takes no reason parameter, just an
optional description for extra context. New DSL markers should declare effective
targets instead of reaching for this exemption.
Configuration
apiWatchdog {dslMarkerWithoutExplicitTargets = WatchdogSeverity.WARNING}
With direct compiler invocation:
-P plugin:org.jetbrains.kotlin.library.api.watchdog:diagnosticSeverity=DSL_MARKER_WITHOUT_EXPLICIT_TARGETS:warning
See also
- Scope control: @DslMarker
- DSL markers with no-op targets, the sibling check for markers that
declare an explicit
@Targetbut still list ineffective ones - Exemptions and internal API