1 package org.jetbrains.dokka.Utilities
2 
3 import com.google.inject.Binder
4 import com.google.inject.Module
5 import com.google.inject.TypeLiteral
6 import com.google.inject.binder.AnnotatedBindingBuilder
7 import com.google.inject.name.Names
8 import org.jetbrains.dokka.*
9 import org.jetbrains.dokka.Formats.FormatDescriptor
10 import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
11 import java.io.File
12 import kotlin.reflect.KClass
13 
14 const val impliedPlatformsName = "impliedPlatforms"
15 
16 class DokkaAnalysisModule(val environment: AnalysisEnvironment,
17                           val options: DocumentationOptions,
18                           val defaultPlatformsProvider: DefaultPlatformsProvider,
19                           val nodeReferenceGraph: NodeReferenceGraph,
20                           val logger: DokkaLogger) : Module {
configurenull21     override fun configure(binder: Binder) {
22         binder.bind<DokkaLogger>().toInstance(logger)
23 
24         val coreEnvironment = environment.createCoreEnvironment()
25         binder.bind<KotlinCoreEnvironment>().toInstance(coreEnvironment)
26 
27         val (dokkaResolutionFacade, libraryResolutionFacade) = environment.createResolutionFacade(coreEnvironment)
28         binder.bind<DokkaResolutionFacade>().toInstance(dokkaResolutionFacade)
29         binder.bind<DokkaResolutionFacade>().annotatedWith(Names.named("libraryResolutionFacade")).toInstance(libraryResolutionFacade)
30 
31         binder.bind<DocumentationOptions>().toInstance(options)
32 
33         binder.bind<DefaultPlatformsProvider>().toInstance(defaultPlatformsProvider)
34 
35         binder.bind<NodeReferenceGraph>().toInstance(nodeReferenceGraph)
36 
37         val descriptor = ServiceLocator.lookup<FormatDescriptor>("format", options.outputFormat)
38         descriptor.configureAnalysis(binder)
39     }
40 }
41 
42 object StringListType : TypeLiteral<@JvmSuppressWildcards List<String>>()
43 
44 class DokkaOutputModule(val options: DocumentationOptions,
45                         val logger: DokkaLogger) : Module {
configurenull46     override fun configure(binder: Binder) {
47         binder.bind(File::class.java).annotatedWith(Names.named("outputDir")).toInstance(File(options.outputDir))
48 
49         binder.bind<DocumentationOptions>().toInstance(options)
50         binder.bind<DokkaLogger>().toInstance(logger)
51         binder.bind(StringListType).annotatedWith(Names.named(impliedPlatformsName)).toInstance(options.impliedPlatforms)
52         binder.bind<String>().annotatedWith(Names.named("outlineRoot")).toInstance(options.outlineRoot)
53         binder.bind<String>().annotatedWith(Names.named("dacRoot")).toInstance(options.dacRoot)
54         binder.bind<Boolean>().annotatedWith(Names.named("generateClassIndex")).toInstance(options.generateClassIndexPage)
55         binder.bind<Boolean>().annotatedWith(Names.named("generatePackageIndex")).toInstance(options.generatePackageIndexPage)
56         val descriptor = ServiceLocator.lookup<FormatDescriptor>("format", options.outputFormat)
57 
58         descriptor.configureOutput(binder)
59     }
60 }
61 
registerCategorynull62 private inline fun <reified T: Any> Binder.registerCategory(category: String) {
63     ServiceLocator.allServices(category).forEach {
64         @Suppress("UNCHECKED_CAST")
65         bind(T::class.java).annotatedWith(Names.named(it.name)).to(T::class.java.classLoader.loadClass(it.className) as Class<T>)
66     }
67 }
68 
bindNameAnnotatednull69 private inline fun <reified Base : Any, reified T : Base> Binder.bindNameAnnotated(name: String) {
70     bind(Base::class.java).annotatedWith(Names.named(name)).to(T::class.java)
71 }
72 
73 
bindnull74 inline fun <reified T: Any> Binder.bind(): AnnotatedBindingBuilder<T> = bind(T::class.java)
75 
76 inline fun <reified T: Any> Binder.lazyBind(): Lazy<AnnotatedBindingBuilder<T>> = lazy { bind(T::class.java) }
77 
toOptionalnull78 inline infix fun <reified T: Any, TKClass: KClass<out T>> Lazy<AnnotatedBindingBuilder<T>>.toOptional(kClass: TKClass?) =
79         kClass?.let { value toType it }
80 
toTypenull81 inline infix fun <reified T: Any, TKClass: KClass<out T>> AnnotatedBindingBuilder<T>.toType(kClass: TKClass) = to(kClass.java)
82