fix access from tests to internal elements in production code in case of circular dependency
This commit is contained in:
@@ -28,6 +28,7 @@ public class ModuleBuilder(
|
||||
private val sourceFiles = ArrayList<String>()
|
||||
private val classpathRoots = ArrayList<String>()
|
||||
private val javaSourceRoots = ArrayList<JavaRootPath>()
|
||||
private val friendDirs = ArrayList<String>()
|
||||
|
||||
public fun addSourceFiles(pattern: String) {
|
||||
sourceFiles.add(pattern)
|
||||
@@ -41,7 +42,12 @@ public class ModuleBuilder(
|
||||
javaSourceRoots.add(rootPath)
|
||||
}
|
||||
|
||||
public fun addFriendDir(friendDir: String) {
|
||||
friendDirs.add(friendDir)
|
||||
}
|
||||
|
||||
override fun getOutputDirectory(): String = outputDir
|
||||
override fun getFriendPaths(): List<String> = friendDirs
|
||||
override fun getJavaSourceRoots(): List<JavaRootPath> = javaSourceRoots
|
||||
override fun getSourceFiles(): List<String> = sourceFiles
|
||||
override fun getClasspathRoots(): List<String> = classpathRoots
|
||||
|
||||
+5
@@ -47,6 +47,7 @@ public class ModuleXmlParser {
|
||||
public static final String TYPE_PRODUCTION = "java-production";
|
||||
public static final String TYPE_TEST = "java-test";
|
||||
public static final String OUTPUT_DIR = "outputDir";
|
||||
public static final String FRIEND_DIR = "friendDir";
|
||||
public static final String SOURCES = "sources";
|
||||
public static final String JAVA_SOURCE_ROOTS = "javaSourceRoots";
|
||||
public static final String JAVA_SOURCE_PACKAGE_PREFIX = "packagePrefix";
|
||||
@@ -162,6 +163,10 @@ public class ModuleXmlParser {
|
||||
String path = getAttribute(attributes, PATH, qName);
|
||||
moduleBuilder.addSourceFiles(path);
|
||||
}
|
||||
else if (FRIEND_DIR.equalsIgnoreCase(qName)) {
|
||||
String path = getAttribute(attributes, PATH, qName);
|
||||
moduleBuilder.addFriendDir(path);
|
||||
}
|
||||
else if (CLASSPATH.equalsIgnoreCase(qName)) {
|
||||
String path = getAttribute(attributes, PATH, qName);
|
||||
moduleBuilder.addClasspathEntry(path);
|
||||
|
||||
@@ -18,13 +18,11 @@ package org.jetbrains.kotlin.cli.common
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.load.kotlin.getSourceElement
|
||||
import org.jetbrains.kotlin.load.kotlin.isContainedByCompiledPartOfOurModule
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.util.ModuleVisibilityHelper
|
||||
@@ -44,37 +42,37 @@ class ModuleVisibilityHelperImpl : ModuleVisibilityHelper {
|
||||
}
|
||||
|
||||
val moduleVisibilityManager = ModuleVisibilityManager.SERVICE.getInstance(project)
|
||||
|
||||
fun findModule(kotlinFile: KtFile): Module? = moduleVisibilityManager.chunk.firstOrNull { it.getSourceFiles().containsRaw(kotlinFile.virtualFile.path) }
|
||||
|
||||
val whatSource = getSourceElement(what)
|
||||
if (whatSource is KotlinSourceElement) {
|
||||
if (moduleVisibilityManager.chunk.size > 1 && fromSource is KotlinSourceElement) {
|
||||
val fromSourceKotlinFile = fromSource.psi.getContainingKtFile()
|
||||
val whatSourceKotlinFile = whatSource.psi.getContainingKtFile()
|
||||
return findModule(whatSourceKotlinFile) === findModule(fromSourceKotlinFile)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
moduleVisibilityManager.friendPaths.forEach {
|
||||
if (isContainedByCompiledPartOfOurModule(what, File(it))) return true
|
||||
}
|
||||
|
||||
val modules = moduleVisibilityManager.chunk
|
||||
|
||||
val outputDirectories = modules.map { File(it.getOutputDirectory()) }
|
||||
if (outputDirectories.isEmpty()) return isContainedByCompiledPartOfOurModule(what, null)
|
||||
val whatSource = getSourceElement(what)
|
||||
if (whatSource is KotlinSourceElement) {
|
||||
if (modules.size > 1 && fromSource is KotlinSourceElement) {
|
||||
return findModule(what, modules) === findModule(from, modules)
|
||||
}
|
||||
|
||||
outputDirectories.forEach {
|
||||
if (isContainedByCompiledPartOfOurModule(what, it)) return true
|
||||
return true
|
||||
}
|
||||
|
||||
// Hack in order to allow access to internal elements in production code from tests
|
||||
if (modules.singleOrNull()?.getModuleType() == ModuleXmlParser.TYPE_TEST) return true
|
||||
if (modules.isEmpty()) return false
|
||||
|
||||
return false
|
||||
return findModule(from, modules) === findModule(what, modules)
|
||||
}
|
||||
|
||||
private fun findModule(descriptor: DeclarationDescriptor, modules: Collection<Module>): Module? {
|
||||
val sourceElement = getSourceElement(descriptor)
|
||||
if (sourceElement is KotlinSourceElement) {
|
||||
return modules.singleOrNull() ?: modules.firstOrNull { sourceElement.psi.getContainingKtFile().virtualFile.path in it.getSourceFiles() }
|
||||
}
|
||||
else {
|
||||
return modules.firstOrNull { module ->
|
||||
isContainedByCompiledPartOfOurModule(descriptor, File(module.getOutputDirectory())) ||
|
||||
module.getFriendPaths().any { isContainedByCompiledPartOfOurModule(descriptor, File(it))}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user