aboutsummaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/kotlin/Analysis/AnalysisEnvironment.kt195
-rw-r--r--core/src/main/kotlin/Generation/DokkaGenerator.kt24
-rw-r--r--core/src/main/kotlin/Generation/configurationImpl.kt13
3 files changed, 171 insertions, 61 deletions
diff --git a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt
index d31fe187..fe9ec2fa 100644
--- a/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt
+++ b/core/src/main/kotlin/Analysis/AnalysisEnvironment.kt
@@ -18,6 +18,11 @@ 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.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
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -33,14 +38,15 @@ import org.jetbrains.kotlin.container.tryGetService
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
+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.*
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
@@ -60,7 +66,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 {
@@ -69,7 +75,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, Platform.common -> 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,
@@ -93,10 +104,11 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
return environment
}
- fun createSourceModuleSearchScope(project: Project, sourceFiles: List<KtFile>): GlobalSearchScope {
- // TODO: Fix when going to implement dokka for JS
- return TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
- }
+ fun createSourceModuleSearchScope(project: Project, sourceFiles: List<KtFile>): GlobalSearchScope =
+ when (analysisPlatform) {
+ Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
+ Platform.js, Platform.common -> GlobalSearchScope.filesScope(project, sourceFiles.map { it.virtualFile }.toSet())
+ }
fun createResolutionFacade(environment: KotlinCoreEnvironment): Pair<DokkaResolutionFacade, DokkaResolutionFacade> {
@@ -105,7 +117,20 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
val sourceFiles = environment.getSourceFiles()
- val library = object : ModuleInfo {
+ val targetPlatform = when (analysisPlatform) {
+ Platform.js -> JsPlatform
+ Platform.common -> TargetPlatform.Common
+ Platform.jvm -> JvmPlatform
+ }
+
+ val library = object : LibraryModuleInfo {
+ override val platform: TargetPlatform
+ get() = targetPlatform
+
+ override fun getLibraryRoots(): Collection<String> {
+ return classpath.map { it.absolutePath }
+ }
+
override val name: Name = Name.special("<library>")
override fun dependencies(): List<ModuleInfo> = listOf(this)
}
@@ -115,47 +140,119 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
}
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))
+ else -> throw IllegalArgumentException("Unexpected module info")
+ }
+ }
- val builtIns = JvmBuiltIns(projectContext.storageManager)
+ 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)
- val javaRoots = classpath
- .mapNotNull {
- val rootFile = when {
- it.extension == "jar" ->
- StandardFileSystems.jar().findFileByPath("${it.absolutePath}${URLUtil.JAR_SEPARATOR}")
- else ->
- StandardFileSystems.local().findFileByPath(it.absolutePath)
- }
+ }
+ val resolverForLibrary = resolverForProject.resolverForModule(library) // Required before module to initialize library properly
+ val resolverForModule = resolverForProject.resolverForModule(module)
+ val libraryModuleDescriptor = resolverForProject.descriptorForModule(library)
+ val moduleDescriptor = resolverForProject.descriptorForModule(module)
+ builtIns?.initialize(moduleDescriptor, true)
+ 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))
- rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) }
- }
+ return created to libraryResolutionFacade
+ }
- val resolverForProject = ResolverForProjectImpl(
- "Dokka",
- projectContext,
- listOf(library, module),
- {
- when (it) {
- library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope))
- module -> ModuleContent(it, emptyList(), sourcesScope)
- else -> throw IllegalArgumentException("Unexpected module info")
- }
- },
- {
- JvmPlatform.multiTargetPlatform
+ private fun createCommonResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>,
+ environment: KotlinCoreEnvironment
+ ): ResolverForProjectImpl<ModuleInfo> {
+ return ResolverForProjectImpl(
+ debugName = "Dokka",
+ projectContext = projectContext,
+ 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)
},
- LanguageSettingsProvider.Default /* TODO: Fix this */,
- { JvmAnalyzerFacade },
+ builtIns = DefaultBuiltIns.Instance
+ )
+ }
+
+ private fun createJsResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>
+ ): ResolverForProjectImpl<ModuleInfo> {
+ 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
+ )
+ }
+
+ private fun createJvmResolverForProject(
+ projectContext: ProjectContext,
+ module: ModuleInfo,
+ library: LibraryModuleInfo,
+ modulesContent: (ModuleInfo) -> ModuleContent<ModuleInfo>,
+ sourcesScope: GlobalSearchScope,
+ builtIns: KotlinBuiltIns
+ ): ResolverForProjectImpl<ModuleInfo> {
+ 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) }
+ }
- JvmPlatformParameters {
+ return ResolverForProjectImpl(
+ debugName = "Dokka",
+ projectContext = projectContext,
+ modules = listOf(module, library),
+ modulesContent = modulesContent,
+ 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)
@@ -163,18 +260,6 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
},
builtIns = builtIns
)
-
- val resolverForLibrary = resolverForProject.resolverForModule(library) // Required before module to initialize library properly
- val resolverForModule = resolverForProject.resolverForModule(module)
- val libraryModuleDescriptor = resolverForProject.descriptorForModule(library)
- val moduleDescriptor = resolverForProject.descriptorForModule(module)
- builtIns.initialize(moduleDescriptor, true)
- 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
}
fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) {
@@ -194,6 +279,10 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
* $paths: collection of files to add
*/
fun addClasspath(paths: List<File>) {
+ if (analysisPlatform == Platform.js) {
+ configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath })
+ }
+ configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath })
configuration.addJvmClasspathRoots(paths)
}
@@ -202,6 +291,10 @@ class AnalysisEnvironment(val messageCollector: MessageCollector) : Disposable {
* $path: path to add
*/
fun addClasspath(path: File) {
+ if (analysisPlatform == Platform.js) {
+ configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath)
+ }
+ configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath)
configuration.addJvmClasspathRoot(path)
}
diff --git a/core/src/main/kotlin/Generation/DokkaGenerator.kt b/core/src/main/kotlin/Generation/DokkaGenerator.kt
index 46fdaf0a..9de4396b 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<SourceRoot>) {
+ private fun appendSourceModule(defaultPlatform: String?,
+ analysisPlatform: Platform,
+ sourceRoots: List<SourceRoot>
+
+ ) {
+
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<String>): AnalysisEnvironment {
- val environment = AnalysisEnvironment(DokkaMessageCollector(logger))
+ fun createAnalysisEnvironment(sourcePaths: List<String>, 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 90e27b4b..8829682a 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<String> = emptyList()) : SourceRoot {
+class SourceRootImpl(path: String, override val platforms: List<String> = 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)
}
}
}