diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index c56e9a795d1..bd0cfa9ced3 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -716,6 +716,30 @@ abstract class CommonCompilerArguments : CommonToolArguments() { field = value } + @Argument( + value = "-Xmodule", + valueDescription = ";", + description = "Describes module with specific sources. Usage of this arguments requires to specify module for each source file from free args", + delimiter = "" + ) + var modulesDescription: Array? = null + set(value) { + checkFrozen() + field = value + } + + @Argument( + value = "-XdependsOn", + valueDescription = ":", + description = "Declares that depends on with dependsOn relation", + delimiter = "" + ) + var dependsOnDependencies: Array? = null + set(value) { + checkFrozen() + field = value + } + @OptIn(IDEAPluginsCompatibilityAPI::class) open fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap, Any> { return HashMap, Any>().apply { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt index dffee8d4eaa..dfcbdd91b0e 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.cli.common +import com.intellij.ide.highlighter.JavaFileType import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments import org.jetbrains.kotlin.cli.common.arguments.ManualLanguageFeatureSetting @@ -12,6 +13,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion +import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.KotlinPaths import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir import org.jetbrains.kotlin.utils.PathUtil @@ -47,6 +49,7 @@ fun CompilerConfiguration.setupCommonArguments( val usesK2 = arguments.useK2 || languageVersionSettings.languageVersion.usesK2 put(CommonConfigurationKeys.USE_FIR, usesK2) put(CommonConfigurationKeys.USE_LIGHT_TREE, arguments.useFirLT) + buildHmppModuleStructure(arguments)?.let { put(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE, it) } } fun CompilerConfiguration.setupLanguageVersionSettings(arguments: A) { @@ -125,3 +128,134 @@ private fun MessageCollector.reportUnsafeInternalArgum ) } } + +private fun CompilerConfiguration.buildHmppModuleStructure(arguments: CommonCompilerArguments): HmppCliModuleStructure? { + val rawModules = arguments.modulesDescription + val rawDependencies = arguments.dependsOnDependencies + + val messageCollector = getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) + + fun reportError(message: String) { + messageCollector.report(CompilerMessageSeverity.ERROR, message) + } + + fun reportWarning(message: String) { + messageCollector.report(CompilerMessageSeverity.WARNING, message) + } + + if (rawModules == null) { + if (rawDependencies != null) { + reportError("-XdependsOn flag can not be used without -Xmodule") + } + return null + } + + if (!languageVersionSettings.languageVersion.usesK2) { + reportWarning("-Xmodule flag is not supported for language version < 2.0") + return null + } + + var modules = rawModules.mapNotNull { arg -> + val split = arg.split(";") + val name = split.first() + when (split.size) { + 1 -> reportWarning("Incorrect syntax for -Xmodule argument. Module $name has no sources") + 2 -> {} // OK + else -> { + reportError("Incorrect syntax for -Xmodule argument. `;` expected but got `$arg`") + return@mapNotNull null + } + } + val sources = split.getOrNull(1)?.split(",")?.toSet().orEmpty() + HmppCliModule(name, sources) + } + + var wasError = false + // check sources mapping + for (i in modules.indices) { + val m1 = modules[i] + for (j in (i + 1) until modules.size) { + val m2 = modules[j] + val commonFiles = m1.sources.intersect(m2.sources) + if (commonFiles.isNotEmpty()) { + val message = buildString { + if (commonFiles.size == 1) { + append("File '${commonFiles.single()}'") + } else { + append("Files ") + append(commonFiles.joinToString(", ") { "'$it'" }) + } + append(" can be a part of only one module, but is listed as a source for both `${m1.name}` and `${m2.name}`, please check you -Xmodule options.") + } + reportError(message) + wasError = true + } + } + } + + for (source in arguments.freeArgs) { + if (source.endsWith(JavaFileType.DOT_DEFAULT_EXTENSION)) continue + if (modules.none { source in it.sources }) { + reportError("Source '$source' does not belong to any module") + wasError = true + } + } + + if (wasError) { + return null + } + + if (modules.size == 1) { + if (rawDependencies?.isNotEmpty() == true) { + reportError("-XdependsOn flag is specified but there is only one module declared") + } + return HmppCliModuleStructure(modules, emptyMap()) + } + + val duplicatedModules = modules.filter { module -> modules.count { it.name == module.name } > 1 } + + if (duplicatedModules.isNotEmpty()) { + reportError("There are multiple modules with same name(s): ${duplicatedModules.distinct().joinToString(", ") { it.name }}") + return null + } + + val moduleByName = modules.associateBy { it.name } + + val dependenciesMap = rawDependencies.orEmpty().mapNotNull { + val split = it.split(":") + if (split.size != 2) { + reportError("Incorrect syntax for -XdependsOn argument. Expected : but got `$it`") + return@mapNotNull null + } + val moduleName1 = split[0] + val moduleName2 = split[1] + + fun findModule(name: String): HmppCliModule? { + return moduleByName[name].also { module -> + if (module == null) { + reportError("Module `$name` not found in -Xmodule arguments") + } + } + } + + val module1 = findModule(moduleName1) + val module2 = findModule(moduleName2) + if (module1 == null || module2 == null) return@mapNotNull null + module1 to module2 + }.groupBy( + keySelector = { it.first }, + valueTransform = { it.second } + ) + + modules = DFS.topologicalOrder(modules) { dependenciesMap[it].orEmpty() }.asReversed() + + modules.forEachIndexed { i, module -> + val dependencies = dependenciesMap[module].orEmpty() + val previousModules = modules.subList(0, i) + if (dependencies.any { it !in previousModules }) { + reportError("There is a cycle in dependencies of module `${module.name}`") + } + } + + return HmppCliModuleStructure(modules, dependenciesMap) +} diff --git a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index 3da2ba7c670..bcac3b0fac1 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -56,6 +56,9 @@ object CommonConfigurationKeys { @JvmField val USE_LIGHT_TREE = CompilerConfigurationKey.create("light tree") + @JvmField + val HMPP_MODULE_STRUCTURE = CompilerConfigurationKey.create("HMPP module structure") + @JvmField val EXPECT_ACTUAL_LINKER = CompilerConfigurationKey.create("Experimental expect/actual linker") diff --git a/compiler/config/src/org/jetbrains/kotlin/config/HmppCliModule.kt b/compiler/config/src/org/jetbrains/kotlin/config/HmppCliModule.kt new file mode 100644 index 00000000000..cf2f92f8cc9 --- /dev/null +++ b/compiler/config/src/org/jetbrains/kotlin/config/HmppCliModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.config + +class HmppCliModule(val name: String, val sources: Set) { + override fun toString(): String { + return "Module $name" + } +} + +/** + * All [modules] are sorted in reversed topological order + * (module without dependencies will be the first) + */ +class HmppCliModuleStructure( + val modules: List, + val dependenciesMap: Map> +) diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 98373e1cc8e..a9e2ea24b55 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -63,6 +63,8 @@ where advanced options include: -Xcommon-sources= Sources of the common module that need to be compiled together with this module in the multi-platform mode. Should be a subset of sources passed as free arguments -Xcontext-receivers Enable experimental context receivers + -XdependsOn=: + Declares that depends on with dependsOn relation -Xdisable-default-scripting-plugin Do not enable scripting plugin by default -Xdisable-phases Disable backend phases @@ -89,6 +91,8 @@ where advanced options include: -Xlegacy-smart-cast-after-try Allow var smart casts despite assignment in try block -Xlist-phases List backend phases -Xmetadata-version Change metadata version of the generated binary files + -Xmodule=; + Describes module with specific sources. Usage of this arguments requires to specify module for each source file from free args -Xmulti-platform Enable experimental language support for multi-platform projects -Xnew-inference Enable new experimental generic type inference algorithm -Xno-check-actual Do not check presence of 'actual' modifier in multi-platform projects diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index f4f0f6d47db..ce62ef2250b 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -169,6 +169,8 @@ where advanced options include: -Xcommon-sources= Sources of the common module that need to be compiled together with this module in the multi-platform mode. Should be a subset of sources passed as free arguments -Xcontext-receivers Enable experimental context receivers + -XdependsOn=: + Declares that depends on with dependsOn relation -Xdisable-default-scripting-plugin Do not enable scripting plugin by default -Xdisable-phases Disable backend phases @@ -195,6 +197,8 @@ where advanced options include: -Xlegacy-smart-cast-after-try Allow var smart casts despite assignment in try block -Xlist-phases List backend phases -Xmetadata-version Change metadata version of the generated binary files + -Xmodule=; + Describes module with specific sources. Usage of this arguments requires to specify module for each source file from free args -Xmulti-platform Enable experimental language support for multi-platform projects -Xnew-inference Enable new experimental generic type inference algorithm -Xno-check-actual Do not check presence of 'actual' modifier in multi-platform projects diff --git a/compiler/testData/cli/jvm/hmpp/cycleInDependencies.args b/compiler/testData/cli/jvm/hmpp/cycleInDependencies.args new file mode 100644 index 00000000000..35b7e0d462a --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/cycleInDependencies.args @@ -0,0 +1,14 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +$TESTDATA_DIR$/src/c.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/src/b.kt +-Xmodule=c;$TESTDATA_DIR$/src/c.kt +-XdependsOn=b\:a +-XdependsOn=c\:b +-XdependsOn=a\:c diff --git a/compiler/testData/cli/jvm/hmpp/cycleInDependencies.out b/compiler/testData/cli/jvm/hmpp/cycleInDependencies.out new file mode 100644 index 00000000000..a603138dba8 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/cycleInDependencies.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: there is a cycle in dependencies of module `b` +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.args b/compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.args new file mode 100644 index 00000000000..1db4f0760ae --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.args @@ -0,0 +1,8 @@ +$TESTDATA_DIR$/src/a.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-XdependsOn=b\:a diff --git a/compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.out b/compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.out new file mode 100644 index 00000000000..ad55c04fb66 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: -XdependsOn flag is specified but there is only one module declared +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.args b/compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.args new file mode 100644 index 00000000000..351e97737f7 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.args @@ -0,0 +1,7 @@ +$TESTDATA_DIR$/src/a.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-XdependsOn=a\:b diff --git a/compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.out b/compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.out new file mode 100644 index 00000000000..642a8c0abd8 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: -XdependsOn flag can not be used without -Xmodule +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/duplicatedModules.args b/compiler/testData/cli/jvm/hmpp/duplicatedModules.args new file mode 100644 index 00000000000..b8a69ec9e11 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/duplicatedModules.args @@ -0,0 +1,10 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/src/b.kt +-Xmodule=a;$TESTDATA_DIR$/src/c.kt diff --git a/compiler/testData/cli/jvm/hmpp/duplicatedModules.out b/compiler/testData/cli/jvm/hmpp/duplicatedModules.out new file mode 100644 index 00000000000..11e3cf4a573 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/duplicatedModules.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: there are multiple modules with same name(s): a, a +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/lowLanguageVersion.args b/compiler/testData/cli/jvm/hmpp/lowLanguageVersion.args new file mode 100644 index 00000000000..8b2c3120fc8 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/lowLanguageVersion.args @@ -0,0 +1,11 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +$TESTDATA_DIR$/src/c.kt +-d +$TEMP_DIR$ +-language-version +1.9 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/src/b.kt,$TESTDATA_DIR$/src/c.kt +-Xcommon-sources=$TESTDATA_DIR$/src/a.kt,$TESTDATA_DIR$/src/b.kt diff --git a/compiler/testData/cli/jvm/hmpp/lowLanguageVersion.out b/compiler/testData/cli/jvm/hmpp/lowLanguageVersion.out new file mode 100644 index 00000000000..44bbb9e0c72 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/lowLanguageVersion.out @@ -0,0 +1,11 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: -Xmodule flag is not supported for language version < 2.0 +OK diff --git a/compiler/testData/cli/jvm/hmpp/missingModule.args b/compiler/testData/cli/jvm/hmpp/missingModule.args new file mode 100644 index 00000000000..d8134152595 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/missingModule.args @@ -0,0 +1,10 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/src/b.kt +-XdependsOn=c\:a diff --git a/compiler/testData/cli/jvm/hmpp/missingModule.out b/compiler/testData/cli/jvm/hmpp/missingModule.out new file mode 100644 index 00000000000..ca747003f6f --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/missingModule.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: module `c` not found in -Xmodule arguments +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.args b/compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.args new file mode 100644 index 00000000000..a203d933aa0 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.args @@ -0,0 +1,8 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;a.kt;b.kt diff --git a/compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.out b/compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.out new file mode 100644 index 00000000000..c928c8e893a --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.out @@ -0,0 +1,14 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: incorrect syntax for -Xmodule argument. `;` expected but got `a;a.kt;b.kt` +error: source '$TESTDATA_DIR$/src/a.kt' does not belong to any module +error: source '$TESTDATA_DIR$/src/b.kt' does not belong to any module +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/moduleWithoutSources.args b/compiler/testData/cli/jvm/hmpp/moduleWithoutSources.args new file mode 100644 index 00000000000..a0d02b5db0f --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/moduleWithoutSources.args @@ -0,0 +1,8 @@ +$TESTDATA_DIR$/src/a.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a +-Xmodule=b; diff --git a/compiler/testData/cli/jvm/hmpp/moduleWithoutSources.out b/compiler/testData/cli/jvm/hmpp/moduleWithoutSources.out new file mode 100644 index 00000000000..f902bfda9fd --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/moduleWithoutSources.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: source '$TESTDATA_DIR$/src/a.kt' does not belong to any module +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.args b/compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.args new file mode 100644 index 00000000000..fbbf735173b --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.args @@ -0,0 +1,9 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt +-Xmodule=b;$TESTDATA_DIR$/src/a.kt diff --git a/compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.out b/compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.out new file mode 100644 index 00000000000..86feec929de --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.out @@ -0,0 +1,13 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: file '$TESTDATA_DIR$/src/a.kt' can be a part of only one module, but is listed as a source for both `a` and `b`, please check you -Xmodule options. +error: source '$TESTDATA_DIR$/src/b.kt' does not belong to any module +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.args b/compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.args new file mode 100644 index 00000000000..f2c1a302fa3 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.args @@ -0,0 +1,8 @@ +$TESTDATA_DIR$/src/a.kt +$TESTDATA_DIR$/src/b.kt +-d +$TEMP_DIR$ +-language-version +2.0 +-XXLanguage\:+MultiPlatformProjects +-Xmodule=a;$TESTDATA_DIR$/src/a.kt diff --git a/compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.out b/compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.out new file mode 100644 index 00000000000..60d704c7b6d --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.out @@ -0,0 +1,12 @@ +warning: ATTENTION! +This build uses unsafe internal compiler arguments: + +-XXLanguage:+MultiPlatformProjects + +This mode is not recommended for production use, +as no stability/compatibility guarantees are given on +compiler or generated code. Use it at your own risk! + +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +error: source '$TESTDATA_DIR$/src/b.kt' does not belong to any module +COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/hmpp/src/a.kt b/compiler/testData/cli/jvm/hmpp/src/a.kt new file mode 100644 index 00000000000..2430da2c5eb --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/src/a.kt @@ -0,0 +1,7 @@ +expect class A { + fun foo() +} + +expect class B { + fun bar() +} diff --git a/compiler/testData/cli/jvm/hmpp/src/b.kt b/compiler/testData/cli/jvm/hmpp/src/b.kt new file mode 100644 index 00000000000..97eb22cbdf7 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/src/b.kt @@ -0,0 +1,13 @@ +actual class A { + actual fun foo() {} + fun actFoo() {} +} + +fun acceptB(b: B) { + b.bar() +} + +fun acceptA(a: A) { + a.foo() + a.actFoo() +} diff --git a/compiler/testData/cli/jvm/hmpp/src/c.kt b/compiler/testData/cli/jvm/hmpp/src/c.kt new file mode 100644 index 00000000000..bf7cd33d0d0 --- /dev/null +++ b/compiler/testData/cli/jvm/hmpp/src/c.kt @@ -0,0 +1,15 @@ +actual class B { + actual fun bar() {} + fun actBar() {} +} + +fun actualAcceptB(b: B) { + b.bar() + b.actBar() +} + +fun test() { + acceptA(A()) + acceptB(B()) + actualAcceptB(B()) +} diff --git a/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit3CompilerTests.kt b/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit3CompilerTests.kt index 714f4807bca..55c2c94c152 100644 --- a/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit3CompilerTests.kt +++ b/compiler/tests-for-compiler-generator/tests/org/jetbrains/kotlin/test/generators/GenerateJUnit3CompilerTests.kt @@ -250,6 +250,7 @@ fun generateJUnit3CompilerTests(args: Array) { testClass { model("cli/jvm/readingConfigFromEnvironment", extension = "args", testMethod = "doJvmTest", recursive = false) model("cli/jvm/plugins", extension = "args", testMethod = "doJvmTest", recursive = false) + model("cli/jvm/hmpp", extension = "args", testMethod = "doJvmTest", recursive = false) model("cli/jvm", extension = "args", testMethod = "doJvmTest", recursive = false) model("cli/js", extension = "args", testMethod = "doJsTest", recursive = false) model("cli/js-dce", extension = "args", testMethod = "doJsDceTest", recursive = false) diff --git a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java index 230aea26077..61b95099809 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -105,6 +105,69 @@ public class CliTestGenerated extends AbstractCliTest { } } + @TestMetadata("compiler/testData/cli/jvm/hmpp") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Hmpp extends AbstractCliTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doJvmTest, this, testDataFilePath); + } + + public void testAllFilesPresentInHmpp() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/cli/jvm/hmpp"), Pattern.compile("^(.+)\\.args$"), null, false); + } + + @TestMetadata("cycleInDependencies.args") + public void testCycleInDependencies() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/cycleInDependencies.args"); + } + + @TestMetadata("dependsOnSingleModule.args") + public void testDependsOnSingleModule() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/dependsOnSingleModule.args"); + } + + @TestMetadata("dependsOnWithoutModules.args") + public void testDependsOnWithoutModules() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/dependsOnWithoutModules.args"); + } + + @TestMetadata("duplicatedModules.args") + public void testDuplicatedModules() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/duplicatedModules.args"); + } + + @TestMetadata("lowLanguageVersion.args") + public void testLowLanguageVersion() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/lowLanguageVersion.args"); + } + + @TestMetadata("missingModule.args") + public void testMissingModule() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/missingModule.args"); + } + + @TestMetadata("moduleIncorrectSyntax.args") + public void testModuleIncorrectSyntax() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/moduleIncorrectSyntax.args"); + } + + @TestMetadata("moduleWithoutSources.args") + public void testModuleWithoutSources() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/moduleWithoutSources.args"); + } + + @TestMetadata("sameSourceInDifferentModules.args") + public void testSameSourceInDifferentModules() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/sameSourceInDifferentModules.args"); + } + + @TestMetadata("sourceNotInAnyModule.args") + public void testSourceNotInAnyModule() throws Exception { + runTest("compiler/testData/cli/jvm/hmpp/sourceNotInAnyModule.args"); + } + } + @TestMetadata("compiler/testData/cli/jvm") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)