package org.jetbrains.dokka.Utilities import com.google.inject.Binder import com.google.inject.Module import com.google.inject.TypeLiteral import com.google.inject.binder.AnnotatedBindingBuilder import com.google.inject.name.Names import org.jetbrains.dokka.* import org.jetbrains.dokka.Formats.FormatDescriptor import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import java.io.File import kotlin.reflect.KClass const val impliedPlatformsName = "impliedPlatforms" class DokkaRunModule(val configuration: DokkaConfiguration) : Module { override fun configure(binder: Binder) { binder.bind().toInstance(configuration) binder.bind(StringListType).annotatedWith(Names.named(impliedPlatformsName)).toInstance(configuration.impliedPlatforms) binder.bind(File::class.java).annotatedWith(Names.named("outputDir")).toInstance(File(configuration.outputDir)) } } class DokkaAnalysisModule(val environment: AnalysisEnvironment, val configuration: DokkaConfiguration, val defaultPlatformsProvider: DefaultPlatformsProvider, val nodeReferenceGraph: NodeReferenceGraph, val passConfiguration: DokkaConfiguration.PassConfiguration, val logger: DokkaLogger) : Module { override fun configure(binder: Binder) { binder.bind().toInstance(logger) val coreEnvironment = environment.createCoreEnvironment() binder.bind().toInstance(coreEnvironment) val (dokkaResolutionFacade, libraryResolutionFacade) = environment.createResolutionFacade(coreEnvironment) binder.bind().toInstance(dokkaResolutionFacade) binder.bind().annotatedWith(Names.named("libraryResolutionFacade")).toInstance(libraryResolutionFacade) binder.bind().toInstance(passConfiguration) binder.bind().toInstance(defaultPlatformsProvider) binder.bind().toInstance(nodeReferenceGraph) val descriptor = ServiceLocator.lookup("format", configuration.format) descriptor.configureAnalysis(binder) } } object StringListType : TypeLiteral<@JvmSuppressWildcards List>() class DokkaOutputModule(val configuration: DokkaConfiguration, val logger: DokkaLogger) : Module { override fun configure(binder: Binder) { binder.bind().toInstance(logger) val descriptor = ServiceLocator.lookup("format", configuration.format) descriptor.configureOutput(binder) } } private inline fun Binder.registerCategory(category: String) { ServiceLocator.allServices(category).forEach { @Suppress("UNCHECKED_CAST") bind(T::class.java).annotatedWith(Names.named(it.name)).to(T::class.java.classLoader.loadClass(it.className) as Class) } } private inline fun Binder.bindNameAnnotated(name: String) { bind(Base::class.java).annotatedWith(Names.named(name)).to(T::class.java) } inline fun Binder.bind(): AnnotatedBindingBuilder = bind(T::class.java) inline fun Binder.lazyBind(): Lazy> = lazy { bind(T::class.java) } inline infix fun > Lazy>.toOptional(kClass: TKClass?) = kClass?.let { value toType it } inline infix fun > AnnotatedBindingBuilder.toType(kClass: TKClass) = to(kClass.java)