idea-plugin / arrow.meta.ide.dsl.application / ApplicationSyntax / addAppService

addAppService

open fun <A : Any> MetaIde.addAppService(service: Class<A>, instance: (A?) -> A?): ExtensionPhase

registers an application-level service and the instance. The IntelliJ Platform ensures that only one instance of instance per application is instantiated. even though the service can be retrieved multiple times with ServiceManager.getService or com.intellij.openapi.project.Project.getService for project-level services. It is impeccable that there is only one instance implementation for a given service to fulfill coherence in the ide. The ide will throw an exception, if that premise is not met.

import org.jetbrains.kotlin.psi.KtNamedFunction

interface MyService {
  fun printLn(f: KtNamedFunction): Unit
}
import arrow.meta.ide.MetaIde
import arrow.meta.ide.IdePlugin
import arrow.meta.ide.invoke
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.psi.KtNamedFunction

//sampleStart
val MetaIde.services: IdePlugin
  get() = "Register application-level services" {
    meta(
      addAppService(MyService::class.java) {
        object : MyService {
          override fun printLn(f: KtNamedFunction): Unit =
            println("Function: ${f.name} returns ${f.resolveToDescriptorIfAny()?.returnType ?: "ERROR"}")
        }
      }
    )
  }

//sampleEnd
interface MyService {
  fun printLn(f: KtNamedFunction): Unit
}

The service is now available at runtime and there is also the option to utilise project-level services with addProjectService - please check the Docs on how to register those.

import arrow.meta.ide.MetaIde
import arrow.meta.ide.IdePlugin
import arrow.meta.ide.invoke
import com.intellij.lang.annotation.Annotator
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
//sampleStart
val MetaIde.logAnnotator: IdePlugin
  get() = "Log Annotator" {
    meta(
      addAnnotator( // Annotators traverse PsiElements and are means to write language Plugins
        annotator = Annotator { element, holder ->
          val project = element.project
          project.getService(MyProjectService::class.java)?.hello(element)

          element.safeAs<KtNamedFunction>()?.let { f ->
            ServiceManager.getService(MyAppService::class.java)?.printLn(f)
          }
        }
      )
    )
  }

//sampleEnd
interface MyAppService {
  fun printLn(f: KtNamedFunction): Unit
}

interface MyProjectService {
  val project: Project
  fun hello(element: PsiElement): Unit
}

See Also

AnnotatorSyntax

Do you like Arrow?

Arrow Org
<