aboutsummaryrefslogtreecommitdiff
path: root/kotlin-analysis
diff options
context:
space:
mode:
authorsebastian.sellmair <sebastian.sellmair@jetbrains.com>2020-06-24 09:14:37 +0200
committerPaweł Marks <pmarks@virtuslab.com>2020-06-25 19:50:22 +0200
commit08f40e2a13006882e8f8425f111b8527e7bbcb0f (patch)
tree1052c35c75fccaa044a73b33e5f0b5adae4c0f57 /kotlin-analysis
parentcf2e842da89f0effa6bdb5eb942b250c94360b5c (diff)
downloaddokka-08f40e2a13006882e8f8425f111b8527e7bbcb0f.tar.gz
dokka-08f40e2a13006882e8f8425f111b8527e7bbcb0f.tar.bz2
dokka-08f40e2a13006882e8f8425f111b8527e7bbcb0f.zip
Remove kotlin source analysis from :core to :kotlin-analysis (thanks to Afzal Najam)
Diffstat (limited to 'kotlin-analysis')
-rw-r--r--kotlin-analysis/build.gradle.kts27
-rw-r--r--kotlin-analysis/dependencies/build.gradle.kts67
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt636
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt31
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt42
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreProjectFileIndex.kt515
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt38
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt44
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt14
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt59
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JavaResolveExtension.kt128
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt46
-rw-r--r--kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt51
13 files changed, 1698 insertions, 0 deletions
diff --git a/kotlin-analysis/build.gradle.kts b/kotlin-analysis/build.gradle.kts
new file mode 100644
index 00000000..67480f82
--- /dev/null
+++ b/kotlin-analysis/build.gradle.kts
@@ -0,0 +1,27 @@
+import org.jetbrains.configureBintrayPublication
+
+plugins {
+ id("com.github.johnrengelman.shadow")
+ `maven-publish`
+ id("com.jfrog.bintray")
+}
+
+dependencies {
+ compileOnly(project(":core"))
+
+ val kotlin_version: String by project
+ api("org.jetbrains.kotlin:kotlin-compiler:$kotlin_version")
+
+ api(project(":kotlin-analysis:dependencies", configuration = "shadow"))
+}
+
+publishing {
+ publications {
+ register<MavenPublication>("analysis") {
+ artifactId = "dokka-analysis"
+ from(components["java"])
+ }
+ }
+}
+
+configureBintrayPublication("analysis")
diff --git a/kotlin-analysis/dependencies/build.gradle.kts b/kotlin-analysis/dependencies/build.gradle.kts
new file mode 100644
index 00000000..5bba6422
--- /dev/null
+++ b/kotlin-analysis/dependencies/build.gradle.kts
@@ -0,0 +1,67 @@
+import org.jetbrains.configureBintrayPublication
+
+
+plugins {
+ id("com.github.johnrengelman.shadow")
+ `maven-publish`
+ id("com.jfrog.bintray")
+}
+
+repositories {
+ maven(url = "https://www.jetbrains.com/intellij-repository/snapshots")
+ maven(url = "https://www.jetbrains.com/intellij-repository/releases")
+ maven(url = "https://kotlin.bintray.com/kotlin-plugin")
+}
+
+val intellijCore: Configuration by configurations.creating
+
+fun intellijCoreAnalysis() = zipTree(intellijCore.singleFile).matching {
+ include("intellij-core-analysis.jar")
+}
+
+dependencies {
+ val kotlin_plugin_version: String by project
+ api("org.jetbrains.kotlin:ide-common-ij193:$kotlin_plugin_version")
+ api("org.jetbrains.kotlin:kotlin-plugin-ij193:$kotlin_plugin_version") {
+ //TODO: parametrize ij version after 1.3.70
+ isTransitive = false
+ }
+
+ val idea_version: String by project
+ intellijCore("com.jetbrains.intellij.idea:intellij-core:$idea_version")
+ implementation(intellijCoreAnalysis())
+
+ implementation("org.jetbrains:markdown:0.1.41") {
+ because("it's published only on bintray")
+ }
+}
+
+tasks {
+ shadowJar {
+ val dokka_version: String by project
+ archiveFileName.set("dokka-kotlin-analysis-dependencies-$dokka_version.jar")
+ archiveClassifier.set("")
+
+ exclude("colorScheme/**")
+ exclude("fileTemplates/**")
+ exclude("inspectionDescriptions/**")
+ exclude("intentionDescriptions/**")
+ exclude("tips/**")
+ exclude("messages/**")
+ exclude("src/**")
+ exclude("**/*.kotlin_metadata")
+ exclude("**/*.kotlin_builtins")
+ }
+}
+
+
+publishing {
+ publications {
+ register<MavenPublication>("kotlin-analysis-dependencies") {
+ artifactId = "kotlin-analysis-dependencies"
+ project.shadow.component(this)
+ }
+ }
+}
+
+configureBintrayPublication("kotlin-analysis-dependencies")
diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt
new file mode 100644
index 00000000..7836bde9
--- /dev/null
+++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt
@@ -0,0 +1,636 @@
+package org.jetbrains.dokka.analysis
+
+import com.google.common.collect.ImmutableMap
+import com.intellij.core.CoreApplicationEnvironment
+import com.intellij.core.CoreModuleManager
+import com.intellij.mock.MockComponentManager
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.extensions.Extensions
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.module.ModuleManager
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.roots.OrderEnumerationHandler
+import com.intellij.openapi.roots.ProjectFileIndex
+import com.intellij.openapi.roots.ProjectRootManager
+import com.intellij.openapi.util.Disposer
+import com.intellij.openapi.vfs.StandardFileSystems
+import com.intellij.psi.PsiElement
+import com.intellij.psi.search.GlobalSearchScope
+import org.jetbrains.dokka.Platform
+import org.jetbrains.kotlin.analyzer.*
+import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
+import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
+import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
+import org.jetbrains.kotlin.builtins.DefaultBuiltIns
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
+import org.jetbrains.kotlin.caches.resolve.*
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.common.config.ContentRoot
+import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
+import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
+import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
+import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
+import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
+import org.jetbrains.kotlin.cli.jvm.config.*
+import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
+import org.jetbrains.kotlin.config.*
+import org.jetbrains.kotlin.container.getService
+import org.jetbrains.kotlin.container.tryGetService
+import org.jetbrains.kotlin.context.ProjectContext
+import org.jetbrains.kotlin.context.withModule
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
+import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory
+import org.jetbrains.kotlin.js.config.JSConfigurationKeys
+import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
+import org.jetbrains.kotlin.library.impl.createKotlinLibrary
+import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.platform.CommonPlatforms
+import org.jetbrains.kotlin.platform.TargetPlatform
+import org.jetbrains.kotlin.platform.js.JsPlatforms
+import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
+import org.jetbrains.kotlin.platform.jvm.JvmPlatforms.unspecifiedJvmPlatform
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.CompilerEnvironment
+import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
+import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
+import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
+import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory
+import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
+import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
+import org.jetbrains.kotlin.resolve.lazy.ResolveSession
+import org.jetbrains.kotlin.types.KotlinType
+import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
+import org.jetbrains.kotlin.util.slicedMap.WritableSlice
+import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
+import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor
+import org.jetbrains.kotlin.ide.konan.NativePlatformKindResolution
+import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
+import org.jetbrains.kotlin.platform.IdePlatformKind
+import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
+import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
+import org.jetbrains.kotlin.platform.konan.NativePlatforms
+import java.io.File
+
+const val JAR_SEPARATOR = "!/"
+const val KLIB_EXTENSION = "klib"
+
+/**
+ * Kotlin as a service entry point
+ *
+ * Configures environment, analyses files and provides facilities to perform code processing without emitting bytecode
+ *
+ * $messageCollector: required by compiler infrastructure and will receive all compiler messages
+ * $body: optional and can be used to configure environment without creating local variable
+ */
+class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPlatform: Platform) : Disposable {
+ val configuration = CompilerConfiguration()
+
+ init {
+ configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
+ }
+
+ fun createCoreEnvironment(): KotlinCoreEnvironment {
+ System.setProperty("idea.io.use.nio2", "true")
+
+ val configFiles = when (analysisPlatform) {
+ Platform.jvm, Platform.common -> EnvironmentConfigFiles.JVM_CONFIG_FILES
+ Platform.native -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES
+ Platform.js -> EnvironmentConfigFiles.JS_CONFIG_FILES
+ }
+
+ val environment = KotlinCoreEnvironment.createForProduction(this, configuration, configFiles)
+ val projectComponentManager = environment.project as MockComponentManager
+
+ val projectFileIndex = CoreProjectFileIndex(
+ environment.project,
+ environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS)
+ )
+
+ val moduleManager = object : CoreModuleManager(environment.project, this) {
+ override fun getModules(): Array<out Module> = arrayOf(projectFileIndex.module)
+ }
+
+ CoreApplicationEnvironment.registerComponentInstance(
+ projectComponentManager.picoContainer,
+ ModuleManager::class.java, moduleManager
+ )
+
+ CoreApplicationEnvironment.registerExtensionPoint(
+ Extensions.getRootArea(),
+ OrderEnumerationHandler.EP_NAME, OrderEnumerationHandler.Factory::class.java
+ )
+
+ projectComponentManager.registerService(
+ ProjectFileIndex::class.java,
+ projectFileIndex
+ )
+
+ projectComponentManager.registerService(
+ ProjectRootManager::class.java,
+ CoreProjectRootManager(projectFileIndex)
+ )
+
+ registerExtensionPoint(
+ ApplicationExtensionDescriptor("org.jetbrains.kotlin.idePlatformKind", IdePlatformKind::class.java),
+ listOf(
+ CommonIdePlatformKind,
+ JvmIdePlatformKind,
+ JsIdePlatformKind,
+ NativeIdePlatformKind
+ )
+ )
+
+ registerExtensionPoint(
+ IdePlatformKindResolution,
+ listOf(
+ CommonPlatformKindResolution(),
+ JvmPlatformKindResolution(),
+ JsPlatformKindResolution(),
+ NativePlatformKindResolution()
+ )
+ )
+
+ return environment
+ }
+
+ private fun createSourceModuleSearchScope(project: Project, sourceFiles: List<KtFile>): GlobalSearchScope =
+ when (analysisPlatform) {
+ Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
+ Platform.js, Platform.common, Platform.native -> GlobalSearchScope.filesScope(
+ project,
+ sourceFiles.map { it.virtualFile }.toSet()
+ )
+ }
+
+ fun createResolutionFacade(environment: KotlinCoreEnvironment): Pair<DokkaResolutionFacade, DokkaResolutionFacade> {
+ val projectContext = ProjectContext(environment.project, "Dokka")
+ val sourceFiles = environment.getSourceFiles()
+
+
+ val targetPlatform = when (analysisPlatform) {
+ Platform.js -> JsPlatforms.defaultJsPlatform
+ Platform.common -> CommonPlatforms.defaultCommonPlatform
+ Platform.native -> NativePlatforms.unspecifiedNativePlatform
+ Platform.jvm -> JvmPlatforms.defaultJvmPlatform
+ }
+
+ val nativeLibraries = classpath.filter { it.extension == KLIB_EXTENSION }
+ .map { createNativeLibraryModuleInfo(it) }
+
+ val library = object : LibraryModuleInfo {
+ override val analyzerServices: PlatformDependentAnalyzerServices =
+ analysisPlatform.analyzerServices()
+ override val name: Name = Name.special("<library>")
+ override val platform: TargetPlatform = targetPlatform
+ override fun dependencies(): List<ModuleInfo> = listOf(this)
+ override fun getLibraryRoots(): Collection<String> =
+ classpath.filterNot { it.extension == KLIB_EXTENSION }.map { it.absolutePath }
+ }
+
+ val module = object : ModuleInfo {
+ override val analyzerServices: PlatformDependentAnalyzerServices =
+ analysisPlatform.analyzerServices()
+ override val name: Name = Name.special("<module>")
+ override val platform: TargetPlatform = targetPlatform
+ override fun dependencies(): List<ModuleInfo> = listOf(this, library) + nativeLibraries
+ }
+
+ val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles)
+ val modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo> = {
+ when (it) {
+ library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope))
+ module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project))
+ in nativeLibraries -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope))
+ else -> throw IllegalArgumentException("Unexpected module info")
+ }
+ }
+
+ var builtIns: JvmBuiltIns? = null
+
+ val resolverForProject = when (analysisPlatform) {
+ Platform.jvm -> {
+ builtIns = JvmBuiltIns(
+ projectContext.storageManager,
+ JvmBuiltIns.Kind.FROM_CLASS_LOADER
+ ) // TODO we should use FROM_DEPENDENCIES
+ createJvmResolverForProject(
+ projectContext,
+ module,
+ library,
+ modulesContent,
+ sourcesScope,
+ builtIns
+ )
+ }
+ Platform.common -> createCommonResolverForProject(
+ projectContext,
+ module,
+ library,
+ modulesContent,
+ environment
+ )
+ Platform.js -> createJsResolverForProject(projectContext, module, library, modulesContent)
+ Platform.native -> createNativeResolverForProject(projectContext, module, library, modulesContent)
+
+ }
+ val libraryModuleDescriptor = resolverForProject.descriptorForModule(library)
+ val moduleDescriptor = resolverForProject.descriptorForModule(module)
+ builtIns?.initialize(moduleDescriptor, true)
+
+ val resolverForLibrary =
+ resolverForProject.resolverForModule(library) // Required before module to initialize library properly
+ val resolverForModule = resolverForProject.resolverForModule(module)
+ val libraryResolutionFacade =
+ DokkaResolutionFacade(
+ environment.project,
+ libraryModuleDescriptor,
+ resolverForLibrary
+ )
+ val created =
+ DokkaResolutionFacade(
+ environment.project,
+ moduleDescriptor,
+ resolverForModule
+ )
+ val projectComponentManager = environment.project as MockComponentManager
+ projectComponentManager.registerService(KotlinCacheService::class.java,
+ CoreKotlinCacheService(created)
+ )
+
+ return created to libraryResolutionFacade
+ }
+
+ private fun Platform.analyzerServices() = when (this) {
+ Platform.js -> JsPlatformAnalyzerServices
+ Platform.common -> CommonPlatformAnalyzerServices
+ Platform.native -> NativePlatformAnalyzerServices
+ Platform.jvm -> JvmPlatformAnalyzerServices
+ }
+
+ private fun createNativeLibraryModuleInfo(libraryFile: File): LibraryModuleInfo {
+ val kotlinLibrary = createKotlinLibrary(org.jetbrains.kotlin.konan.file.File(libraryFile.absolutePath), "",false)
+ return object : LibraryModuleInfo {
+ override val analyzerServices: PlatformDependentAnalyzerServices =
+ analysisPlatform.analyzerServices()
+ override val name: Name = Name.special("<klib>")
+ override val platform: TargetPlatform = NativePlatforms.unspecifiedNativePlatform
+ override fun dependencies(): List<ModuleInfo> = listOf(this)
+ override fun getLibraryRoots(): Collection<String> = listOf(libraryFile.absolutePath)
+ override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
+ get() = super.capabilities + (KlibModuleOrigin.CAPABILITY to kotlinLibrary)
+ }
+ }
+
+ private fun createCommonResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>,
+ environment: KotlinCoreEnvironment
+ ): ResolverForProject<ModuleInfo> {
+ return object : AbstractResolverForProject<ModuleInfo>(
+ "Dokka",
+ projectContext,
+ modules = listOf(module, library)
+ ) {
+ override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null
+
+ override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = modulesContent(module)
+
+ override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance
+
+ override fun createResolverForModule(
+ descriptor: ModuleDescriptor,
+ moduleInfo: ModuleInfo
+ ): ResolverForModule =
+ CommonResolverForModuleFactory(
+ CommonAnalysisParameters { content ->
+ environment.createPackagePartProvider(content.moduleContentScope)
+ },
+ CompilerEnvironment,
+ unspecifiedJvmPlatform,
+ true
+ ).createResolverForModule(
+ descriptor as ModuleDescriptorImpl,
+ projectContext.withModule(descriptor),
+ modulesContent(moduleInfo),
+ this,
+ LanguageVersionSettingsImpl.DEFAULT
+ )
+ }
+ }
+
+ private fun createJsResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>
+ ): ResolverForProject<ModuleInfo> {
+ return object : AbstractResolverForProject<ModuleInfo>(
+ "Dokka",
+ projectContext,
+ modules = listOf(module, library)
+ ) {
+ override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = modulesContent(module)
+ override fun createResolverForModule(
+ descriptor: ModuleDescriptor,
+ moduleInfo: ModuleInfo
+ ): ResolverForModule = JsResolverForModuleFactory(
+ CompilerEnvironment
+ ).createResolverForModule(
+ descriptor as ModuleDescriptorImpl,
+ projectContext.withModule(descriptor),
+ modulesContent(moduleInfo),
+ this,
+ LanguageVersionSettingsImpl.DEFAULT
+ )
+
+ override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance
+
+ override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null
+ }
+ }
+
+ private fun createNativeResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>
+ ): ResolverForProject<ModuleInfo> {
+ return object : AbstractResolverForProject<ModuleInfo>(
+ "Dokka",
+ projectContext,
+ modules = module.dependencies()
+ ) {
+ override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> = modulesContent(module)
+ override fun createResolverForModule(
+ descriptor: ModuleDescriptor,
+ moduleInfo: ModuleInfo
+ ): ResolverForModule {
+
+ return NativeResolverForModuleFactory(
+ PlatformAnalysisParameters.Empty,
+ CompilerEnvironment,
+ NativePlatforms.unspecifiedNativePlatform
+ ).createResolverForModule(
+ descriptor as ModuleDescriptorImpl,
+ projectContext.withModule(descriptor),
+ modulesContent(moduleInfo),
+ this,
+ LanguageVersionSettingsImpl.DEFAULT
+ )
+ }
+
+ override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance
+
+ override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null
+ }
+ }
+
+ private fun createJvmResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>,
+ sourcesScope: GlobalSearchScope,
+ builtIns: KotlinBuiltIns
+ ): ResolverForProject<ModuleInfo> {
+ val javaRoots = classpath
+ .mapNotNull {
+ val rootFile = when (it.extension) {
+ "jar" -> StandardFileSystems.jar().findFileByPath("${it.absolutePath}$JAR_SEPARATOR")
+ else -> StandardFileSystems.local().findFileByPath(it.absolutePath)
+ }
+ rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) }
+ }
+
+ return object : AbstractResolverForProject<ModuleInfo>(
+ "Dokka",
+ projectContext,
+ modules = listOf(module, library)
+ ) {
+ override fun modulesContent(module: ModuleInfo): ModuleContent<ModuleInfo> =
+ when (module) {
+ library -> ModuleContent(module, emptyList(), GlobalSearchScope.notScope(sourcesScope))
+ module -> ModuleContent(module, emptyList(), sourcesScope)
+ else -> throw IllegalArgumentException("Unexpected module info")
+ }
+
+ override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = builtIns
+
+ override fun createResolverForModule(
+ descriptor: ModuleDescriptor,
+ moduleInfo: ModuleInfo
+ ): ResolverForModule = JvmResolverForModuleFactory(
+ JvmPlatformParameters({ content ->
+ JvmPackagePartProvider(
+ configuration.languageVersionSettings,
+ content.moduleContentScope
+ )
+ .apply {
+ addRoots(javaRoots, messageCollector)
+ }
+ }, {
+ val file = (it as? BinaryJavaClass)?.virtualFile ?: (it as JavaClassImpl).psi.containingFile.virtualFile
+ if (file in sourcesScope)
+ module
+ else
+ library
+ }),
+ CompilerEnvironment,
+ unspecifiedJvmPlatform
+ ).createResolverForModule(
+ descriptor as ModuleDescriptorImpl,
+ projectContext.withModule(descriptor),
+ modulesContent(moduleInfo),
+ this,
+ LanguageVersionSettingsImpl.DEFAULT
+ )
+
+ override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null
+ }
+ }
+
+ fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) {
+ val languageVersion = LanguageVersion.fromVersionString(languageVersionString) ?: LanguageVersion.LATEST_STABLE
+ val apiVersion =
+ apiVersionString?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(languageVersion)
+ configuration.languageVersionSettings = LanguageVersionSettingsImpl(languageVersion, apiVersion)
+ }
+
+ /**
+ * Classpath for this environment.
+ */
+ val classpath: List<File>
+ get() = configuration.jvmClasspathRoots
+
+ /**
+ * Adds list of paths to classpath.
+ * $paths: collection of files to add
+ */
+ fun addClasspath(paths: List<File>) {
+ if (analysisPlatform == Platform.js) {
+ configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath })
+ }
+ configuration.addJvmClasspathRoots(paths)
+ }
+
+ /**
+ * Adds path to classpath.
+ * $path: path to add
+ */
+ fun addClasspath(path: File) {
+ if (analysisPlatform == Platform.js) {
+ configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath)
+ }
+ configuration.addJvmClasspathRoot(path)
+ }
+
+ /**
+ * List of source roots for this environment.
+ */
+ val sources: List<String>
+ get() = configuration.get(CLIConfigurationKeys.CONTENT_ROOTS)
+ ?.filterIsInstance<KotlinSourceRoot>()
+ ?.map { it.path } ?: emptyList()
+
+ /**
+ * Adds list of paths to source roots.
+ * $list: collection of files to add
+ */
+ fun addSources(list: List<String>) {
+ list.forEach {
+ configuration.addKotlinSourceRoot(it)
+ val file = File(it)
+ if (file.isDirectory || file.extension == ".java") {
+ configuration.addJavaSourceRoot(file)
+ }
+ }
+ }
+
+ fun addRoots(list: List<ContentRoot>) {
+ configuration.addAll(CLIConfigurationKeys.CONTENT_ROOTS, list)
+ }
+
+ /**
+ * Disposes the environment and frees all associated resources.
+ */
+ override fun dispose() {
+ Disposer.dispose(this)
+ }
+
+ companion object {
+ private fun <T : Any> registerExtensionPoint(
+ appExtension: ApplicationExtensionDescriptor<T>,
+ instances: List<T>
+ ) {
+ if (Extensions.getRootArea().hasExtensionPoint(appExtension.extensionPointName))
+ return
+
+ appExtension.registerExtensionPoint()
+ instances.forEach(appExtension::registerExtension)
+ }
+ }
+}
+
+fun contentRootFromPath(path: String): ContentRoot {
+ val file = File(path)
+ return if (file.extension == "java") JavaSourceRoot(file, null) else KotlinSourceRoot(path, false)
+}
+
+
+class DokkaResolutionFacade(
+ override val project: Project,
+ override val moduleDescriptor: ModuleDescriptor,
+ val resolverForModule: ResolverForModule
+) : ResolutionFacade {
+ override fun analyzeWithAllCompilerChecks(elements: Collection<KtElement>): AnalysisResult {
+ throw UnsupportedOperationException()
+ }
+
+ override fun <T : Any> tryGetFrontendService(element: PsiElement, serviceClass: Class<T>): T? {
+ return resolverForModule.componentProvider.tryGetService(serviceClass)
+ }
+
+ override fun resolveToDescriptor(
+ declaration: KtDeclaration,
+ bodyResolveMode: BodyResolveMode
+ ): DeclarationDescriptor {
+ return resolveSession.resolveToDescriptor(declaration)
+ }
+
+ override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext {
+ throw UnsupportedOperationException()
+ }
+
+ val resolveSession: ResolveSession get() = getFrontendService(ResolveSession::class.java)
+
+ override fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode): BindingContext {
+ if (element is KtDeclaration) {
+ val descriptor = resolveToDescriptor(element)
+ return object : BindingContext {
+ override fun <K : Any?, V : Any?> getKeys(p0: WritableSlice<K, V>?): Collection<K> {
+ throw UnsupportedOperationException()
+ }
+
+ override fun getType(p0: KtExpression): KotlinType? {
+ throw UnsupportedOperationException()
+ }
+
+ override fun <K : Any?, V : Any?> get(slice: ReadOnlySlice<K, V>?, key: K): V? {
+ if (key != element) {
+ throw UnsupportedOperationException()
+ }
+ return when {
+ slice == BindingContext.DECLARATION_TO_DESCRIPTOR -> descriptor as V
+ slice == BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER && (element as KtParameter).hasValOrVar() -> descriptor as V
+ else -> null
+ }
+ }
+
+ override fun getDiagnostics(): Diagnostics {
+ throw UnsupportedOperationException()
+ }
+
+ override fun addOwnDataTo(p0: BindingTrace, p1: Boolean) {
+ throw UnsupportedOperationException()
+ }
+
+ override fun <K : Any?, V : Any?> getSliceContents(p0: ReadOnlySlice<K, V>): ImmutableMap<K, V> {
+ throw UnsupportedOperationException()
+ }
+
+ }
+ }
+ throw UnsupportedOperationException()
+ }
+
+ override fun <T : Any> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
+ throw UnsupportedOperationException()
+ }
+
+ override fun <T : Any> getFrontendService(serviceClass: Class<T>): T {
+ return resolverForModule.componentProvider.getService(serviceClass)
+ }
+
+ override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
+ return resolverForModule.componentProvider.getService(serviceClass)
+ }
+
+ override fun <T : Any> getIdeService(serviceClass: Class<T>): T {
+ throw UnsupportedOperationException()
+ }
+
+}
diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt
new file mode 100644
index 00000000..ebfe20a5
--- /dev/null
+++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt
@@ -0,0 +1,31 @@
+package org.jetbrains.dokka.analysis
+
+import com.intellij.psi.PsiField
+import com.intellij.psi.PsiMethod
+import org.jetbrains.dokka.links.Callable
+import org.jetbrains.dokka.links.JavaClassReference
+import org.jetbrains.dokka.links.TypeReference
+import org.jetbrains.kotlin.descriptors.CallableDescriptor
+
+fun Callable.Companion.from(descriptor: CallableDescriptor) = with(descriptor) {
+ Callable(
+ name.asString(),
+ extensionReceiverParameter?.let { TypeReference.from(it) },
+ valueParameters.mapNotNull { TypeReference.from(it) }
+ )
+}
+
+fun Callable.Companion.from(psi: PsiMethod) = with(psi) {
+ Callable(
+ name,
+ null,
+ parameterList.parameters.map { param -> JavaClassReference(param.type.canonicalText) })
+}
+
+fun Callable.Companion.from(psi: PsiField): Callable {
+ return Callable(
+ name = psi.name,
+ receiver = null,
+ params = emptyList()
+ )
+}
diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt
new file mode 100644
index 00000000..68415875
--- /dev/null
+++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt
@@ -0,0 +1,42 @@
+package org.jetbrains.dokka.analysis
+
+import com.intellij.psi.PsiFile
+import org.jetbrains.dokka.analysis.DokkaResolutionFacade
+import org.jetbrains.kotlin.analyzer.ModuleInfo
+import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
+import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
+import org.jetbrains.kotlin.psi.KtElement
+import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache
+
+
+class CoreKotlinCacheService(private val resolutionFacade: DokkaResolutionFacade) : KotlinCacheService {
+ override fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade {
+ return resolutionFacade
+ }
+
+ override fun getResolutionFacade(
+ elements: List<KtElement>,
+ platform: org.jetbrains.kotlin.platform.TargetPlatform
+ ): ResolutionFacade {
+ return resolutionFacade
+ }
+
+ override fun getResolutionFacadeByFile(
+ file: PsiFile,
+ platform: org.jetbrains.kotlin.platform.Tar