diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.java b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.java index 6d146f3274f..13c4b4f7cfe 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.java +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.java @@ -32,6 +32,7 @@ import org.jetbrains.jps.builders.logging.ProjectBuilderLogger; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.ModuleBuildTarget; import org.jetbrains.jps.incremental.ProjectBuildException; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.kotlin.config.IncrementalCompilation; import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder; @@ -61,6 +62,11 @@ public class KotlinBuilderModuleScriptGenerator { ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); for (ModuleBuildTarget target : chunk.getTargets()) { File outputDir = getOutputDirSafe(target); + List friendDirs = new ArrayList(); + File friendDir = getFriendDirSafe(target); + if (friendDir != null) { + friendDirs.add(friendDir); + } List moduleSources = new ArrayList( IncrementalCompilation.isEnabled() @@ -85,7 +91,8 @@ public class KotlinBuilderModuleScriptGenerator { findClassPathRoots(target), (JavaModuleBuildTargetType) targetType, // this excludes the output directories from the class path, to be removed for true incremental compilation - outputDirs + outputDirs, + friendDirs ); } @@ -107,6 +114,17 @@ public class KotlinBuilderModuleScriptGenerator { return outputDir; } + @Nullable + public static File getFriendDirSafe(@NotNull ModuleBuildTarget target) throws ProjectBuildException { + if (!target.isTests()) return null; + + File outputDirForProduction = JpsJavaExtensionService.getInstance().getOutputDirectory(target.getModule(), false); + if (outputDirForProduction == null) { + throw new ProjectBuildException("No output production directory found for " + target); + } + return outputDirForProduction; + } + @NotNull private static Collection findClassPathRoots(@NotNull ModuleBuildTarget target) { return ContainerUtil.filter(getAllDependencies(target).classes().getRoots(), new Condition() { diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/modules/KotlinModuleXmlBuilder.java b/jps/jps-plugin/src/org/jetbrains/kotlin/modules/KotlinModuleXmlBuilder.java index 73cdd88fd4b..4b48e2340e5 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/modules/KotlinModuleXmlBuilder.java +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/modules/KotlinModuleXmlBuilder.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.utils.Printer; import java.io.File; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -47,7 +48,8 @@ public class KotlinModuleXmlBuilder { List javaSourceRoots, Collection classpathRoots, JavaModuleBuildTargetType targetType, - Set directoriesToFilterOut + Set directoriesToFilterOut, + @NotNull List friendDirs ) { assert !done : "Already done"; @@ -65,6 +67,10 @@ public class KotlinModuleXmlBuilder { ); p.pushIndent(); + for (File friendDir : friendDirs) { + p.println("<", FRIEND_DIR, " ", PATH, "=\"", getEscapedPath(friendDir), "\"/>"); + } + for (File sourceFile : sourceFiles) { p.println("<", SOURCES, " ", PATH, "=\"", getEscapedPath(sourceFile), "\"/>"); } diff --git a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt index 3b31cf01de5..f6a96f4e6e4 100644 --- a/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt +++ b/jps/jps-plugin/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt @@ -503,6 +503,21 @@ public class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() { checkWhen(touch("module2/src/b.kt"), null, packageClasses("module2", "module2/src/b.kt", "test.TestPackage")) } + public fun testCircularDependenciesSamePackageWithTests() { + initProject() + val result = makeAll() + result.assertSuccessful() + + // Check that outputs are located properly + val facadeWithA = findFileInOutputDir(findModule("module1"), "test/AKt.class") + val facadeWithB = findFileInOutputDir(findModule("module2"), "test/BKt.class") + UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "", "a", "funA", "getA") + UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "", "b", "funB", "getB", "setB") + + checkWhen(touch("module1/src/a.kt"), null, packageClasses("module1", "module1/src/a.kt", "test.TestPackage")) + checkWhen(touch("module2/src/b.kt"), null, packageClasses("module2", "module2/src/b.kt", "test.TestPackage")) + } + public fun testInternalFromAnotherModule() { initProject() val result = makeAll() @@ -517,6 +532,13 @@ public class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() { result.checkErrors() } + public fun testCircularDependenciesWrongInternalFromTests() { + initProject() + val result = makeAll() + result.assertFailed() + result.checkErrors() + } + public fun testCircularDependencyWithReferenceToOldVersionLib() { initProject() diff --git a/jps/jps-plugin/test/org/jetbrains/kotlin/jvm/compiler/ClasspathOrderTest.kt b/jps/jps-plugin/test/org/jetbrains/kotlin/jvm/compiler/ClasspathOrderTest.kt index 67d05520359..3408e3537e8 100644 --- a/jps/jps-plugin/test/org/jetbrains/kotlin/jvm/compiler/ClasspathOrderTest.kt +++ b/jps/jps-plugin/test/org/jetbrains/kotlin/jvm/compiler/ClasspathOrderTest.kt @@ -47,7 +47,8 @@ public class ClasspathOrderTest : TestCaseWithTmpdir() { listOf(JvmSourceRoot(sourceDir)), listOf(PathUtil.getKotlinPathsForDistDirectory().getRuntimePath()), JavaModuleBuildTargetType.PRODUCTION, - setOf() + setOf(), + emptyList() ).asText().toString() val xml = File(tmpdir, "module.xml") diff --git a/jps/jps-plugin/test/org/jetbrains/kotlin/modules/KotlinModuleXmlGeneratorTest.java b/jps/jps-plugin/test/org/jetbrains/kotlin/modules/KotlinModuleXmlGeneratorTest.java index a16f2d3ce01..a30b6c775ad 100644 --- a/jps/jps-plugin/test/org/jetbrains/kotlin/modules/KotlinModuleXmlGeneratorTest.java +++ b/jps/jps-plugin/test/org/jetbrains/kotlin/modules/KotlinModuleXmlGeneratorTest.java @@ -34,7 +34,8 @@ public class KotlinModuleXmlGeneratorTest extends TestCase { Collections.singletonList(new JvmSourceRoot(new File("java"), null)), Arrays.asList(new File("cp1"), new File("cp2")), JavaModuleBuildTargetType.PRODUCTION, - Collections.emptySet() + Collections.emptySet(), + Collections.emptyList() ).asText().toString(); KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/basic.xml"), actual); } @@ -47,7 +48,8 @@ public class KotlinModuleXmlGeneratorTest extends TestCase { Collections.emptyList(), Arrays.asList(new File("cp1"), new File("cp2")), JavaModuleBuildTargetType.PRODUCTION, - Collections.singleton(new File("cp1")) + Collections.singleton(new File("cp1")), + Collections.emptyList() ).asText().toString(); KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/filtered.xml"), actual); } @@ -61,7 +63,8 @@ public class KotlinModuleXmlGeneratorTest extends TestCase { Collections.emptyList(), Arrays.asList(new File("cp1"), new File("cp2")), JavaModuleBuildTargetType.PRODUCTION, - Collections.singleton(new File("cp1")) + Collections.singleton(new File("cp1")), + Collections.emptyList() ); builder.addModule( "name2", @@ -70,7 +73,8 @@ public class KotlinModuleXmlGeneratorTest extends TestCase { Collections.emptyList(), Arrays.asList(new File("cp12"), new File("cp22")), JavaModuleBuildTargetType.TEST, - Collections.singleton(new File("cp12")) + Collections.singleton(new File("cp12")), + Collections.emptyList() ); String actual = builder.asText().toString(); KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/multiple.xml"), actual); diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/kotlinProject.ipr b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/kotlinProject.ipr new file mode 100644 index 00000000000..c1a403dd047 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/kotlinProject.ipr @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/module1.iml b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/module1.iml new file mode 100644 index 00000000000..a28a2f8285e --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/module1.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/src/a.kt b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/src/a.kt new file mode 100644 index 00000000000..4da8772ebba --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/src/a.kt @@ -0,0 +1,9 @@ +package test + +fun a() { + +} + +internal fun funA() {} + +val a = "" diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/test/test_a_1.kt b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/test/test_a_1.kt new file mode 100644 index 00000000000..e3526b4ac21 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/test/test_a_1.kt @@ -0,0 +1,3 @@ +package test + +internal fun testFunA() {} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/test/test_a_2.kt b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/test/test_a_2.kt new file mode 100644 index 00000000000..028f7dbaa66 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module1/test/test_a_2.kt @@ -0,0 +1,6 @@ +package test + +fun foo() { + funA() + testFunA() +} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/module2.iml b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/module2.iml new file mode 100644 index 00000000000..a2e977d345b --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/module2.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/src/b.kt b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/src/b.kt new file mode 100644 index 00000000000..395d5075411 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/src/b.kt @@ -0,0 +1,9 @@ +package test + +fun b() { + +} + +internal fun funB() {} + +var b = b() diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/test/test_b_1.kt b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/test/test_b_1.kt new file mode 100644 index 00000000000..d6360452cef --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/test/test_b_1.kt @@ -0,0 +1,3 @@ +package test + +internal fun testFunB() {} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/test/test_b_2.kt b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/test/test_b_2.kt new file mode 100644 index 00000000000..b2dc2d25119 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesSamePackageWithTests/module2/test/test_b_2.kt @@ -0,0 +1,6 @@ +package test + +fun bar() { + funB() + testFunB() +} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/errors.txt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/errors.txt new file mode 100644 index 00000000000..f6a8fb3be27 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/errors.txt @@ -0,0 +1,4 @@ +Cannot access 'funA': it is 'internal' in 'test' at line 4, column 5 +Cannot access 'funB': it is 'internal' in 'test' at line 4, column 5 +Cannot access 'testFunA': it is 'internal' in 'test' at line 5, column 5 +Cannot access 'testFunB': it is 'internal' in 'test' at line 5, column 5 \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/kotlinProject.ipr b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/kotlinProject.ipr new file mode 100644 index 00000000000..c1a403dd047 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/kotlinProject.ipr @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/module1.iml b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/module1.iml new file mode 100644 index 00000000000..a28a2f8285e --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/module1.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/src/a.kt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/src/a.kt new file mode 100644 index 00000000000..4da8772ebba --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/src/a.kt @@ -0,0 +1,9 @@ +package test + +fun a() { + +} + +internal fun funA() {} + +val a = "" diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/test/test_a_1.kt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/test/test_a_1.kt new file mode 100644 index 00000000000..e3526b4ac21 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/test/test_a_1.kt @@ -0,0 +1,3 @@ +package test + +internal fun testFunA() {} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/test/test_a_2.kt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/test/test_a_2.kt new file mode 100644 index 00000000000..fb8416d39d3 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module1/test/test_a_2.kt @@ -0,0 +1,6 @@ +package test + +fun foo() { + funB() + testFunB() +} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/module2.iml b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/module2.iml new file mode 100644 index 00000000000..a2e977d345b --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/module2.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/src/b.kt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/src/b.kt new file mode 100644 index 00000000000..395d5075411 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/src/b.kt @@ -0,0 +1,9 @@ +package test + +fun b() { + +} + +internal fun funB() {} + +var b = b() diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/test/test_b_1.kt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/test/test_b_1.kt new file mode 100644 index 00000000000..d6360452cef --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/test/test_b_1.kt @@ -0,0 +1,3 @@ +package test + +internal fun testFunB() {} \ No newline at end of file diff --git a/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/test/test_b_2.kt b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/test/test_b_2.kt new file mode 100644 index 00000000000..e9ce5c96421 --- /dev/null +++ b/jps/jps-plugin/testData/general/CircularDependenciesWrongInternalFromTests/module2/test/test_b_2.kt @@ -0,0 +1,6 @@ +package test + +fun bar() { + funA() + testFunA() +} \ No newline at end of file