org.jetbrains.kotlin.analyzer.AnalyzerFacade.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.analyzer
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.context.ModuleContext
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.descriptors.impl.LazyModuleDependencies
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.createModule
import java.util.*
class ResolverForModule(
val packageFragmentProvider: PackageFragmentProvider,
val componentProvider: ComponentProvider
)
abstract class ResolverForProject {
fun resolverForModule(moduleInfo: M): ResolverForModule = resolverForModuleDescriptor(descriptorForModule(moduleInfo))
abstract fun tryGetResolverForModule(moduleInfo: M): ResolverForModule?
abstract fun descriptorForModule(moduleInfo: M): ModuleDescriptor
abstract fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): ResolverForModule
abstract val name: String
abstract val allModules: Collection
override fun toString() = "$name"
}
class EmptyResolverForProject : ResolverForProject() {
override val name: String
get() = "Empty resolver"
override fun tryGetResolverForModule(moduleInfo: M): ResolverForModule? = null
override fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): ResolverForModule = throw IllegalStateException("$descriptor is not contained in this resolver")
override fun descriptorForModule(moduleInfo: M) = throw IllegalStateException("Should not be called for $moduleInfo")
override val allModules: Collection = listOf()
}
class ResolverForProjectImpl(
private val debugName: String,
val descriptorByModule: Map,
val delegateResolver: ResolverForProject = EmptyResolverForProject()
) : ResolverForProject() {
override fun tryGetResolverForModule(moduleInfo: M): ResolverForModule? {
if (!isCorrectModuleInfo(moduleInfo)) {
return null
}
return resolverForModuleDescriptor(doGetDescriptorForModule(moduleInfo))
}
internal val resolverByModuleDescriptor: MutableMap ResolverForModule> = HashMap()
override val allModules: Collection by lazy {
(descriptorByModule.keys + delegateResolver.allModules).toSet()
}
override val name: String
get() = "Resolver for '$debugName'"
private fun isCorrectModuleInfo(moduleInfo: M) = moduleInfo in allModules
override fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): ResolverForModule {
val computation = resolverByModuleDescriptor[descriptor] ?: return delegateResolver.resolverForModuleDescriptor(descriptor)
return computation()
}
override fun descriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
if (!isCorrectModuleInfo(moduleInfo)) {
throw AssertionError("$name does not know how to resolve $moduleInfo")
}
return doGetDescriptorForModule(moduleInfo)
}
private fun doGetDescriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
return descriptorByModule[moduleInfo] ?: delegateResolver.descriptorForModule(moduleInfo) as ModuleDescriptorImpl
}
}
data class ModuleContent(
val syntheticFiles: Collection,
val moduleContentScope: GlobalSearchScope
)
interface PlatformAnalysisParameters
interface ModuleInfo {
val isLibrary: Boolean
get() = false
val name: Name
fun dependencies(): List
fun modulesWhoseInternalsAreVisible(): Collection = listOf()
fun dependencyOnBuiltIns(): DependencyOnBuiltIns = DependenciesOnBuiltIns.LAST
val capabilities: Map, Any?>
get() = emptyMap()
//TODO: (module refactoring) provide dependency on builtins after runtime in IDEA
interface DependencyOnBuiltIns {
fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList)
}
enum class DependenciesOnBuiltIns : DependencyOnBuiltIns {
NONE {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList) {
//do nothing
}
},
LAST {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList) {
dependencies.add(builtinsModule)
}
};
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList) {
//TODO: KT-5457
}
}
}
abstract class AnalyzerFacade {
fun setupResolverForProject(
debugName: String,
projectContext: ProjectContext,
modules: Collection,
modulesContent: (M) -> ModuleContent,
platformParameters: P,
targetEnvironment: TargetEnvironment = CompilerEnvironment,
delegateResolver: ResolverForProject = EmptyResolverForProject(),
packagePartProviderFactory: (M, ModuleContent) -> PackagePartProvider = { module, content -> PackagePartProvider.Empty }
): ResolverForProject {
val storageManager = projectContext.storageManager
fun createResolverForProject(): ResolverForProjectImpl {
val descriptorByModule = HashMap()
modules.forEach {
module ->
descriptorByModule[module] = targetPlatform.createModule(module.name, storageManager, module.capabilities)
}
return ResolverForProjectImpl(debugName, descriptorByModule, delegateResolver)
}
val resolverForProject = createResolverForProject()
fun computeDependencyDescriptors(module: M): List {
val dependenciesDescriptors = module.dependencies().mapTo(ArrayList()) {
dependencyInfo ->
resolverForProject.descriptorForModule(dependencyInfo as M)
}
val builtinsModule = targetPlatform.builtIns.builtInsModule
module.dependencyOnBuiltIns().adjustDependencies(builtinsModule, dependenciesDescriptors)
return dependenciesDescriptors
}
fun computeModulesWhoseInternalsAreVisible(module: M): Set {
return module.modulesWhoseInternalsAreVisible().mapTo(LinkedHashSet()) { resolverForProject.descriptorForModule(it as M) }
}
fun setupModuleDependencies() {
modules.forEach {
module ->
resolverForProject.descriptorForModule(module).setDependencies(
LazyModuleDependencies(
storageManager,
{ computeDependencyDescriptors(module) },
{ computeModulesWhoseInternalsAreVisible(module) }
)
)
}
}
setupModuleDependencies()
fun initializeResolverForProject() {
modules.forEach {
module ->
val descriptor = resolverForProject.descriptorForModule(module)
val computeResolverForModule = storageManager.createLazyValue {
val content = modulesContent(module)
createResolverForModule(
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
platformParameters, targetEnvironment, resolverForProject,
packagePartProviderFactory(module, content)
)
}
descriptor.initialize(DelegatingPackageFragmentProvider { computeResolverForModule().packageFragmentProvider })
resolverForProject.resolverByModuleDescriptor[descriptor] = computeResolverForModule
}
}
initializeResolverForProject()
return resolverForProject
}
protected abstract fun createResolverForModule(
moduleInfo: M,
moduleDescriptor: ModuleDescriptorImpl,
moduleContext: ModuleContext,
moduleContent: ModuleContent,
platformParameters: P,
targetEnvironment: TargetEnvironment,
resolverForProject: ResolverForProject,
packagePartProvider: PackagePartProvider
): ResolverForModule
abstract val targetPlatform: TargetPlatform
}
//NOTE: relies on delegate to be lazily computed and cached
private class DelegatingPackageFragmentProvider(
private val delegate: () -> PackageFragmentProvider
) : PackageFragmentProvider {
override fun getPackageFragments(fqName: FqName): List {
return delegate().getPackageFragments(fqName)
}
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection {
return delegate().getSubPackagesOf(fqName, nameFilter)
}
}