All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tschuchort.compiletesting.MainComponentRegistrar.kt Maven / Gradle / Ivy

/*
 * Copyright 2010-2016 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
@file:Suppress("DEPRECATION")
package com.tschuchort.compiletesting

import com.google.auto.service.AutoService
import org.jetbrains.kotlin.com.intellij.mock.MockProject
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import org.jetbrains.kotlin.config.CommonConfigurationKeys.USE_FIR
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.kapt3.base.KaptOptions
import org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor

@ExperimentalCompilerApi
@AutoService(ComponentRegistrar::class, CompilerPluginRegistrar::class)
internal class MainComponentRegistrar : ComponentRegistrar, CompilerPluginRegistrar() {

  override val supportsK2: Boolean
    get() = getThreadLocalParameters("supportsK2")?.supportsK2 != false

  // Handle unset parameters gracefully because this plugin may be accidentally called by other tools that
  // discover it on the classpath (for example the kotlin jupyter kernel).
  private fun getThreadLocalParameters(caller: String): ThreadLocalParameters? {
    val params = threadLocalParameters.get()
    if (params == null) {
      System.err.println("WARNING: ${MainComponentRegistrar::class.simpleName}::$caller accessed before thread local parameters have been set")
    }

    return params
  }

  override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
    val parameters = getThreadLocalParameters("registerExtensions") ?: return

    parameters.compilerPluginRegistrar.forEach { pluginRegistrar ->
      with(pluginRegistrar) {
        registerExtensions(configuration)
      }
    }
  }

  // Legacy plugins
  override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
    val parameters = getThreadLocalParameters("registerProjectComponents") ?: return

    /*
     * The order of registering plugins here matters. If the kapt plugin is registered first, then
     * it will be executed first and any changes made to the AST by later plugins won't apply to the
     * generated stub files and thus won't be visible to any annotation processors. So we decided
     * to register third-party plugins before kapt and hope that it works, although we don't
     * know for sure if that is the correct way.
     */
    parameters.componentRegistrars.forEach { componentRegistrar ->
      componentRegistrar.registerProjectComponents(project, configuration)
    }

    if (!configuration.getBoolean(USE_FIR)) {
      KaptComponentRegistrar(parameters.processors, parameters.kaptOptions)
        .registerProjectComponents(project, configuration)
    }
  }

  companion object {
    /*
     * This compiler plugin is instantiated by K2JVMCompiler using
     * a service locator. So we can't just pass parameters to it easily.
     * Instead, we need to use a thread-local global variable to pass
     * any parameters that change between compilations
     */
    val threadLocalParameters: ThreadLocal = ThreadLocal()
  }

  data class ThreadLocalParameters(
    val processors: List,
    val kaptOptions: KaptOptions.Builder,
    val componentRegistrars: List,
    val compilerPluginRegistrar: List,
    val supportsK2: Boolean,
  )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy