Make test source module a friend of production source module

This commit is contained in:
Pavel V. Talanov
2014-09-10 21:45:06 +04:00
parent f3a9bed14a
commit 88b262faf1
10 changed files with 292 additions and 13 deletions
@@ -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)
}