From 0e428ca10cb92923ea177b0773d00a56e16c3de5 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 14 Jun 2016 21:09:42 +0300 Subject: [PATCH] JPS: don't consider that production target of module "B" is depends on test target of module "A" when "B" depends on "A" #KT-12595 Fixed --- .../kotlin/jps/build/KotlinJpsBuildTest.kt | 62 ++++++++++++++++++- .../kotlin/jps/build/KotlinBuilder.kt | 9 +-- .../general/GetDependentTargets/expected.txt | 42 +++++++++++++ .../general/GetDependentTargets/src/foo.kt | 3 + .../general/GetDependentTargets/test/test.kt | 3 + 5 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 jps-plugin/testData/general/GetDependentTargets/expected.txt create mode 100644 jps-plugin/testData/general/GetDependentTargets/src/foo.kt create mode 100644 jps-plugin/testData/general/GetDependentTargets/test/test.kt diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt index 024e486c2bb..fa258d46e30 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt @@ -26,6 +26,7 @@ import com.intellij.testFramework.UsefulTestCase import com.intellij.util.ArrayUtil import com.intellij.util.containers.ContainerUtil import com.intellij.util.io.ZipUtil +import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.api.CanceledStatus import org.jetbrains.jps.builders.BuildResult import org.jetbrains.jps.builders.CompileScopeTestBuilder @@ -33,16 +34,23 @@ import org.jetbrains.jps.builders.JpsBuildTestCase import org.jetbrains.jps.builders.TestProjectBuilderLogger import org.jetbrains.jps.builders.impl.BuildDataPathsImpl import org.jetbrains.jps.builders.logging.BuildLoggingManager +import org.jetbrains.jps.cmdline.ProjectDescriptor import org.jetbrains.jps.incremental.BuilderRegistry +import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.IncProjectBuilder +import org.jetbrains.jps.incremental.ModuleLevelBuilder import org.jetbrains.jps.incremental.messages.BuildMessage import org.jetbrains.jps.incremental.messages.CompilerMessage +import org.jetbrains.jps.model.JpsModuleRootModificationUtil +import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.jps.model.java.JpsJavaDependencyScope import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.util.JpsPathUtil import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil +import org.jetbrains.kotlin.incremental.CacheVersion +import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.test.KotlinTestUtils @@ -754,18 +762,66 @@ class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() { doTest() } + fun testGetDependentTargets() { + fun addModuleWithSourceAndTestRoot(name: String): JpsModule { + return addModule(name, "src/").apply { + contentRootsList.addUrl(JpsPathUtil.pathToUrl("test/")) + addSourceRoot(JpsPathUtil.pathToUrl("test/"), JavaSourceRootType.TEST_SOURCE) + } + } + + val a = addModuleWithSourceAndTestRoot("a") + val b = addModuleWithSourceAndTestRoot("b") + val c = addModuleWithSourceAndTestRoot("c") + val b2 = addModuleWithSourceAndTestRoot("b2") + val c2 = addModuleWithSourceAndTestRoot("c2") + + JpsModuleRootModificationUtil.addDependency(b, a, JpsJavaDependencyScope.COMPILE, /*exported =*/ true) + JpsModuleRootModificationUtil.addDependency(c, b, JpsJavaDependencyScope.COMPILE, /*exported =*/ false) + JpsModuleRootModificationUtil.addDependency(b2, a, JpsJavaDependencyScope.COMPILE, /*exported =*/ false) + JpsModuleRootModificationUtil.addDependency(c2, b2, JpsJavaDependencyScope.COMPILE, /*exported =*/ false) + + val actual = StringBuilder() + buildCustom(CanceledStatus.NULL, TestProjectBuilderLogger(), BuildResult()) { + project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object: BuildLogger { + override fun buildStarted(context: CompileContext, chunk: ModuleChunk) { + actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n") + actual.append(getDependentTargets(chunk, context).map { it.toString() }.sorted().joinToString("\n")) + actual.append("\n---------\n") + } + + override fun actionsOnCacheVersionChanged(actions: List) {} + override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {} + override fun markedAsDirty(files: Iterable) {} + })) + } + + val expectedFile = File(getCurrentTestDataRoot(), "expected.txt") + + KotlinTestUtils.assertEqualsToFile(expectedFile, actual.toString()) + } + private fun BuildResult.checkErrors() { val actualErrors = getMessages(BuildMessage.Kind.ERROR) .map { it as CompilerMessage } .map { "${it.messageText} at line ${it.line}, column ${it.column}" }.sorted().joinToString("\n") - val projectRoot = File(AbstractKotlinJpsBuildTestCase.TEST_DATA_PATH + "general/" + getTestName(false)) - val expectedFile = File(projectRoot, "errors.txt") + val expectedFile = File(getCurrentTestDataRoot(), "errors.txt") KotlinTestUtils.assertEqualsToFile(expectedFile, actualErrors) } - private fun buildCustom(canceledStatus: CanceledStatus, logger: TestProjectBuilderLogger,buildResult: BuildResult) { + private fun getCurrentTestDataRoot() = File(AbstractKotlinJpsBuildTestCase.TEST_DATA_PATH + "general/" + getTestName(false)) + + private fun buildCustom( + canceledStatus: CanceledStatus, + logger: TestProjectBuilderLogger, + buildResult: BuildResult, + setupProject: ProjectDescriptor.() -> Unit = {} + ) { val scopeBuilder = CompileScopeTestBuilder.make().all() val descriptor = this.createProjectDescriptor(BuildLoggingManager(logger)) + + descriptor.setupProject() + try { val builder = IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), this.myBuildParams, canceledStatus, null, true) builder.addMessageHandler(buildResult) diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 5edbe429833..558f82c70ba 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -142,7 +142,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode - LOG.info("Build result: " + actualExitCode) + LOG.debug("Build result: " + actualExitCode) context.testingContext?.buildLogger?.buildFinished(actualExitCode) @@ -820,14 +820,15 @@ private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): M return chunkCaches } -private fun getDependentTargets( +fun getDependentTargets( compilingChunk: ModuleChunk, context: CompileContext ): Set { - val classpathKind = JpsJavaClasspathKind.compile(compilingChunk.targets.any { it.isTests }) + val compilingChunkIsTests = compilingChunk.targets.any { it.isTests } + val classpathKind = JpsJavaClasspathKind.compile(compilingChunkIsTests) fun dependsOnCompilingChunk(target: BuildTarget<*>): Boolean { - if (target !is ModuleBuildTarget) return false + if (target !is ModuleBuildTarget || compilingChunkIsTests && !target.isTests) return false val dependencies = getDependenciesRecursively(target.module, classpathKind) return ContainerUtil.intersects(dependencies, compilingChunk.modules) diff --git a/jps-plugin/testData/general/GetDependentTargets/expected.txt b/jps-plugin/testData/general/GetDependentTargets/expected.txt new file mode 100644 index 00000000000..19377f83f9f --- /dev/null +++ b/jps-plugin/testData/general/GetDependentTargets/expected.txt @@ -0,0 +1,42 @@ +Targets dependent on Module 'a' production: +Module 'a' tests +Module 'b' production +Module 'b' tests +Module 'b2' production +Module 'b2' tests +Module 'c' production +Module 'c' tests +--------- +Targets dependent on Module 'a' tests: +Module 'b' tests +Module 'b2' tests +Module 'c' tests +--------- +Targets dependent on Module 'b2' production: +Module 'b2' tests +Module 'c2' production +Module 'c2' tests +--------- +Targets dependent on Module 'b2' tests: +Module 'c2' tests +--------- +Targets dependent on Module 'c2' production: +Module 'c2' tests +--------- +Targets dependent on Module 'c2' tests: + +--------- +Targets dependent on Module 'b' production: +Module 'b' tests +Module 'c' production +Module 'c' tests +--------- +Targets dependent on Module 'b' tests: +Module 'c' tests +--------- +Targets dependent on Module 'c' production: +Module 'c' tests +--------- +Targets dependent on Module 'c' tests: + +--------- diff --git a/jps-plugin/testData/general/GetDependentTargets/src/foo.kt b/jps-plugin/testData/general/GetDependentTargets/src/foo.kt new file mode 100644 index 00000000000..a2c4e958bb5 --- /dev/null +++ b/jps-plugin/testData/general/GetDependentTargets/src/foo.kt @@ -0,0 +1,3 @@ +fun foo() { + +} \ No newline at end of file diff --git a/jps-plugin/testData/general/GetDependentTargets/test/test.kt b/jps-plugin/testData/general/GetDependentTargets/test/test.kt new file mode 100644 index 00000000000..839220d1002 --- /dev/null +++ b/jps-plugin/testData/general/GetDependentTargets/test/test.kt @@ -0,0 +1,3 @@ +fun test() { + +}