Implement module accessibility checks differently in compiler and IDE
Essentially, the logic that was previously in JvmModuleAccessibilityChecker.diagnosticFor, is moved into a new abstract method JavaModuleResolver.checkAccessibility, which is implemented differently in the compiler and in the IDE. In the compiler, we use our JavaModuleInfo and JavaModuleGraph, as previously. In the IDE, we use intellij's PsiJavaModule and JavaModuleGraphUtil. This fixes strange behavior in IDE where some modules could be observed in an invalid state. The cause of that was the JavaModuleGraph instance caching modules in IdeJavaModuleResolver, which is a project component. Moreover, this will allow to report an error "named module does not read unnamed module" in the compiler, and avoid reporting it in the IDE (see the comment in IdeJavaModuleResolver about that)
This commit is contained in:
@@ -21,12 +21,13 @@ import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleGraph
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
|
||||
class CliJavaModuleResolver(
|
||||
override val moduleGraph: JavaModuleGraph,
|
||||
private val moduleGraph: JavaModuleGraph,
|
||||
private val javaModules: List<JavaModule>
|
||||
) : JavaModuleResolver {
|
||||
init {
|
||||
@@ -37,7 +38,7 @@ class CliJavaModuleResolver(
|
||||
|
||||
private val sourceModule = javaModules.firstOrNull { !it.isBinary }
|
||||
|
||||
override fun findJavaModule(file: VirtualFile): JavaModule? =
|
||||
private fun findJavaModule(file: VirtualFile): JavaModule? =
|
||||
when (file.fileType) {
|
||||
KotlinFileType.INSTANCE, JavaFileType.INSTANCE -> sourceModule
|
||||
JavaClassFileType.INSTANCE -> javaModules.firstOrNull { module ->
|
||||
@@ -45,4 +46,28 @@ class CliJavaModuleResolver(
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun checkAccessibility(
|
||||
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
|
||||
): JavaModuleResolver.AccessError? {
|
||||
val ourModule = fileFromOurModule?.let(this::findJavaModule)
|
||||
val theirModule = this.findJavaModule(referencedFile)
|
||||
|
||||
if (ourModule?.name == theirModule?.name) return null
|
||||
|
||||
if (theirModule == null) {
|
||||
return JavaModuleResolver.AccessError.ModuleDoesNotReadUnnamedModule
|
||||
}
|
||||
|
||||
if (ourModule != null && !moduleGraph.reads(ourModule.name, theirModule.name)) {
|
||||
return JavaModuleResolver.AccessError.ModuleDoesNotReadModule(theirModule.name)
|
||||
}
|
||||
|
||||
val fqName = referencedPackage ?: return null
|
||||
if (!theirModule.exports(fqName) && (ourModule == null || !theirModule.exportsTo(fqName, ourModule.name))) {
|
||||
return JavaModuleResolver.AccessError.ModuleDoesNotExportPackage(theirModule.name)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user