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

addProjectService

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

registers a project service instance once all project components are initialized. Contrary to addAppService this extension only works for existing services that have been declared in the plugin.xml, due to it’s current implementation in the Meta internals.

Parameters

instance -

hijacks the existing instance A from the IDE and registers the new instance A. The hijacked instance is preserved, when instance returns null. There are several use-cases like org.jetbrains.kotlin.caches.resolve.KotlinCacheService for project-level services. The following example registers a logger for the KotlinCacheService by hijacking it’s standard implementation from the kotlin plugin.

import arrow.meta.ide.MetaIde
import arrow.meta.ide.IdePlugin
import arrow.meta.ide.invoke
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache
//sampleStart
val MetaIde.logKotlinCachePlugin: IdePlugin
  get() = "Log Kotlin Cache Plugin" {
    meta(
      addProjectService(KotlinCacheService::class.java) { project: Project, kotlinCache: KotlinCacheService? ->
        kotlinCache?.let(::logKotlinCache)
      }
    )
  }
//sampleEnd
fun logKotlinCache(delegate: KotlinCacheService): KotlinCacheService =
  object : KotlinCacheService by delegate {
    override fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade {
      println("Meaningful Log message for $elements")
      return delegate.getResolutionFacade(elements)
    }

    override fun getResolutionFacade(elements: List<KtElement>, platform: TargetPlatform): ResolutionFacade {
      println("Meaningful Log message for $elements based on target:$platform")
      return delegate.getResolutionFacade(elements, platform)
    }

    override fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade? {
      println("Meaningful Log message for $file based on target:$platform")
      return delegate.getResolutionFacadeByFile(file, platform)
    }

    override fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? {
      println("Meaningful Log message for module ${moduleInfo.name} based on target:$platform")
      return delegate.getResolutionFacadeByModuleInfo(moduleInfo, platform)
    }

    override fun getSuppressionCache(): KotlinSuppressCache {
      println("Meaningful Log message for KotlinSuppressCache")
      return delegate.getSuppressionCache()
    }
  }

With this example in mind, the usage of KotlinCacheService implies logging the example output on console.

Do you like Arrow?

Arrow Org
<