FIR: implement -Xfriend-paths
This commit is contained in:
@@ -58,6 +58,7 @@ fun FirSession.registerResolveComponents() {
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun FirSession.registerJavaSpecificResolveComponents() {
|
||||
register(FirVisibilityChecker::class, FirJavaVisibilityChecker)
|
||||
register(FirModuleVisibilityChecker::class, FirJvmModuleVisibilityChecker(this))
|
||||
register(ConeCallConflictResolverFactory::class, JvmCallConflictResolverFactory)
|
||||
register(FirEffectiveVisibilityResolver::class, FirJvmEffectiveVisibilityResolver(this))
|
||||
register(FirPlatformClassMapper::class, FirJavaClassMapper(this))
|
||||
|
||||
@@ -6,23 +6,30 @@
|
||||
package org.jetbrains.kotlin.fir.session
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
|
||||
class FirJvmModuleInfo(override val name: Name, val dependencies: List<ModuleInfo>) : ModuleInfo {
|
||||
class FirJvmModuleInfo(
|
||||
override val name: Name,
|
||||
val dependencies: List<ModuleInfo> = emptyList(),
|
||||
val friendPaths: List<String> = emptyList(),
|
||||
val outputDirectory: String? = null
|
||||
) : ModuleInfo {
|
||||
companion object {
|
||||
val LIBRARIES_MODULE_NAME = Name.special("<dependencies>")
|
||||
|
||||
fun createForLibraries(mainModuleName: String? = null): FirJvmModuleInfo {
|
||||
val name = mainModuleName?.let { Name.special("<dependencies of $it>") } ?: LIBRARIES_MODULE_NAME
|
||||
return FirJvmModuleInfo(name, emptyList())
|
||||
return FirJvmModuleInfo(name)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(moduleName: String, dependencies: List<ModuleInfo>) : this(Name.identifier(moduleName), dependencies)
|
||||
constructor(module: Module, dependencies: List<ModuleInfo>) :
|
||||
this(Name.identifier(module.getModuleName()), dependencies, module.getFriendPaths(), module.getOutputDirectory())
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = JvmPlatforms.unspecifiedJvmPlatform
|
||||
@@ -30,7 +37,6 @@ class FirJvmModuleInfo(override val name: Name, val dependencies: List<ModuleInf
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||
get() = JvmPlatformAnalyzerServices
|
||||
|
||||
override fun dependencies(): List<ModuleInfo> {
|
||||
return dependencies
|
||||
}
|
||||
override fun dependencies(): List<ModuleInfo> =
|
||||
dependencies
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.session
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import org.jetbrains.kotlin.fir.FirModuleVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.containerSource
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
|
||||
import java.nio.file.Paths
|
||||
|
||||
class FirJvmModuleVisibilityChecker(private val session: FirSession) : FirModuleVisibilityChecker {
|
||||
override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean {
|
||||
val moduleInfo = session.moduleInfo as? FirJvmModuleInfo ?: return false
|
||||
val binaryClass = when (val source = declaration.containerSource) {
|
||||
is KotlinJvmBinarySourceElement -> source.binaryClass
|
||||
is JvmPackagePartSource -> source.knownJvmBinaryClass
|
||||
else -> null
|
||||
} as? VirtualFileKotlinClass ?: return false
|
||||
// For incremental compilation, the already compiled part of the module should be accessible.
|
||||
return moduleInfo.friendPaths.any { binaryClass.isIn(it) } || moduleInfo.outputDirectory?.let { binaryClass.isIn(it) } == true
|
||||
}
|
||||
|
||||
private fun VirtualFileKotlinClass.isIn(jarOrDirectory: String): Boolean =
|
||||
when (file.fileSystem.protocol) {
|
||||
StandardFileSystems.FILE_PROTOCOL ->
|
||||
VfsUtilCore.virtualToIoFile(file).toPath().startsWith(jarOrDirectory)
|
||||
StandardFileSystems.JAR_PROTOCOL ->
|
||||
VfsUtilCore.getVirtualFileForJar(file)?.let(VfsUtilCore::virtualToIoFile)?.toPath() == Paths.get(jarOrDirectory)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user