Make test source module a friend of production source module
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
<root>
|
||||
<item name='com.intellij.openapi.vfs.VfsUtil java.lang.String getUrlForLibraryRoot(java.io.File)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.openapi.vfs.VirtualFile com.intellij.openapi.vfs.VirtualFile createChildDirectory(java.lang.Object, java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.openapi.vfs.LocalFileSystem com.intellij.openapi.vfs.LocalFileSystem getInstance()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.openapi.vfs.VfsUtil java.lang.String getUrlForLibraryRoot(java.io.File)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.openapi.vfs.VirtualFile com.intellij.openapi.vfs.VirtualFile createChildDirectory(java.lang.Object, java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
@@ -77,6 +77,7 @@ public trait PlatformAnalysisParameters
|
||||
public trait ModuleInfo {
|
||||
public val name: Name
|
||||
public fun dependencies(): List<ModuleInfo>
|
||||
public fun friends(): Collection<ModuleInfo> = listOf()
|
||||
public fun dependencyOnBuiltins(): DependencyOnBuiltins = DependenciesOnBuiltins.LAST
|
||||
|
||||
//TODO: (module refactoring) provide dependency on builtins after runtime in IDEA
|
||||
@@ -137,12 +138,24 @@ public trait AnalyzerFacade<out A : ResolverForModule, in P : PlatformAnalysisPa
|
||||
module.dependencyOnBuiltins().adjustDependencies(builtinsModule, dependenciesDescriptors)
|
||||
dependenciesDescriptors.forEach { currentModule.addDependencyOnModule(it) }
|
||||
}
|
||||
|
||||
resolverForProject.descriptorByModule.values().forEach { it.seal() }
|
||||
}
|
||||
|
||||
setupModuleDependencies()
|
||||
|
||||
fun addFriends() {
|
||||
modules.forEach {
|
||||
module ->
|
||||
val descriptor = resolverForProject.descriptorForModule(module)
|
||||
module.friends().forEach {
|
||||
descriptor.addFriend(resolverForProject.descriptorForModule(it as M))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addFriends()
|
||||
|
||||
resolverForProject.descriptorByModule.values().forEach { it.seal() }
|
||||
|
||||
fun initializeResolverForProject() {
|
||||
modules.forEach {
|
||||
module ->
|
||||
|
||||
@@ -86,9 +86,11 @@ public data class ModuleProductionSourceInfo(val module: Module) : IdeaModuleInf
|
||||
override fun contentScope() = module.getModuleScope(false)
|
||||
|
||||
override fun dependencies() = ideaModelDependencies(module, productionOnly = true)
|
||||
|
||||
override fun friends() = listOf(module.testSourceInfo())
|
||||
}
|
||||
|
||||
//TODO: (module refactoring) do not create ModuleTestSourceInfo when there are not test roots for module
|
||||
//TODO: (module refactoring) do not create ModuleTestSourceInfo when there are no test roots for module
|
||||
public data class ModuleTestSourceInfo(val module: Module) : IdeaModuleInfo() {
|
||||
override val name = Name.special("<test sources for module ${module.getName()}>")
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package shared
|
||||
|
||||
import shared.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: test">test</error>.*
|
||||
|
||||
private fun privateInM1() {
|
||||
}
|
||||
fun internalInM1() {
|
||||
}
|
||||
public fun publicInM1() {
|
||||
}
|
||||
|
||||
fun access() {
|
||||
privateInM1()
|
||||
internalInM1()
|
||||
publicInM1()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM1Test">privateInM1Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM1Test">internalInM1Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM1Test">publicInM1Test</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2">privateInM2</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2">internalInM2</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2">publicInM2</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2Test">privateInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2Test">internalInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2Test">publicInM2Test</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3">privateInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3">internalInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3">publicInM3</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3Test">privateInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3Test">internalInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3Test">publicInM3Test</error>()
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package shared.test
|
||||
|
||||
import shared.*
|
||||
|
||||
private fun privateInM1Test() {
|
||||
}
|
||||
fun internalInM1Test() {
|
||||
}
|
||||
public fun publicInM1Test() {
|
||||
}
|
||||
|
||||
fun access() {
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM1': it is 'private' in 'shared'">privateInM1</error>()
|
||||
internalInM1()
|
||||
publicInM1()
|
||||
|
||||
privateInM1Test()
|
||||
internalInM1Test()
|
||||
publicInM1Test()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2">privateInM2</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2">internalInM2</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2">publicInM2</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2Test">privateInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2Test">internalInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2Test">publicInM2Test</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3">privateInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3">internalInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3">publicInM3</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3Test">privateInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3Test">internalInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3Test">publicInM3Test</error>()
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package shared
|
||||
|
||||
import shared.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: test">test</error>.*
|
||||
|
||||
private fun privateInM2() {
|
||||
}
|
||||
fun internalInM2() {
|
||||
}
|
||||
public fun publicInM2() {
|
||||
}
|
||||
|
||||
fun access() {
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM1': it is 'private' in 'shared'">privateInM1</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM1': it is 'internal' in 'shared'">internalInM1</error>()
|
||||
publicInM1()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM1Test">privateInM1Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM1Test">internalInM1Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM1Test">publicInM1Test</error>()
|
||||
|
||||
privateInM2()
|
||||
internalInM2()
|
||||
publicInM2()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2Test">privateInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2Test">internalInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2Test">publicInM2Test</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3">privateInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3">internalInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3">publicInM3</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3Test">privateInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3Test">internalInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3Test">publicInM3Test</error>()
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package shared.test
|
||||
|
||||
import shared.*
|
||||
|
||||
private fun privateInM2Test() {
|
||||
}
|
||||
fun internalInM2Test() {
|
||||
}
|
||||
public fun publicInM2Test() {
|
||||
}
|
||||
|
||||
fun access() {
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM1': it is 'private' in 'shared'">privateInM1</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM1': it is 'internal' in 'shared'">internalInM1</error>()
|
||||
publicInM1()
|
||||
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM1Test': it is 'private' in 'test'">privateInM1Test</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM1Test': it is 'internal' in 'test'">internalInM1Test</error>()
|
||||
publicInM1Test()
|
||||
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM2': it is 'private' in 'shared'">privateInM2</error>()
|
||||
internalInM2()
|
||||
publicInM2()
|
||||
|
||||
privateInM2Test()
|
||||
internalInM2Test()
|
||||
publicInM2Test()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3">privateInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3">internalInM3</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3">publicInM3</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3Test">privateInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3Test">internalInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3Test">publicInM3Test</error>()
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package shared
|
||||
|
||||
import shared.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: test">test</error>.*
|
||||
|
||||
private fun privateInM3() {
|
||||
}
|
||||
fun internalInM3() {
|
||||
}
|
||||
public fun publicInM3() {
|
||||
}
|
||||
|
||||
fun access() {
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM1">privateInM1</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM1">internalInM1</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM1">publicInM1</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM1Test">privateInM1Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM1Test">internalInM1Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM1Test">publicInM1Test</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2">privateInM2</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2">internalInM2</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2">publicInM2</error>()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM2Test">privateInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM2Test">internalInM2Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM2Test">publicInM2Test</error>()
|
||||
|
||||
privateInM3()
|
||||
internalInM3()
|
||||
publicInM3()
|
||||
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: privateInM3Test">privateInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: internalInM3Test">internalInM3Test</error>()
|
||||
<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: publicInM3Test">publicInM3Test</error>()
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package shared.test
|
||||
|
||||
import shared.*
|
||||
|
||||
private fun privateInM3Test() {
|
||||
}
|
||||
fun internalInM3Test() {
|
||||
}
|
||||
public fun publicInM3Test() {
|
||||
}
|
||||
|
||||
fun access() {
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM1': it is 'private' in 'shared'">privateInM1</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM1': it is 'internal' in 'shared'">internalInM1</error>()
|
||||
publicInM1()
|
||||
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM1Test': it is 'private' in 'test'">privateInM1Test</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM1Test': it is 'internal' in 'test'">internalInM1Test</error>()
|
||||
publicInM1Test()
|
||||
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM2': it is 'private' in 'shared'">privateInM2</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM2': it is 'internal' in 'shared'">internalInM2</error>()
|
||||
publicInM2()
|
||||
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM2Test': it is 'private' in 'test'">privateInM2Test</error>()
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'internalInM2Test': it is 'internal' in 'test'">internalInM2Test</error>()
|
||||
publicInM2Test()
|
||||
|
||||
<error descr="[INVISIBLE_MEMBER] Cannot access 'privateInM3': it is 'private' in 'shared'">privateInM3</error>()
|
||||
internalInM3()
|
||||
publicInM3()
|
||||
|
||||
privateInM3Test()
|
||||
internalInM3Test()
|
||||
publicInM3Test()
|
||||
}
|
||||
@@ -22,6 +22,13 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import org.jetbrains.jet.plugin.project.PluginJetFilesProvider
|
||||
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import java.io.File
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.roots.DependencyScope
|
||||
import org.junit.Assert
|
||||
|
||||
class MultiModuleHighlightingTest : DaemonAnalyzerTestCase() {
|
||||
|
||||
@@ -55,16 +62,54 @@ class MultiModuleHighlightingTest : DaemonAnalyzerTestCase() {
|
||||
checkHighlightingInAllFiles()
|
||||
}
|
||||
|
||||
fun testTestRoot() {
|
||||
val module1 = module("m1", hasTestRoot = true)
|
||||
val module2 = module("m2", hasTestRoot = true)
|
||||
val module3 = module("m3", hasTestRoot = true)
|
||||
|
||||
module3.addDependency(module1, dependencyScope = DependencyScope.TEST)
|
||||
module3.addDependency(module2, dependencyScope = DependencyScope.TEST)
|
||||
module2.addDependency(module1, dependencyScope = DependencyScope.COMPILE)
|
||||
|
||||
checkHighlightingInAllFiles()
|
||||
}
|
||||
|
||||
private fun checkHighlightingInAllFiles() {
|
||||
var atLeastOneFile = false
|
||||
PluginJetFilesProvider.allFilesInProject(myProject!!).forEach { file ->
|
||||
atLeastOneFile = true
|
||||
configureByExistingFile(file.getVirtualFile()!!)
|
||||
checkHighlighting(myEditor, true, false)
|
||||
}
|
||||
Assert.assertTrue(atLeastOneFile)
|
||||
}
|
||||
|
||||
private fun module(name: String): Module {
|
||||
return createModuleFromTestData(TEST_DATA_PATH + "${getTestName(true)}/$name", "$name", StdModuleTypes.JAVA, true)!!
|
||||
private fun module(name: String, hasTestRoot: Boolean = false): Module {
|
||||
val srcDir = TEST_DATA_PATH + "${getTestName(true)}/$name"
|
||||
val moduleWithSrcRootSet = createModuleFromTestData(srcDir, "$name", StdModuleTypes.JAVA, true)!!
|
||||
if (hasTestRoot) {
|
||||
setTestRoot(moduleWithSrcRootSet, name)
|
||||
}
|
||||
return moduleWithSrcRootSet
|
||||
}
|
||||
|
||||
private fun Module.addDependency(other: Module) = ModuleRootModificationUtil.addDependency(this, other)
|
||||
private fun setTestRoot(module: Module, name: String) {
|
||||
val testDir = TEST_DATA_PATH + "${getTestName(true)}/${name}Test"
|
||||
val testRootDirInTestData = File(testDir)
|
||||
val testRootDir = createTempDirectory()!!
|
||||
FileUtil.copyDir(testRootDirInTestData, testRootDir)
|
||||
val testRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(testRootDir)!!
|
||||
object : WriteCommandAction.Simple<Unit>(getProject()) {
|
||||
override fun run() {
|
||||
testRoot.refresh(false, true)
|
||||
}
|
||||
}.execute().throwException()
|
||||
PsiTestUtil.addSourceRoot(module, testRoot, true)
|
||||
}
|
||||
|
||||
private fun Module.addDependency(
|
||||
other: Module,
|
||||
dependencyScope: DependencyScope = DependencyScope.COMPILE,
|
||||
exported: Boolean = false
|
||||
) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported)
|
||||
}
|
||||
Reference in New Issue
Block a user