diff options
| author | sebastian.sellmair <sebastian.sellmair@jetbrains.com> | 2020-06-24 09:14:37 +0200 |
|---|---|---|
| committer | Paweł Marks <pmarks@virtuslab.com> | 2020-06-25 19:50:22 +0200 |
| commit | 08f40e2a13006882e8f8425f111b8527e7bbcb0f (patch) | |
| tree | 1052c35c75fccaa044a73b33e5f0b5adae4c0f57 /kotlin-analysis | |
| parent | cf2e842da89f0effa6bdb5eb942b250c94360b5c (diff) | |
| download | dokka-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')
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 |
