package org.jetbrains.dokka.Utilities import com.google.inject.Binder import com.google.inject.Module import com.google.inject.Provider 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.dokka.Model.DescriptorSignatureProvider import org.jetbrains.dokka.Samples.SampleProcessingService import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import java.io.File import kotlin.reflect.KClass const val impliedPlatformsName = "impliedPlatforms" class DokkaAnalysisModule(val environment: AnalysisEnvironment, val options: DocumentationOptions, val defaultPlatformsProvider: DefaultPlatformsProvider, val nodeReferenceGraph: NodeReferenceGraph, val logger: DokkaLogger) : Module { override fun configure(binder: Binder) { binder.bind().toInstance(logger) binder.registerCategory("language") val coreEnvironment = environment.createCoreEnvironment() binder.bind().toInstance(coreEnvironment) val dokkaResolutionFacade = environment.createResolutionFacade(coreEnvironment) binder.bind().toInstance(dokkaResolutionFacade) binder.bind().toInstance(options) binder.bind().toInstance(defaultPlatformsProvider) binder.bind().toInstance(nodeReferenceGraph) val descriptor = ServiceLocator.lookup("format", options.outputFormat) descriptor.configureAnalysis(binder) } } object StringListType : TypeLiteral<@JvmSuppressWildcards List>() class DokkaOutputModule(val options: DocumentationOptions, val logger: DokkaLogger) : Module { override fun configure(binder: Binder) { binder.bind(LanguageService::class.java).to(KotlinLanguageService::class.java) binder.bind(File::class.java).annotatedWith(Names.named("outputDir")).toInstance(File(options.outputDir)) binder.bind().toInstance(options) binder.bind().toInstance(logger) binder.bind(StringListType).annotatedWith(Names.named(impliedPlatformsName)).toInstance(options.impliedPlatforms) val descriptor = ServiceLocator.lookup("format", options.outputFormat) 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 infix fun > AnnotatedBindingBuilder.toOptional(kClass: TKClass?) = kClass?.let { to(it.java) } inline infix fun > AnnotatedBindingBuilder.toType(kClass: TKClass) = to(kClass.java)