# Question about extending PsiDocumentationTargetProvider

**URL:** <https://platform.jetbrains.com/t/question-about-extending-psidocumentationtargetprovider/5016>\
**Category:** IntelliJ Platform\
**Tags:** plugin-development\
**Created:** [September 7, 2026, 12:50am UTC](https://platform.jetbrains.com/t/question-about-extending-psidocumentationtargetprovider/5016 "2026-09-07T00:50:36Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![bitspittle](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/bitspittle/32/209_2.png) [@bitspittle](https://platform.jetbrains.com/u/bitspittle)\
**Post date:** [September 7, 2026, 12:50am UTC](https://platform.jetbrains.com/t/question-about-extending-psidocumentationtargetprovider/5016/1 "2026-09-07T00:50:37Z")

</div>

SHORT VERSION: Is there a way I can extend `PsiDocumentationTargetProvider` to add an additional page of docs on top of the KDoc page that is already shown?

* * *

I am working on a Kotlin framework that wraps, among other things, web CSS properties. I am also writing an IDEA plugin for working with this framework.

What I would like to do is _extend_ the existing Kotlin “quick documentation” popup with an additional page that shows the CSS documentation from the MDN.

For example, the quick docs for `Modifier.backgroundColor` would show the KDoc I wrote for that function on page 1 / 2, and the MDN docs for the `background-color` property on page 2 / 2.

However, the way that `PsiDocumentationTargetProvider` works (it seems) is it finds the first docs provider that matches and stops there. Which means I can show _either_ MDN docs _or_ KDocs but not both.

The way I “fixed” this was by basically instantiating an instance of `KotlinPsiDocumentationTargetProvider` myself and then calling `kotlinDocProvider.documentationTargets(element, originalElement)` to get the KDocs, and to that result I add my own additional documentation target as an additional entry. In `plugin.xml` I also declared that my documentation provider should be triggered before the kotlin documentation provider. And that worked!

However, it did trigger a verification violation:

```auto
Override-only method
PsiDocumentationTargetProvider.documentationTargets(PsiElement, PsiElement) 

is invoked in 
CssModifierDocumentationTargetProvider.documentationTargets(PsiElement, PsiElement) : List.
This method is marked with @ApiStatus.OverrideOnly annotation, which indicates that
the method must be only overridden but not invoked by client code. See documentation
of the @ApiStatus.OverrideOnly for more info.

```

but the `verifyPlugin` task still passed at the time. This was with `intellij-platform` version `2.10.5`.

I just upgraded to `2.18.1` and it seems like the violation has been upgraded into an error.

Is there another way I’m supposed to be doing this? Is this going to get my plugin rejected in the future, meaning I need to back the feature out?

* * *

The following is all relevant code:

**Plugin.xml**

```xml
<platform.backend.documentation.psiTargetProvider
  order="before KotlinDocumentationTargetProvider"
  implementation="com.varabyte.kobweb.intellij.docs.CssModifierDocumentationTargetProvider"/>

```

**CssModifierDocumentationTargetProvider.kt**

```kotlin
private val MODIFIER_ID = ClassId.fromString("com/varabyte/kobweb/compose/ui/Modifier")

class CssModifierDocumentationTarget(val cssPropertyName: String, val element: PsiElement) : DocumentationTarget {
    override fun computePresentation(): TargetPresentation =
        TargetPresentation.builder(cssPropertyName)
            .icon(com.intellij.icons.AllIcons.FileTypes.Css)
            .presentation()

    override fun computeDocumentation(): DocumentationResult? {
        val mdnDoc = getCssMdnDocumentation(cssPropertyName, MdnCssSymbolKind.Property)
            ?: return null
        val html = mdnDoc.getDocumentation(withDefinition = true)
        return DocumentationResult.documentation(html).externalUrl(mdnDoc.url)
    }

    override fun createPointer(): Pointer<out DocumentationTarget> {
        val elementPointer = element.createSmartPointer()

        return Pointer {
            elementPointer.element?.let {
                CssModifierDocumentationTarget(cssPropertyName, it)
            }
        }
    }
}

/**
 * Provides documentation for CSS modifier functions tied to CSS properties.
 *
 * For example, `Modifier.backgroundColor(...)` will show the MDN documentation for the `background-color` CSS property
 * on the second page.
 */
class CssModifierDocumentationTargetProvider : PsiDocumentationTargetProvider {
    val kotlinDocProvider = KotlinPsiDocumentationTargetProvider()

    override fun documentationTargets(
        element: PsiElement,
        originalElement: PsiElement?,
    ): List<DocumentationTarget> {
        return kotlinDocProvider.documentationTargets(element, originalElement) +
                listOfNotNull(documentationTarget(element))
    }

    private fun documentationTarget(element: PsiElement): DocumentationTarget? {
        val function = element.asKtNamedFunction() ?: return null

        analyze(function) {
            if (function.receiverTypeReference?.type?.isClassType(MODIFIER_ID) != true) {
                return null
            }
            if (!function.returnType.isClassType(MODIFIER_ID)) {
                return null
            }
        }

        val propertyName = function.name?.camelCaseToKebabCase() ?: return null

        return CssModifierDocumentationTarget(propertyName, element)
    }
}

```

And the line that is blowing up the verifier is:

```kotlin
return kotlinDocProvider.documentationTargets(element, originalElement) +

```

---

<div class="post-metadata">

**Author:** ![bitspittle](https://sea1.discourse-cdn.com/flex001/user_avatar/platform.jetbrains.com/bitspittle/32/209_2.png) [@bitspittle](https://platform.jetbrains.com/u/bitspittle)\
**Post date:** [September 8, 2026, 3:40pm UTC](https://platform.jetbrains.com/t/question-about-extending-psidocumentationtargetprovider/5016/2 "2026-09-08T15:40:37Z")

</div>

In case this ever gets to the relevant team, here are some possibilities that I could think of on how to move forward:

1. Update the behavior of the documentation provider to be additive instead of “first success”

2. Make it so that I can create a KDoc `DocumentationTarget` myself (currently, all of the classes around that are declared internal, meaning I can only create them indirectly through a KotlinDocumentationTargetProvider, which the verifier step is preventing here)

3. Remove the `OverrideOnly` annotation from `PsiDocumentationTargetProvider`

4. Make `KotlinDocumentationTargetProvider` an open class that can be inherited (I don’t like having open classes that aren’t abstract, but with `OverrideOnly`, delegation has been taken off the table)
