diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt index 81a2301ec1e..58bb145d6d9 100644 --- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt +++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt @@ -373,6 +373,11 @@ class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() { makeAll().assertSuccessful() } + fun testKotlinJavaScriptInternalFromSpecialRelatedModule() { + initProject(JS_STDLIB) + makeAll().assertSuccessful() + } + fun testKotlinJavaScriptProjectWithTests() { initProject(JS_STDLIB) makeAll().assertSuccessful() diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt index 4d9f6be7c37..5cdad1f9fe7 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt @@ -82,6 +82,7 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { environment: JpsCompilerEnvironment, sourceFiles: Collection, libraries: List, + friendModules: List, outputFile: File ) { log.debug("K2JS: common arguments: " + ArgumentUtils.convertArgumentsToStringList(commonArguments)) @@ -90,7 +91,7 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2jsArguments)) log.debug("K2JS: merged arguments: " + ArgumentUtils.convertArgumentsToStringList(arguments)) - setupK2JsArguments(outputFile, sourceFiles, libraries, arguments) + setupK2JsArguments(outputFile, sourceFiles, libraries, friendModules, arguments) log.debug("K2JS: arguments after setup" + ArgumentUtils.convertArgumentsToStringList(arguments)) withCompilerSettings(compilerSettings) { @@ -203,13 +204,14 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner() { } } - private fun setupK2JsArguments(_outputFile: File, sourceFiles: Collection, _libraries: List, settings: K2JSCompilerArguments) { + private fun setupK2JsArguments(_outputFile: File, sourceFiles: Collection, _libraries: List, _friendModules: List, settings: K2JSCompilerArguments) { with(settings) { noStdlib = true freeArgs = sourceFiles.map { it.path } outputFile = _outputFile.path metaInfo = true libraries = _libraries.joinToString(File.pathSeparator) + friendModules = _friendModules.joinToString(File.pathSeparator) } } diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/JpsJsModuleUtils.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/JpsJsModuleUtils.kt index 476c3d2179c..a26bb7e50b0 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/JpsJsModuleUtils.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/JpsJsModuleUtils.kt @@ -51,18 +51,16 @@ object JpsJsModuleUtils { if (module.moduleType != JpsJavaModuleType.INSTANCE) return if ((module != target.module || target.isTests) && module.sourceRoots.any { it.rootType == JavaSourceRootType.SOURCE}) { - addTarget(module, JavaModuleBuildTargetType.PRODUCTION) + addTarget(module, isTests = false) } if (module != target.module && target.isTests && module.sourceRoots.any { it.rootType == JavaSourceRootType.TEST_SOURCE}) { - addTarget(module, JavaModuleBuildTargetType.TEST) + addTarget(module, isTests = true) } } - fun addTarget(module: JpsModule, targetType: JavaModuleBuildTargetType) { - val moduleBuildTarget = ModuleBuildTarget(module, targetType) - val outputDir = KotlinBuilderModuleScriptGenerator.getOutputDirSafe(moduleBuildTarget) - val metaInfoFile = getOutputMetaFile(outputDir, module.name, targetType.isTests) + fun addTarget(module: JpsModule, isTests: Boolean) { + val metaInfoFile = getOutputMetaFile(module, isTests) if (metaInfoFile.exists()) { result.add(metaInfoFile.absolutePath) } @@ -70,6 +68,13 @@ object JpsJsModuleUtils { }) } + @JvmStatic + fun getOutputMetaFile(module: JpsModule, isTests: Boolean): File { + val moduleBuildTarget = ModuleBuildTarget(module, if (isTests) JavaModuleBuildTargetType.TEST else JavaModuleBuildTargetType.PRODUCTION) + val outputDir = KotlinBuilderModuleScriptGenerator.getOutputDirSafe(moduleBuildTarget) + return getOutputMetaFile(outputDir, module.name, isTests) + } + @JvmStatic fun getOutputFile(outputDir: File, moduleName: String, isTests: Boolean) = File(outputDir, moduleName + suffix(isTests) + KotlinJavascriptMetadataUtils.JS_EXT) diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 86556d9a2f6..c1cf1016223 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -57,6 +57,7 @@ import org.jetbrains.kotlin.daemon.common.isDaemonEnabled import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.jps.JpsKotlinCompilerSettings +import org.jetbrains.kotlin.jps.build.JpsJsModuleUtils.getOutputMetaFile import org.jetbrains.kotlin.jps.incremental.* import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents @@ -661,8 +662,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val compilerSettings = JpsKotlinCompilerSettings.getCompilerSettings(representativeModule) val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(representativeModule) + val friendPaths = KotlinBuilderModuleScriptGenerator.getProductionModulesWhichInternalsAreVisible(representativeTarget).mapNotNull { + val file = getOutputMetaFile(it, false) + if (file.exists()) file.absolutePath.toString() else null + } + val compilerRunner = JpsKotlinCompilerRunner() - compilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, environment, sourceFiles, libraries, outputFile) + compilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, environment, sourceFiles, libraries, friendPaths, outputFile) return environment.outputItemsCollector } diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.kt index 500d7c50ecb..f216c680c37 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilderModuleScriptGenerator.kt @@ -132,20 +132,21 @@ object KotlinBuilderModuleScriptGenerator { fun getOutputDirSafe(target: ModuleBuildTarget): File = target.outputDir ?: throw ProjectBuildException("No output directory found for " + target) - private fun getAdditionalOutputDirsWhereInternalsAreVisible(target: ModuleBuildTarget): List { - if (!target.isTests) return emptyList() + fun getProductionModulesWhichInternalsAreVisible(from: ModuleBuildTarget): List { + if (!from.isTests) return emptyList() - val result = SmartList() - - result.addIfNotNull(JpsJavaExtensionService.getInstance().getOutputDirectory(target.module, false)) - - getRelatedProductionModule(target.module)?.let { - result.addIfNotNull(JpsJavaExtensionService.getInstance().getOutputDirectory(it, false)) - } + val result = SmartList(from.module) + result.addIfNotNull(getRelatedProductionModule(from.module)) return result } + fun getAdditionalOutputDirsWhereInternalsAreVisible(target: ModuleBuildTarget): List { + return getProductionModulesWhichInternalsAreVisible(target).mapNotNullTo(SmartList()) { + JpsJavaExtensionService.getInstance().getOutputDirectory(it, false) + } + } + private fun findClassPathRoots(target: ModuleBuildTarget): Collection { return getAllDependencies(target).classes().roots.filter { file -> if (!file.exists()) { diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/kotlinProject.ipr b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/kotlinProject.ipr new file mode 100644 index 00000000000..c1a403dd047 --- /dev/null +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/kotlinProject.ipr @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module1/module1.iml b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module1/module1.iml new file mode 100644 index 00000000000..3b1ba79ed61 --- /dev/null +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module1/module1.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module1/src/foo.kt b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module1/src/foo.kt new file mode 100644 index 00000000000..830308321e1 --- /dev/null +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module1/src/foo.kt @@ -0,0 +1,27 @@ +package test1 + +@Target(AnnotationTarget.FILE) +@Retention(AnnotationRetention.SOURCE) +internal annotation class InternalFileAnnotation1() + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +internal annotation class InternalClassAnnotation1() + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.SOURCE) +internal annotation class InternalFunctionAnnotation1() + +internal open class InternalClass1 + +abstract class ClassA1(internal val member: Int) + +abstract class ClassB1 { + internal abstract val member: Int + internal fun func() = 1 +} + +internal val internalProp = 1 + +internal fun internalFun() {} + diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module2/module2.iml b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module2/module2.iml new file mode 100644 index 00000000000..427f7bce96f --- /dev/null +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module2/module2.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module2/test/bar.kt b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module2/test/bar.kt new file mode 100644 index 00000000000..22519ed79af --- /dev/null +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptInternalFromSpecialRelatedModule/module2/test/bar.kt @@ -0,0 +1,33 @@ +@file:InternalFileAnnotation1 + +package test2 + +import test1.* + +internal class FromInternalClass1: InternalClass1() + +@InternalClassAnnotation1 +class FromClassA1 : ClassA1(10) { + @InternalClassAnnotation1 + class Nested { + @InternalFunctionAnnotation1 + fun foo() {} + } +} + +class FromClassB1 : ClassB1() { + internal override val member = 10 +} + +@InternalFunctionAnnotation1 +fun foo() {} + +fun box() { + internalProp + internalFun() + + InternalClass1() + FromClassA1().member + FromClassB1().member + FromClassB1().func() +} diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/src/Main.kt b/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/src/Main.kt index e97bc7ec751..bc18855ddf8 100644 --- a/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/src/Main.kt +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/src/Main.kt @@ -1,2 +1,6 @@ fun main() { -} \ No newline at end of file +} + +internal fun internalFun() {} + +internal val internalVal = 10 diff --git a/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/tests/MainTests.kt b/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/tests/MainTests.kt index d0fbf1444f8..ad63f184bce 100644 --- a/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/tests/MainTests.kt +++ b/jps/jps-plugin/testData/general/KotlinJavaScriptProjectWithTests/tests/MainTests.kt @@ -1,3 +1,5 @@ fun testMain() { main() -} \ No newline at end of file + internalFun() + var a = internalVal +}