From 9ea429920e07c77e1241c4beb172bb36735af783 Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Tue, 10 Jul 2018 19:27:16 +0300 Subject: Add js platform support --- .../main/kotlin/Analysis/AnalysisEnvironment.kt | 110 +++++++++++++++++---- core/src/main/kotlin/Generation/DokkaGenerator.kt | 24 +++-- .../main/kotlin/Generation/configurationImpl.kt | 13 ++- 3 files changed, 117 insertions(+), 30 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt index b2e4b490..453c0311 100644 --- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt +++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt @@ -18,6 +18,8 @@ import com.intellij.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.io.URLUtil import org.jetbrains.kotlin.analyzer.* +import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns +import org.jetbrains.kotlin.caches.project.LibraryModuleInfo import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -32,14 +34,17 @@ import org.jetbrains.kotlin.container.getService import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.JvmBuiltIns 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.TargetPlatform import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters @@ -59,7 +64,7 @@ import java.io.File * $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) : Disposable { +class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPlatform: Platform) : Disposable { val configuration = CompilerConfiguration() init { @@ -68,7 +73,12 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable { fun createCoreEnvironment(): KotlinCoreEnvironment { System.setProperty("idea.io.use.fallback", "true") - val environment = KotlinCoreEnvironment.createForProduction(this, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) + + val configFiles = when (analysisPlatform) { + Platform.jvm -> EnvironmentConfigFiles.JVM_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, @@ -92,14 +102,71 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable { return environment } - fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope { - // TODO: Fix when going to implement dokka for JS - return TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) + fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope = when (analysisPlatform) { + Platform.js -> GlobalSearchScope.filesScope(project, sourceFiles.map { it.virtualFile }.toSet()) + Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) } fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { + return when(analysisPlatform) { + Platform.jvm -> createJVMResolutionFacade(environment) + Platform.js -> createJSResolutionFacade(environment) + } + } + private fun createJSResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { + val projectContext = ProjectContext(environment.project) + val sourceFiles = environment.getSourceFiles() + + val library = object : LibraryModuleInfo { + override val platform: TargetPlatform + get() = JsPlatform + + override fun getLibraryRoots(): Collection { + return classpath.map { it.absolutePath } + } + + override val name: Name = Name.special("") + override fun dependencies(): List = listOf(this) + } + val module = object : ModuleInfo { + override val name: Name = Name.special("") + override fun dependencies(): List = listOf(this, library) + } + + val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) + + val resolverForProject = ResolverForProjectImpl( + debugName = "Dokka", + projectContext = projectContext, + modules = listOf(library, module), + modulesContent = { + when (it) { + library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) + module -> ModuleContent(it, emptyList(), sourcesScope) + else -> throw IllegalArgumentException("Unexpected module info") + } + }, + modulePlatforms = { JsPlatform.multiTargetPlatform }, + moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, + resolverForModuleFactoryByPlatform = { JsAnalyzerFacade }, + platformParameters = object : PlatformAnalysisParameters {}, + targetEnvironment = CompilerEnvironment, + builtIns = JsPlatform.builtIns + ) + + resolverForProject.resolverForModule(library) // Required before module to initialize library properly + val resolverForModule = resolverForProject.resolverForModule(module) + val moduleDescriptor = resolverForProject.descriptorForModule(module) + val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule) + val projectComponentManager = environment.project as MockComponentManager + projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created)) + return created + + } + + private fun createJVMResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { val projectContext = ProjectContext(environment.project) val sourceFiles = environment.getSourceFiles() @@ -131,30 +198,27 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable { } val resolverForProject = ResolverForProjectImpl( - "Dokka", - projectContext, - listOf(library, module), - { + debugName = "Dokka", + projectContext = projectContext, + modules = listOf(library, module), + modulesContent = { when (it) { library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) module -> ModuleContent(it, emptyList(), sourcesScope) else -> throw IllegalArgumentException("Unexpected module info") } }, - { - JvmPlatform.multiTargetPlatform - }, - LanguageSettingsProvider.Default /* TODO: Fix this */, - { JvmAnalyzerFacade }, - - JvmPlatformParameters { + modulePlatforms = { JvmPlatform.multiTargetPlatform }, + moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, + resolverForModuleFactoryByPlatform = { JvmAnalyzerFacade }, + platformParameters = JvmPlatformParameters { val file = (it as JavaClassImpl).psi.containingFile.virtualFile if (file in sourcesScope) module else library }, - CompilerEnvironment, + targetEnvironment = CompilerEnvironment, packagePartProviderFactory = { content -> JvmPackagePartProvider(configuration.languageVersionSettings, content.moduleContentScope).apply { addRoots(javaRoots) @@ -191,7 +255,10 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable { * $paths: collection of files to add */ fun addClasspath(paths: List) { - configuration.addJvmClasspathRoots(paths) + when (analysisPlatform) { + Platform.js -> configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map{it.absolutePath}) + Platform.jvm -> configuration.addJvmClasspathRoots(paths) + } } /** @@ -199,7 +266,10 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable { * $path: path to add */ fun addClasspath(path: File) { - configuration.addJvmClasspathRoot(path) + when (analysisPlatform) { + Platform.js -> configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) + Platform.jvm -> configuration.addJvmClasspathRoot(path) + } } /** diff --git a/core/src/main/kotlin/Generation/DokkaGenerator.kt b/core/src/main/kotlin/Generation/DokkaGenerator.kt index 09e5cedf..a0a6eef7 100644 --- a/core/src/main/kotlin/Generation/DokkaGenerator.kt +++ b/core/src/main/kotlin/Generation/DokkaGenerator.kt @@ -35,9 +35,10 @@ class DokkaGenerator(val logger: DokkaLogger, private val documentationModule = DocumentationModule(moduleName) fun generate() { - val sourcesGroupedByPlatform = sources.groupBy { it.platforms.firstOrNull() } - for ((platform, roots) in sourcesGroupedByPlatform) { - appendSourceModule(platform, roots) + val sourcesGroupedByPlatform = sources.groupBy { it.platforms.firstOrNull() to it.analysisPlatform } + for ((platformsInfo, roots) in sourcesGroupedByPlatform) { + val (platform, analysisPlatform) = platformsInfo + appendSourceModule(platform, analysisPlatform, roots) } documentationModule.prepareForGeneration(options) @@ -49,9 +50,14 @@ class DokkaGenerator(val logger: DokkaLogger, logger.info("done in ${timeBuild / 1000} secs") } - private fun appendSourceModule(defaultPlatform: String?, sourceRoots: List) { + private fun appendSourceModule(defaultPlatform: String?, + analysisPlatform: Platform, + sourceRoots: List + + ) { + val sourcePaths = sourceRoots.map { it.path } - val environment = createAnalysisEnvironment(sourcePaths) + val environment = createAnalysisEnvironment(sourcePaths, analysisPlatform) logger.info("Module: $moduleName") logger.info("Output: ${File(options.outputDir)}") @@ -82,11 +88,13 @@ class DokkaGenerator(val logger: DokkaLogger, Disposer.dispose(environment) } - fun createAnalysisEnvironment(sourcePaths: List): AnalysisEnvironment { - val environment = AnalysisEnvironment(DokkaMessageCollector(logger)) + fun createAnalysisEnvironment(sourcePaths: List, analysisPlatform: Platform): AnalysisEnvironment { + val environment = AnalysisEnvironment(DokkaMessageCollector(logger), analysisPlatform) environment.apply { - addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) + if (analysisPlatform == Platform.jvm) { + addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) + } // addClasspath(PathUtil.getKotlinPathsForCompiler().getRuntimePath()) for (element in this@DokkaGenerator.classpath) { addClasspath(File(element)) diff --git a/core/src/main/kotlin/Generation/configurationImpl.kt b/core/src/main/kotlin/Generation/configurationImpl.kt index 34d4154e..0d916345 100644 --- a/core/src/main/kotlin/Generation/configurationImpl.kt +++ b/core/src/main/kotlin/Generation/configurationImpl.kt @@ -18,13 +18,22 @@ data class SourceLinkDefinitionImpl(override val path: String, } } -class SourceRootImpl(path: String, override val platforms: List = emptyList()) : SourceRoot { +class SourceRootImpl(path: String, override val platforms: List = emptyList(), + override val analysisPlatform: Platform = Platform.DEFAULT) : SourceRoot { override val path: String = File(path).absolutePath companion object { fun parseSourceRoot(sourceRoot: String): SourceRoot { val components = sourceRoot.split("::", limit = 2) - return SourceRootImpl(components.last(), if (components.size == 1) listOf() else components[0].split(',')) + + // TODO: create syntax for cli + val platform = if (components.size == 1) { + Platform.DEFAULT + } else { + Platform.fromString(components[0]) + } + + return SourceRootImpl(components.last(), emptyList(), platform) } } } -- cgit From 65b61e31b761071589e257381bea33557d932412 Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Thu, 12 Jul 2018 15:32:19 +0300 Subject: AnalysisEnvironment classpath for js platform fix --- .../src/main/kotlin/Analysis/AnalysisEnvironment.kt | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt index 453c0311..27881cad 100644 --- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt +++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt @@ -102,14 +102,15 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl return environment } - fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope = when (analysisPlatform) { - Platform.js -> GlobalSearchScope.filesScope(project, sourceFiles.map { it.virtualFile }.toSet()) + fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope = + when (analysisPlatform) { Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) - } + Platform.js -> GlobalSearchScope.filesScope(project, sourceFiles.map { it.virtualFile }.toSet()) + } fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { - return when(analysisPlatform) { + return when (analysisPlatform) { Platform.jvm -> createJVMResolutionFacade(environment) Platform.js -> createJSResolutionFacade(environment) } @@ -255,10 +256,10 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl * $paths: collection of files to add */ fun addClasspath(paths: List) { - when (analysisPlatform) { - Platform.js -> configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map{it.absolutePath}) - Platform.jvm -> configuration.addJvmClasspathRoots(paths) + if (analysisPlatform == Platform.js) { + configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath }) } + configuration.addJvmClasspathRoots(paths) } /** @@ -266,10 +267,10 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl * $path: path to add */ fun addClasspath(path: File) { - when (analysisPlatform) { - Platform.js -> configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) - Platform.jvm -> configuration.addJvmClasspathRoot(path) + if (analysisPlatform == Platform.js) { + configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) } + configuration.addJvmClasspathRoot(path) } /** -- cgit From b4fcc57ab7f335459131ce105924eeaa5fa77375 Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Thu, 12 Jul 2018 19:25:51 +0300 Subject: Add common platform support --- .../main/kotlin/Analysis/AnalysisEnvironment.kt | 73 +++++++++++++++++++--- 1 file changed, 63 insertions(+), 10 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt index 27881cad..2558942b 100644 --- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt +++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt @@ -18,6 +18,7 @@ import com.intellij.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.io.URLUtil import org.jetbrains.kotlin.analyzer.* +import org.jetbrains.kotlin.analyzer.common.CommonAnalyzerFacade import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns import org.jetbrains.kotlin.caches.project.LibraryModuleInfo import org.jetbrains.kotlin.caches.resolve.KotlinCacheService @@ -34,6 +35,7 @@ import org.jetbrains.kotlin.container.getService import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.PackagePartProvider import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.js.config.JSConfigurationKeys @@ -41,10 +43,7 @@ import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.name.Name 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.TargetPlatform +import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters @@ -75,7 +74,7 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl System.setProperty("idea.io.use.fallback", "true") val configFiles = when (analysisPlatform) { - Platform.jvm -> EnvironmentConfigFiles.JVM_CONFIG_FILES + Platform.jvm, Platform.common -> EnvironmentConfigFiles.JVM_CONFIG_FILES Platform.js -> EnvironmentConfigFiles.JS_CONFIG_FILES } val environment = KotlinCoreEnvironment.createForProduction(this, configuration, configFiles) @@ -105,15 +104,67 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope = when (analysisPlatform) { Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) - Platform.js -> GlobalSearchScope.filesScope(project, sourceFiles.map { it.virtualFile }.toSet()) + Platform.js, Platform.common -> GlobalSearchScope.filesScope(project, sourceFiles.map { it.virtualFile }.toSet()) } - fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { - return when (analysisPlatform) { - Platform.jvm -> createJVMResolutionFacade(environment) - Platform.js -> createJSResolutionFacade(environment) + fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade = when (analysisPlatform) { + Platform.jvm -> createJVMResolutionFacade(environment) + Platform.js -> createJSResolutionFacade(environment) + Platform.common -> createCommonResolutionFacade(environment) + } + + fun createCommonResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { + val projectContext = ProjectContext(environment.project) + val sourceFiles = environment.getSourceFiles() + + val library = object : LibraryModuleInfo { + override val platform: TargetPlatform + get() = TargetPlatform.Common + + override fun getLibraryRoots(): Collection { + return classpath.map { it.absolutePath } + } + + override val name: Name = Name.special("") + override fun dependencies(): List = listOf(this) + } + val module = object : ModuleInfo { + override val name: Name = Name.special("") + override fun dependencies(): List = listOf(this, library) } + + val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) + + val resolverForProject = ResolverForProjectImpl( + debugName = "Dokka", + projectContext = projectContext, + modules = listOf(module, library), + modulesContent = { + when (it) { + library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) + module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project)) + else -> throw IllegalArgumentException("Unexpected module info") + } + }, + modulePlatforms = { MultiTargetPlatform.Common }, + moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, + resolverForModuleFactoryByPlatform = { CommonAnalyzerFacade }, + platformParameters = object : PlatformAnalysisParameters {}, + targetEnvironment = CompilerEnvironment, + packagePartProviderFactory = { content -> + environment.createPackagePartProvider(content.moduleContentScope) + } + ) + + resolverForProject.resolverForModule(library) // Required before module to initialize library properly + val resolverForModule = resolverForProject.resolverForModule(module) + val moduleDescriptor = resolverForProject.descriptorForModule(module) + val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule) + val projectComponentManager = environment.project as MockComponentManager + projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created)) + + return created } private fun createJSResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { @@ -259,6 +310,7 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl if (analysisPlatform == Platform.js) { configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath }) } + configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath }) configuration.addJvmClasspathRoots(paths) } @@ -270,6 +322,7 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl if (analysisPlatform == Platform.js) { configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) } + configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) configuration.addJvmClasspathRoot(path) } -- cgit From eca10911658bc48cd5508fbe1fd371adc881f392 Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Thu, 12 Jul 2018 21:59:25 +0300 Subject: AnalysisPlatform refactoring --- .../main/kotlin/Analysis/AnalysisEnvironment.kt | 197 +++++++++------------ 1 file changed, 83 insertions(+), 114 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt index 2558942b..f03e9eea 100644 --- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt +++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt @@ -19,6 +19,8 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.io.URLUtil import org.jetbrains.kotlin.analyzer.* import org.jetbrains.kotlin.analyzer.common.CommonAnalyzerFacade +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns import org.jetbrains.kotlin.caches.project.LibraryModuleInfo import org.jetbrains.kotlin.caches.resolve.KotlinCacheService @@ -108,19 +110,20 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl } - fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade = when (analysisPlatform) { - Platform.jvm -> createJVMResolutionFacade(environment) - Platform.js -> createJSResolutionFacade(environment) - Platform.common -> createCommonResolutionFacade(environment) - } - - fun createCommonResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { + fun createResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { val projectContext = ProjectContext(environment.project) val sourceFiles = environment.getSourceFiles() + + val targetPlatform = when (analysisPlatform) { + Platform.js -> JsPlatform + Platform.common -> TargetPlatform.Common + Platform.jvm -> JvmPlatform + } + val library = object : LibraryModuleInfo { override val platform: TargetPlatform - get() = TargetPlatform.Common + get() = targetPlatform override fun getLibraryRoots(): Collection { return classpath.map { it.absolutePath } @@ -135,31 +138,29 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl } val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) + val modulesContent: (ModuleInfo) -> ModuleContent = { + when (it) { + library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) + module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project)) + else -> throw IllegalArgumentException("Unexpected module info") + } + } - val resolverForProject = ResolverForProjectImpl( - debugName = "Dokka", - projectContext = projectContext, - modules = listOf(module, library), - modulesContent = { - when (it) { - library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project)) - else -> throw IllegalArgumentException("Unexpected module info") - } - }, - modulePlatforms = { MultiTargetPlatform.Common }, - moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, - resolverForModuleFactoryByPlatform = { CommonAnalyzerFacade }, - platformParameters = object : PlatformAnalysisParameters {}, - targetEnvironment = CompilerEnvironment, - packagePartProviderFactory = { content -> - environment.createPackagePartProvider(content.moduleContentScope) + var builtIns: JvmBuiltIns? = null + + val resolverForProject = when (analysisPlatform) { + Platform.jvm -> { + builtIns = JvmBuiltIns(projectContext.storageManager) + createJvmResolverForProject(projectContext, module, library, modulesContent, sourcesScope, builtIns) } - ) + Platform.js -> createJsResolverForProject(projectContext, module, library, modulesContent) + Platform.common -> createCommonResolverForProject(projectContext, module, library, modulesContent, environment) + } resolverForProject.resolverForModule(library) // Required before module to initialize library properly val resolverForModule = resolverForProject.resolverForModule(module) val moduleDescriptor = resolverForProject.descriptorForModule(module) + builtIns?.initialize(moduleDescriptor, true) val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule) val projectComponentManager = environment.project as MockComponentManager projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created)) @@ -167,99 +168,76 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl return created } - private fun createJSResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { - val projectContext = ProjectContext(environment.project) - val sourceFiles = environment.getSourceFiles() - - val library = object : LibraryModuleInfo { - override val platform: TargetPlatform - get() = JsPlatform - - override fun getLibraryRoots(): Collection { - return classpath.map { it.absolutePath } - } - - override val name: Name = Name.special("") - override fun dependencies(): List = listOf(this) - } - val module = object : ModuleInfo { - override val name: Name = Name.special("") - override fun dependencies(): List = listOf(this, library) - } - - val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) - - val resolverForProject = ResolverForProjectImpl( + private fun createCommonResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent, + environment: KotlinCoreEnvironment + ): ResolverForProjectImpl { + return ResolverForProjectImpl( debugName = "Dokka", projectContext = projectContext, - modules = listOf(library, module), - modulesContent = { - when (it) { - library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(it, emptyList(), sourcesScope) - else -> throw IllegalArgumentException("Unexpected module info") - } + modules = listOf(module, library), + modulesContent = modulesContent, + modulePlatforms = { MultiTargetPlatform.Common }, + moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, + resolverForModuleFactoryByPlatform = { CommonAnalyzerFacade }, + platformParameters = object : PlatformAnalysisParameters {}, + targetEnvironment = CompilerEnvironment, + packagePartProviderFactory = { content -> + environment.createPackagePartProvider(content.moduleContentScope) }, + builtIns = DefaultBuiltIns.Instance + ) + } + + private fun createJsResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent + ): ResolverForProjectImpl { + return ResolverForProjectImpl( + debugName = "Dokka", + projectContext = projectContext, + modules = listOf(module, library), + modulesContent = modulesContent, modulePlatforms = { JsPlatform.multiTargetPlatform }, moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, resolverForModuleFactoryByPlatform = { JsAnalyzerFacade }, platformParameters = object : PlatformAnalysisParameters {}, targetEnvironment = CompilerEnvironment, + packagePartProviderFactory = { PackagePartProvider.Empty }, builtIns = JsPlatform.builtIns ) - - resolverForProject.resolverForModule(library) // Required before module to initialize library properly - val resolverForModule = resolverForProject.resolverForModule(module) - val moduleDescriptor = resolverForProject.descriptorForModule(module) - val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule) - val projectComponentManager = environment.project as MockComponentManager - projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created)) - return created - } - private fun createJVMResolutionFacade(environment: KotlinCoreEnvironment): DokkaResolutionFacade { - val projectContext = ProjectContext(environment.project) - val sourceFiles = environment.getSourceFiles() - - - val library = object : ModuleInfo { - override val name: Name = Name.special("") - override fun dependencies(): List = listOf(this) - } - val module = object : ModuleInfo { - override val name: Name = Name.special("") - override fun dependencies(): List = listOf(this, library) - } - - val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) - - val builtIns = JvmBuiltIns(projectContext.storageManager) - - + private fun createJvmResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent, + sourcesScope: GlobalSearchScope, + builtIns: KotlinBuiltIns + ): ResolverForProjectImpl { val javaRoots = classpath - .mapNotNull { - val rootFile = when { - it.extension == "jar" -> - StandardFileSystems.jar().findFileByPath("${it.absolutePath}${URLUtil.JAR_SEPARATOR}") - else -> - StandardFileSystems.local().findFileByPath(it.absolutePath) - } - - rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) } + .mapNotNull { + val rootFile = when { + it.extension == "jar" -> + StandardFileSystems.jar().findFileByPath("${it.absolutePath}${URLUtil.JAR_SEPARATOR}") + else -> + StandardFileSystems.local().findFileByPath(it.absolutePath) } - val resolverForProject = ResolverForProjectImpl( + rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) } + } + + return ResolverForProjectImpl( debugName = "Dokka", projectContext = projectContext, - modules = listOf(library, module), - modulesContent = { - when (it) { - library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(it, emptyList(), sourcesScope) - else -> throw IllegalArgumentException("Unexpected module info") - } - }, + modules = listOf(module, library), + modulesContent = modulesContent, modulePlatforms = { JvmPlatform.multiTargetPlatform }, moduleLanguageSettingsProvider = LanguageSettingsProvider.Default /* TODO: Fix this */, resolverForModuleFactoryByPlatform = { JvmAnalyzerFacade }, @@ -269,7 +247,8 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl module else library - }, + } + , targetEnvironment = CompilerEnvironment, packagePartProviderFactory = { content -> JvmPackagePartProvider(configuration.languageVersionSettings, content.moduleContentScope).apply { @@ -278,16 +257,6 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl }, builtIns = builtIns ) - - resolverForProject.resolverForModule(library) // Required before module to initialize library properly - val resolverForModule = resolverForProject.resolverForModule(module) - val moduleDescriptor = resolverForProject.descriptorForModule(module) - builtIns.initialize(moduleDescriptor, true) - val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule) - val projectComponentManager = environment.project as MockComponentManager - projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created)) - - return created } fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) { -- cgit From fe20206eecd22cb4bd4de03efc0e9c28e1981bac Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Fri, 13 Jul 2018 15:04:56 +0300 Subject: Minor style fixes --- core/src/main/kotlin/Analysis/AnalysisEnvironment.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt index f03e9eea..3d70bd84 100644 --- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt +++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt @@ -247,8 +247,7 @@ class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPl module else library - } - , + }, targetEnvironment = CompilerEnvironment, packagePartProviderFactory = { content -> JvmPackagePartProvider(configuration.languageVersionSettings, content.moduleContentScope).apply { -- cgit From 93a9052d8434879f8fdf192d9d498285a6a31127 Mon Sep 17 00:00:00 2001 From: Zubakov Aleksey Date: Tue, 17 Jul 2018 17:13:01 +0300 Subject: NodeReferenceGraph style fixes --- core/src/main/kotlin/Model/DocumentationReference.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Model/DocumentationReference.kt b/core/src/main/kotlin/Model/DocumentationReference.kt index 89ec1b3e..5db1f05a 100644 --- a/core/src/main/kotlin/Model/DocumentationReference.kt +++ b/core/src/main/kotlin/Model/DocumentationReference.kt @@ -37,24 +37,24 @@ class PendingDocumentationReference(val lazyNodeFrom: () -> DocumentationNode?, } } -class NodeReferenceGraph() { +class NodeReferenceGraph { private val nodeMap = hashMapOf() val references = arrayListOf() fun register(signature: String, node: DocumentationNode) { - nodeMap.put(signature, node) + nodeMap[signature] = node } fun link(fromNode: DocumentationNode, toSignature: String, kind: RefKind) { - references.add(PendingDocumentationReference({ -> fromNode}, { -> nodeMap[toSignature]}, kind)) + references.add(PendingDocumentationReference({ fromNode }, { nodeMap[toSignature] }, kind)) } fun link(fromSignature: String, toNode: DocumentationNode, kind: RefKind) { - references.add(PendingDocumentationReference({ -> nodeMap[fromSignature]}, { -> toNode}, kind)) + references.add(PendingDocumentationReference({ nodeMap[fromSignature] }, { toNode }, kind)) } fun link(fromSignature: String, toSignature: String, kind: RefKind) { - references.add(PendingDocumentationReference({ -> nodeMap[fromSignature]}, { -> nodeMap[toSignature]}, kind)) + references.add(PendingDocumentationReference({ nodeMap[fromSignature] }, { nodeMap[toSignature] }, kind)) } fun lookup(signature: String) = nodeMap[signature] -- cgit From 899c11d36f565cd192945573860568ff62c16ef2 Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Wed, 25 Jul 2018 17:24:00 +0300 Subject: Add logic of merging different platforms graphs --- .../main/kotlin/Formats/StructuredFormatService.kt | 12 +- core/src/main/kotlin/Generation/DokkaGenerator.kt | 232 ++++++++++++++++++++- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 6 +- core/src/main/kotlin/Model/DocumentationNode.kt | 10 +- .../main/kotlin/Model/DocumentationReference.kt | 53 ++++- 5 files changed, 288 insertions(+), 25 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt index ebc9cde6..41c8f29a 100644 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt @@ -514,15 +514,15 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, appendSection("Exceptions", node.membersOrGroupMembers(NodeKind.Exception)) appendSection("Type Aliases", node.membersOrGroupMembers(NodeKind.TypeAlias)) appendSection("Extensions for External Classes", node.members(NodeKind.ExternalClass)) - appendSection("Enum Values", node.members(NodeKind.EnumItem), sortMembers = false, omitSamePlatforms = true) - appendSection("Constructors", node.members(NodeKind.Constructor), omitSamePlatforms = true) - appendSection("Properties", node.members(NodeKind.Property), omitSamePlatforms = true) + appendSection("Enum Values", node.membersOrGroupMembers(NodeKind.EnumItem), sortMembers = false, omitSamePlatforms = true) + appendSection("Constructors", node.membersOrGroupMembers(NodeKind.Constructor), omitSamePlatforms = true) + appendSection("Properties", node.membersOrGroupMembers(NodeKind.Property), omitSamePlatforms = true) appendSection("Inherited Properties", node.inheritedMembers(NodeKind.Property)) - appendSection("Functions", node.members(NodeKind.Function), omitSamePlatforms = true) + appendSection("Functions", node.membersOrGroupMembers(NodeKind.Function), omitSamePlatforms = true) appendSection("Inherited Functions", node.inheritedMembers(NodeKind.Function)) - appendSection("Companion Object Properties", node.members(NodeKind.CompanionObjectProperty), omitSamePlatforms = true) + appendSection("Companion Object Properties", node.membersOrGroupMembers(NodeKind.CompanionObjectProperty), omitSamePlatforms = true) appendSection("Inherited Companion Object Properties", node.inheritedCompanionObjectMembers(NodeKind.Property)) - appendSection("Companion Object Functions", node.members(NodeKind.CompanionObjectFunction), omitSamePlatforms = true) + appendSection("Companion Object Functions", node.membersOrGroupMembers(NodeKind.CompanionObjectFunction), omitSamePlatforms = true) appendSection("Inherited Companion Object Functions", node.inheritedCompanionObjectMembers(NodeKind.Function)) appendSection("Other members", node.members.filter { it.kind !in setOf( diff --git a/core/src/main/kotlin/Generation/DokkaGenerator.kt b/core/src/main/kotlin/Generation/DokkaGenerator.kt index 9de4396b..0c4b3b7e 100644 --- a/core/src/main/kotlin/Generation/DokkaGenerator.kt +++ b/core/src/main/kotlin/Generation/DokkaGenerator.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka import com.google.inject.Guice import com.google.inject.Injector +import com.intellij.openapi.application.PathManager import com.intellij.openapi.util.Disposer import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiFile @@ -17,6 +18,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.config.KotlinSourceRoot import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer import org.jetbrains.kotlin.resolve.TopDownAnalysisMode @@ -32,28 +34,34 @@ class DokkaGenerator(val logger: DokkaLogger, val moduleName: String, val options: DocumentationOptions) { - private val documentationModule = DocumentationModule(moduleName) + private val documentationModules: MutableList = mutableListOf() fun generate() { val sourcesGroupedByPlatform = sources.groupBy { it.platforms.firstOrNull() to it.analysisPlatform } for ((platformsInfo, roots) in sourcesGroupedByPlatform) { val (platform, analysisPlatform) = platformsInfo - appendSourceModule(platform, analysisPlatform, roots) + + val documentationModule = DocumentationModule(moduleName) + appendSourceModule(platform, analysisPlatform, roots, documentationModule) + documentationModules.add(documentationModule) } - documentationModule.prepareForGeneration(options) + + val totalDocumentationModule = DocumentationMerger(documentationModules).merge() + totalDocumentationModule.prepareForGeneration(options) val timeBuild = measureTimeMillis { logger.info("Generating pages... ") val outputInjector = Guice.createInjector(DokkaOutputModule(options, logger)) - outputInjector.getInstance(Generator::class.java).buildAll(documentationModule) + outputInjector.getInstance(Generator::class.java).buildAll(totalDocumentationModule) } logger.info("done in ${timeBuild / 1000} secs") } - private fun appendSourceModule(defaultPlatform: String?, - analysisPlatform: Platform, - sourceRoots: List - + private fun appendSourceModule( + defaultPlatform: String?, + analysisPlatform: Platform, + sourceRoots: List, + documentationModule: DocumentationModule ) { val sourcePaths = sourceRoots.map { it.path } @@ -81,6 +89,12 @@ class DokkaGenerator(val logger: DokkaLogger, DokkaAnalysisModule(environment, options, defaultPlatformsProvider, documentationModule.nodeRefGraph, logger)) buildDocumentationModule(injector, documentationModule, { isNotSample(it) }, includes) + documentationModule.nodeRefGraph.nodeMapView.forEach { (_, node) -> + node.addReferenceTo( + DocumentationNode(analysisPlatform.key, Content.Empty, NodeKind.Platform), + RefKind.Platform + ) + } val timeAnalyse = System.currentTimeMillis() - startAnalyse logger.info("done in ${timeAnalyse / 1000} secs") @@ -214,3 +228,205 @@ fun KotlinCoreEnvironment.getJavaSourceFiles(): List { } return result } + +class DocumentationMerger( + private val documentationModules: List +) { + private val producedNodeRefGraph: NodeReferenceGraph + private val signatureMap: Map + + init { + signatureMap = documentationModules + .flatMap { it.nodeRefGraph.nodeMapView.entries } + .map { (k, v) -> v to k } + .toMap() + + producedNodeRefGraph = NodeReferenceGraph() + documentationModules.map { it.nodeRefGraph } + .flatMap { it.references } + .distinct() + .forEach { producedNodeRefGraph.addReference(it) } + } + + private fun splitReferencesByKind( + source: List, + kind: RefKind + ): Pair, List> = + Pair(source.filter { it.kind == kind }, source.filterNot { it.kind == kind }) + + + private fun mergePackageReferences( + from: DocumentationNode, + packages: List + ): List { + val packagesByName = packages + .map { it.to } + .groupBy { it.name } + + val mutableList: MutableList = mutableListOf() + for ((name, listOfPackages) in packagesByName) { + val producedPackage = mergePackagesWithEqualNames(from, listOfPackages) + updatePendingReferences(name, producedPackage) + + mutableList.add( + DocumentationReference(from, producedPackage, RefKind.Member) + ) + } + + return mutableList + } + + private fun mergePackagesWithEqualNames( + from: DocumentationNode, + packages: List + ): DocumentationNode { + val references = packages.flatMap { it.allReferences() } + + val mergedPackage = + DocumentationNode( + packages.first().name, + Content.Empty, + NodeKind.Package + ) + + val mergedReferences = mergeReferences(mergedPackage, references) + + for (packageNode in packages) { + mergedPackage.updateContent { + for (otherChild in packageNode.content.children) { + children.add(otherChild) + } + } + } + + mergedPackage.dropReferences { true } // clear() + for (ref in mergedReferences.distinct()) { + mergedPackage.addReference(ref) + } + + from.append(mergedPackage, RefKind.Member) + + return mergedPackage + } + + + private fun mergeMembers( + from: DocumentationNode, + refs: List + ): List { + val membersBySignature: Map> = refs.map { it.to } + .filter { signatureMap.containsKey(it) } + .groupBy { signatureMap[it]!! } + + val mergedMembers: MutableList = mutableListOf() + for ((signature, members) in membersBySignature) { + val newNode = mergeMembersWithEqualSignature(signature, from, members) + + producedNodeRefGraph.register(signature, newNode) + updatePendingReferences(signature, newNode) + from.append(newNode, RefKind.Member) + + mergedMembers.add(DocumentationReference(from, newNode, RefKind.Member)) + } + + return mergedMembers + } + + private fun mergeMembersWithEqualSignature( + signature: String, + from: DocumentationNode, + refs: List + ): DocumentationNode { + if (refs.size == 1) { + val singleNode = refs.single() + singleNode.owner?.let { owner -> + singleNode.dropReferences { it.to == owner && it.kind == RefKind.Owner } + } + return singleNode + } + val groupNode = DocumentationNode(refs.first().name, Content.Empty, NodeKind.GroupNode) + groupNode.appendTextNode(signature, NodeKind.Signature, RefKind.Detail) + + for (node in refs) { + if (node != groupNode) { + node.owner?.let { owner -> + node.dropReferences { it.to == owner && it.kind == RefKind.Owner } + from.dropReferences { it.to == node && it.kind == RefKind.Member } + } + groupNode.append(node, RefKind.Member) + } + } + return groupNode + } + + + private fun mergeReferences( + from: DocumentationNode, + refs: List + ): List { + val allRefsToPackages = refs.map { it.to } + .all { it.kind == NodeKind.Package } + + if (allRefsToPackages) { + return mergePackageReferences(from, refs) + } + + val (memberRefs, notMemberRefs) = splitReferencesByKind(refs, RefKind.Member) + val mergedMembers = mergeMembers(from, memberRefs) + + return (mergedMembers + notMemberRefs).distinctBy { + it.kind to it.to.name + } + } + + + private fun updatePendingReferences( + signature: String, + nodeToUpdate: DocumentationNode + ) { + producedNodeRefGraph.references.forEach { + it.lazyNodeFrom.update(signature, nodeToUpdate) + it.lazyNodeTo.update(signature, nodeToUpdate) + } + } + + private fun NodeResolver.update(signature: String, nodeToUpdate: DocumentationNode) { + when (this) { + is NodeResolver.BySignature -> update(signature, nodeToUpdate) + is NodeResolver.Exact -> update(signature, nodeToUpdate) + } + } + + private fun NodeResolver.BySignature.update(signature: String, nodeToUpdate: DocumentationNode) { + if (signature == nodeToUpdate.name) { + nodeMap = producedNodeRefGraph.nodeMapView + } + } + + private fun NodeResolver.Exact.update(signature: String, nodeToUpdate: DocumentationNode) { + exactNode?.let { it -> + val equalSignature = + it.anyReference { ref -> ref.to.kind == NodeKind.Signature && ref.to.name == signature } + + if (equalSignature) { + exactNode = nodeToUpdate + } + } + } + + fun merge(): DocumentationModule { + val refs = documentationModules.flatMap { + it.allReferences() + } + val mergedDocumentationModule = DocumentationModule( + name = documentationModules.first().name, + nodeRefGraph = producedNodeRefGraph + ) + + mergeReferences(mergedDocumentationModule, refs) + + return mergedDocumentationModule + } + + +} \ No newline at end of file diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index f1b8e3d3..e3675f9d 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -1079,7 +1079,7 @@ fun DeclarationDescriptor.signature(): String { is TypeAliasDescriptor -> DescriptorUtils.getFqName(this).asString() is PropertyDescriptor -> containingDeclaration.signature() + "$" + name + receiverSignature() - is FunctionDescriptor -> containingDeclaration.signature() + "$" + name + parameterSignature() + is FunctionDescriptor -> containingDeclaration.signature() + "$" + name + parameterSignature() + ":" + returnType?.signature() is ValueParameterDescriptor -> containingDeclaration.signature() + "/" + name is TypeParameterDescriptor -> containingDeclaration.signature() + "*" + name is ReceiverParameterDescriptor -> containingDeclaration.signature() + "/" + name @@ -1149,7 +1149,9 @@ fun DocumentationModule.prepareForGeneration(options: DocumentationOptions) { fun DocumentationNode.generateAllTypesNode() { val allTypes = members(NodeKind.Package) - .flatMap { it.members.filter { it.kind in NodeKind.classLike || it.kind == NodeKind.ExternalClass } } + .flatMap { it.members.filter { + it.kind in NodeKind.classLike || it.kind == NodeKind.ExternalClass + || (it.kind == NodeKind.GroupNode && it.anyReference { it.to.kind in NodeKind.classLike }) } } .sortedBy { if (it.kind == NodeKind.ExternalClass) it.name.substringAfterLast('.').toLowerCase() else it.name.toLowerCase() } val allTypesNode = DocumentationNode("alltypes", Content.Empty, NodeKind.AllTypes) diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt index a3388031..bdb7cf20 100644 --- a/core/src/main/kotlin/Model/DocumentationNode.kt +++ b/core/src/main/kotlin/Model/DocumentationNode.kt @@ -134,6 +134,10 @@ open class DocumentationNode(val name: String, references.add(DocumentationReference(this, to, kind)) } + fun addReference(reference: DocumentationReference) { + references.add(reference) + } + fun dropReferences(predicate: (DocumentationReference) -> Boolean) { references.removeAll(predicate) } @@ -159,6 +163,8 @@ open class DocumentationNode(val name: String, fun member(kind: NodeKind): DocumentationNode = members.filter { it.kind == kind }.single() fun link(kind: NodeKind): DocumentationNode = links.filter { it.kind == kind }.single() + fun anyReference(predicate: (DocumentationReference) -> Boolean): Boolean = references.any(predicate) + fun references(kind: RefKind): List = references.filter { it.kind == kind } fun allReferences(): Set = references @@ -167,9 +173,9 @@ open class DocumentationNode(val name: String, } } -class DocumentationModule(name: String, content: Content = Content.Empty) +class DocumentationModule(name: String, content: Content = Content.Empty, val nodeRefGraph: NodeReferenceGraph = NodeReferenceGraph()) : DocumentationNode(name, content, NodeKind.Module) { - val nodeRefGraph = NodeReferenceGraph() + } val DocumentationNode.path: List diff --git a/core/src/main/kotlin/Model/DocumentationReference.kt b/core/src/main/kotlin/Model/DocumentationReference.kt index 5db1f05a..9223c17a 100644 --- a/core/src/main/kotlin/Model/DocumentationReference.kt +++ b/core/src/main/kotlin/Model/DocumentationReference.kt @@ -25,12 +25,27 @@ enum class RefKind { data class DocumentationReference(val from: DocumentationNode, val to: DocumentationNode, val kind: RefKind) { } -class PendingDocumentationReference(val lazyNodeFrom: () -> DocumentationNode?, - val lazyNodeTo: () -> DocumentationNode?, +sealed class NodeResolver { + abstract fun resolve(): DocumentationNode? + class BySignature(var signature: String, var nodeMap: Map) : NodeResolver() { + override fun resolve(): DocumentationNode? { + return nodeMap[signature] + } + } + + class Exact(var exactNode: DocumentationNode?) : NodeResolver() { + override fun resolve(): DocumentationNode? { + return exactNode + } + } +} + +class PendingDocumentationReference(val lazyNodeFrom: NodeResolver, + val lazyNodeTo: NodeResolver, val kind: RefKind) { fun resolve() { - val fromNode = lazyNodeFrom() - val toNode = lazyNodeTo() + val fromNode = lazyNodeFrom.resolve() + val toNode = lazyNodeTo.resolve() if (fromNode != null && toNode != null) { fromNode.addReferenceTo(toNode, kind) } @@ -39,6 +54,9 @@ class PendingDocumentationReference(val lazyNodeFrom: () -> DocumentationNode?, class NodeReferenceGraph { private val nodeMap = hashMapOf() + val nodeMapView: Map + get() = HashMap(nodeMap) + val references = arrayListOf() fun register(signature: String, node: DocumentationNode) { @@ -46,15 +64,36 @@ class NodeReferenceGraph { } fun link(fromNode: DocumentationNode, toSignature: String, kind: RefKind) { - references.add(PendingDocumentationReference({ fromNode }, { nodeMap[toSignature] }, kind)) + references.add( + PendingDocumentationReference( + NodeResolver.Exact(fromNode), + NodeResolver.BySignature(toSignature, nodeMap), + kind + )) } fun link(fromSignature: String, toNode: DocumentationNode, kind: RefKind) { - references.add(PendingDocumentationReference({ nodeMap[fromSignature] }, { toNode }, kind)) + references.add( + PendingDocumentationReference( + NodeResolver.BySignature(fromSignature, nodeMap), + NodeResolver.Exact(toNode), + kind + ) + ) } fun link(fromSignature: String, toSignature: String, kind: RefKind) { - references.add(PendingDocumentationReference({ nodeMap[fromSignature] }, { nodeMap[toSignature] }, kind)) + references.add( + PendingDocumentationReference( + NodeResolver.BySignature(fromSignature, nodeMap), + NodeResolver.BySignature(toSignature, nodeMap), + kind + ) + ) + } + + fun addReference(reference: PendingDocumentationReference) { + references.add(reference) } fun lookup(signature: String) = nodeMap[signature] -- cgit From 052a218dcf8bc565d5e78dc900a9647f0da5350a Mon Sep 17 00:00:00 2001 From: aleksZubakov Date: Wed, 1 Aug 2018 19:48:45 +0300 Subject: Refactoring, replace DocumentationOption with PassConfiguration --- core/src/main/kotlin/DokkaBootstrapImpl.kt | 32 +----- core/src/main/kotlin/Generation/DokkaGenerator.kt | 58 +++++------ core/src/main/kotlin/Generation/FileGenerator.kt | 5 +- .../main/kotlin/Generation/configurationImpl.kt | 70 ++++++++----- .../kotlin/Java/JavaPsiDocumentationBuilder.kt | 25 +++-- .../main/kotlin/Kotlin/DeclarationLinkResolver.kt | 4 +- .../kotlin/Kotlin/DescriptorDocumentationParser.kt | 2 +- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 108 ++++++--------------- .../Kotlin/ExternalDocumentationLinkResolver.kt | 13 ++- .../Kotlin/KotlinAsJavaDocumentationBuilder.kt | 2 +- .../Samples/DefaultSampleProcessingService.kt | 2 +- .../KotlinWebsiteSampleProcessingService.kt | 4 +- core/src/main/kotlin/Utilities/DokkaModules.kt | 18 ++-- core/src/main/kotlin/javadoc/dokka-adapters.kt | 9 +- 14 files changed, 147 insertions(+), 205 deletions(-) (limited to 'core/src/main') diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index e18ab6cf..ccafcd12 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -2,7 +2,6 @@ package org.jetbrains.dokka import org.jetbrains.dokka.DokkaConfiguration.PackageOptions import ru.yole.jkid.deserialization.deserialize -import java.io.File import java.util.function.BiConsumer @@ -44,36 +43,7 @@ class DokkaBootstrapImpl : DokkaBootstrap { = configure(DokkaProxyLogger(logger), deserialize(serializedConfigurationJSON)) fun configure(logger: DokkaLogger, configuration: DokkaConfiguration) = with(configuration) { - generator = DokkaGenerator( - logger, - classpath, - sourceRoots, - samples, - includes, - moduleName, - DocumentationOptions( - outputDir = outputDir, - outputFormat = format, - includeNonPublic = includeNonPublic, - includeRootPackage = includeRootPackage, - reportUndocumented = reportUndocumented, - skipEmptyPackages = skipEmptyPackages, - skipDeprecated = skipDeprecated, -