# TargetElementEvaluator and wrapping PSI elements

**URL:** <https://platform.jetbrains.com/t/targetelementevaluator-and-wrapping-psi-elements/257>\
**Category:** IntelliJ Platform\
**Created:** [February 7, 2025, 11:30am UTC](https://platform.jetbrains.com/t/targetelementevaluator-and-wrapping-psi-elements/257 "2025-02-07T11:30:02Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![daniele\_athome](https://avatars.discourse-cdn.com/v4/letter/d/a9a28c/32.png) [@daniele\_athome](https://platform.jetbrains.com/u/daniele_athome)\
**Post date:** [February 7, 2025, 11:30am UTC](https://platform.jetbrains.com/t/targetelementevaluator-and-wrapping-psi-elements/257/1 "2025-02-07T11:30:02Z")

</div>

Hi there forum 👋  
I need to turn YAML scalars into references. Consider this example:

```yaml
automation:
  - alias: automation_name_1
    trigger:
       [...]

```

I wanted “Find usages” and the like from “automation\_name\_1” to work, but IntelliJ was complaining that I “_Cannot search for usages from this location. Place the caret on the element to find usages for and try again._”, despite [references from other files is working](https://github.com/daniele-athome/hass-intellij-plugin/blob/master/src/main/kotlin/it/casaricci/hass/plugin/psi/HassEntityReference.kt#L84) (if I use the notation `automation.automation_name_1` in any other YAML file, Ctrl+Click correctly brings me to the example I wrote above).

I’m guessing this is happening because `YAMLScalar` is not a `PsiNamedElement` (right?), so I looked for a way of turning it into a named element. I found two possible ways:

1. [override the parser definition](https://intellij-support.jetbrains.com/hc/en-us/community/posts/24307819476498-Overriding-ParserDefinition-vs-looking-up-in-PSI-when-needed), but it was deemed not recommended - and it caused constant 100% CPU usage for some reason
2. use `TargetElementEvaluator` and implement `getNamedElement` and `adjustReferenceOrReferencedElement` to return a wrapped element ([implementation here](https://github.com/daniele-athome/hass-intellij-plugin/blob/master/src/main/kotlin/it/casaricci/hass/plugin/language/HassElementEvaluator.kt))

I’m currently using approach 2, which leads me to [the wrapper class itself](https://github.com/daniele-athome/hass-intellij-plugin/blob/master/src/main/kotlin/it/casaricci/hass/plugin/language/HassAutomation.kt):

```kotlin
/**
 * Wraps the "alias" key value element of an automation, giving the element [PsiNamedElement] features.
 */
class HassAutomation(private val element: YAMLScalar) : PsiNamedElement, YAMLScalar by element {

    /**
     * Automation name is actually the value of the "alias" key.
     */
    override fun getName(): String {
        return element.textValue
    }

    /**
     * Copied from [YAMLKeyValueImpl] + [org.jetbrains.yaml.YAMLUtil], although it seems like overkill.
     */
    override fun setName(name: String): PsiElement {
        if (name == element.textValue) {
            throw IncorrectOperationException(YAMLBundle.message("rename.same.name"))
        }

        val elementGenerator = YAMLElementGenerator.getInstance(element.project)

        val tempFile: PsiFile = elementGenerator.createDummyYamlWithText(name)
        val textElement = PsiTreeUtil.collectElementsOfType(tempFile, YAMLScalar::class.java).iterator().next()

        element.replace(textElement)
        return this
    }
}

```

And it seems to be working! However, I don’t get “Jump to source” capability for some reason:

 ![automation_jump_to_source_missing](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/1X/a80ac6e3bc16dafd950a38d7de0456d09c4df101.png)

Unwrapped elements that already worked without the target element evaluator (because they are already named element, such as `YAMLKeyValue`) do have “Jump to source” capability:

 ![script_jump_to_source_present](https://us1.discourse-cdn.com/flex001/uploads/jetbrains_platform/original/1X/3b66c77270f6a58288c751494121fe90930b226b.png)

YAML for this case is:

```yaml
script:
  bedroom_turn_on_light_conditional: # the key is the reference in this case
    sequence:
      [...]

```

I must be doing something wrong here, however since the `TargetElementEvaluator` API is not documented I did my best to understand how it worked.

Here is the complete code to the plugin: [GitHub - daniele-athome/hass-intellij-plugin: Home Assistant IntelliJ plugin](https://github.com/daniele-athome/hass-intellij-plugin)

Thank you!
