JPS tests: restore MPP tests runner, support new MPP model
This commit is contained in:
+9
-3
@@ -67,12 +67,18 @@ fun getModificationsToPerform(
|
|||||||
val underscore = fileName.indexOf("_")
|
val underscore = fileName.indexOf("_")
|
||||||
|
|
||||||
if (underscore != -1) {
|
if (underscore != -1) {
|
||||||
val module = fileName.substring(0, underscore)
|
var moduleName = fileName.substring(0, underscore)
|
||||||
|
var moduleFileName = fileName.substring(underscore + 1)
|
||||||
|
if (moduleName.all { it.isDigit() }) {
|
||||||
|
val (moduleName1, moduleFileName1) = moduleFileName.split("_")
|
||||||
|
moduleName = moduleName1
|
||||||
|
moduleFileName = moduleFileName1
|
||||||
|
}
|
||||||
|
|
||||||
assert(moduleNames != null) { "File name has module prefix, but multi-module environment is absent" }
|
assert(moduleNames != null) { "File name has module prefix, but multi-module environment is absent" }
|
||||||
assert(module in moduleNames!!) { "Module not found for file with prefix: $fileName" }
|
assert(moduleName in moduleNames!!) { "Module not found for file with prefix: $fileName" }
|
||||||
|
|
||||||
return Pair(module, fileName.substring(underscore + 1))
|
return Pair(moduleName, moduleFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(moduleNames == null) { "Test is multi-module, but file has no module prefix: $fileName" }
|
assert(moduleNames == null) { "Test is multi-module, but file has no module prefix: $fileName" }
|
||||||
|
|||||||
+87
-38
@@ -43,12 +43,13 @@ import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
|||||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||||
import org.jetbrains.jps.model.library.sdk.JpsSdk
|
import org.jetbrains.jps.model.library.sdk.JpsSdk
|
||||||
import org.jetbrains.jps.util.JpsPathUtil
|
import org.jetbrains.jps.util.JpsPathUtil
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||||
import org.jetbrains.kotlin.incremental.storage.version.CacheAttributesDiff
|
import org.jetbrains.kotlin.incremental.storage.version.CacheAttributesDiff
|
||||||
import org.jetbrains.kotlin.incremental.storage.version.CacheVersionManager
|
import org.jetbrains.kotlin.incremental.storage.version.CacheVersionManager
|
||||||
import org.jetbrains.kotlin.incremental.testingUtils.*
|
import org.jetbrains.kotlin.incremental.testingUtils.*
|
||||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.DependenciesTxtBuilder
|
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxtBuilder
|
||||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt
|
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt
|
||||||
import org.jetbrains.kotlin.jps.incremental.CompositeLookupsCacheAttributesManager
|
import org.jetbrains.kotlin.jps.incremental.CompositeLookupsCacheAttributesManager
|
||||||
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
||||||
@@ -145,7 +146,10 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
protected open val mockConstantSearch: Callbacks.ConstantAffectionResolver?
|
protected open val mockConstantSearch: Callbacks.ConstantAffectionResolver?
|
||||||
get() = MockJavaConstantSearch(workDir)
|
get() = MockJavaConstantSearch(workDir)
|
||||||
|
|
||||||
private fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules()): MakeResult {
|
private fun build(
|
||||||
|
name: String?,
|
||||||
|
scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules()
|
||||||
|
): MakeResult {
|
||||||
val workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath)
|
val workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath)
|
||||||
|
|
||||||
val logger = MyLogger(workDirPath)
|
val logger = MyLogger(workDirPath)
|
||||||
@@ -182,9 +186,19 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
.map { it.messageText }
|
.map { it.messageText }
|
||||||
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
|
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
|
||||||
.joinToString("\n")
|
.joinToString("\n")
|
||||||
return MakeResult(logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n", true, null)
|
return MakeResult(
|
||||||
|
log = logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n",
|
||||||
|
makeFailed = true,
|
||||||
|
mappingsDump = null,
|
||||||
|
name = name
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return MakeResult(logger.log, false, createMappingsDump(projectDescriptor))
|
return MakeResult(
|
||||||
|
log = logger.log,
|
||||||
|
makeFailed = false,
|
||||||
|
mappingsDump = createMappingsDump(projectDescriptor),
|
||||||
|
name = name
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
projectDescriptor.dataManager.flush(false)
|
projectDescriptor.dataManager.flush(false)
|
||||||
@@ -193,7 +207,7 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initialMake(): MakeResult {
|
private fun initialMake(): MakeResult {
|
||||||
val makeResult = build()
|
val makeResult = build(null)
|
||||||
|
|
||||||
val initBuildLogFile = File(testDataDir, "init-build.log")
|
val initBuildLogFile = File(testDataDir, "init-build.log")
|
||||||
if (initBuildLogFile.exists()) {
|
if (initBuildLogFile.exists()) {
|
||||||
@@ -205,12 +219,12 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
return makeResult
|
return makeResult
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun make(): MakeResult {
|
private fun make(name: String?): MakeResult {
|
||||||
return build()
|
return build(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun rebuild(): MakeResult {
|
private fun rebuild(): MakeResult {
|
||||||
return build(CompileScopeTestBuilder.rebuild().allModules())
|
return build(null, CompileScopeTestBuilder.rebuild().allModules())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
||||||
@@ -250,18 +264,23 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
rebuildAndCheckOutput(makeOverallResult)
|
rebuildAndCheckOutput(makeOverallResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readModulesConfig(): ModulesTxt? {
|
open val modulesTxtFile
|
||||||
val dependenciesTxtFile = File(testDataDir, "dependencies.txt")
|
get() = File(testDataDir, "dependencies.txt")
|
||||||
if (!dependenciesTxtFile.exists()) return null
|
|
||||||
|
|
||||||
return DependenciesTxtBuilder().readFile(dependenciesTxtFile)
|
private fun readModulesTxt(): ModulesTxt? {
|
||||||
|
if (!modulesTxtFile.exists()) return null
|
||||||
|
return ModulesTxtBuilder().readFile(modulesTxtFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
|
protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
|
||||||
buildString {
|
buildString {
|
||||||
incrementalMakeResults.forEachIndexed { i, makeResult ->
|
incrementalMakeResults.forEachIndexed { i, makeResult ->
|
||||||
if (i > 0) append("\n")
|
if (i > 0) append("\n")
|
||||||
append("================ Step #${i + 1} =================\n\n")
|
if (makeResult.name != null) {
|
||||||
|
append("================ Step #${i + 1} ${makeResult.name} =================\n\n")
|
||||||
|
} else {
|
||||||
|
append("================ Step #${i + 1} =================\n\n")
|
||||||
|
}
|
||||||
append(makeResult.log)
|
append(makeResult.log)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,13 +382,29 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
return byteArrayOutputStream.toString()
|
return byteArrayOutputStream.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected data class MakeResult(val log: String, val makeFailed: Boolean, val mappingsDump: String?)
|
protected data class MakeResult(
|
||||||
|
val log: String,
|
||||||
|
val makeFailed: Boolean,
|
||||||
|
val mappingsDump: String?,
|
||||||
|
val name: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
open val testDataSrc: File
|
||||||
|
get() = testDataDir
|
||||||
|
|
||||||
private fun performModificationsAndMake(moduleNames: Collection<String>?): List<MakeResult> {
|
private fun performModificationsAndMake(moduleNames: Collection<String>?): List<MakeResult> {
|
||||||
val results = arrayListOf<MakeResult>()
|
val results = arrayListOf<MakeResult>()
|
||||||
val modifications = getModificationsToPerform(testDataDir, moduleNames, allowNoFilesWithSuffixInTestData, TouchPolicy.TIMESTAMP)
|
val modifications = getModificationsToPerform(
|
||||||
|
testDataSrc,
|
||||||
|
moduleNames,
|
||||||
|
allowNoFilesWithSuffixInTestData,
|
||||||
|
TouchPolicy.TIMESTAMP
|
||||||
|
)
|
||||||
|
|
||||||
for (step in modifications) {
|
val stepsTxt = File(testDataSrc, "steps.txt")
|
||||||
|
val modificationNames = if (stepsTxt.exists()) stepsTxt.readLines() else null
|
||||||
|
|
||||||
|
modifications.forEachIndexed { index, step ->
|
||||||
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
|
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
|
||||||
performAdditionalModifications(step)
|
performAdditionalModifications(step)
|
||||||
if (moduleNames == null) {
|
if (moduleNames == null) {
|
||||||
@@ -378,7 +413,9 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) }
|
moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
results.add(make())
|
val name = modificationNames?.getOrNull(index)
|
||||||
|
val makeResult = make(name)
|
||||||
|
results.add(makeResult)
|
||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
@@ -386,21 +423,25 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
protected open fun performAdditionalModifications(modifications: List<Modification>) {
|
protected open fun performAdditionalModifications(modifications: List<Modification>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun generateModuleSources(modulesTxt: ModulesTxt) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// null means one module
|
// null means one module
|
||||||
private fun configureModules(): ModulesTxt? {
|
private fun configureModules(): ModulesTxt? {
|
||||||
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl =
|
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl =
|
||||||
JpsPathUtil.pathToUrl(getAbsolutePath("out"))
|
JpsPathUtil.pathToUrl(getAbsolutePath("out"))
|
||||||
|
|
||||||
val jdk = addJdk("my jdk")
|
val jdk = addJdk("my jdk")
|
||||||
val moduleDependencies = readModulesConfig()
|
val modulesTxt = readModulesTxt()
|
||||||
mapWorkingToOriginalFile = hashMapOf()
|
mapWorkingToOriginalFile = hashMapOf()
|
||||||
|
|
||||||
if (moduleDependencies == null) configureSingleModuleProject(jdk)
|
if (modulesTxt == null) configureSingleModuleProject(jdk)
|
||||||
else configureMultiModuleProject(moduleDependencies, jdk)
|
else configureMultiModuleProject(modulesTxt, jdk)
|
||||||
|
|
||||||
addStdlib()
|
addStdlib()
|
||||||
|
|
||||||
return moduleDependencies
|
return modulesTxt
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun configureSingleModuleProject(jdk: JpsSdk<JpsDummyElement>?) {
|
private fun configureSingleModuleProject(jdk: JpsSdk<JpsDummyElement>?) {
|
||||||
@@ -413,11 +454,14 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
preProcessSources(sourceDestinationDir)
|
preProcessSources(sourceDestinationDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open val ModulesTxt.Module.sourceFilePrefix: String
|
||||||
|
get() = "${name}_"
|
||||||
|
|
||||||
private fun configureMultiModuleProject(
|
private fun configureMultiModuleProject(
|
||||||
moduleDependencies: ModulesTxt,
|
modulesTxt: ModulesTxt,
|
||||||
jdk: JpsSdk<JpsDummyElement>?
|
jdk: JpsSdk<JpsDummyElement>?
|
||||||
) {
|
) {
|
||||||
moduleDependencies.modules.forEach { module ->
|
modulesTxt.modules.forEach { module ->
|
||||||
module.jpsModule = addModule(
|
module.jpsModule = addModule(
|
||||||
module.name,
|
module.name,
|
||||||
arrayOf(getAbsolutePath("${module.name}/src")),
|
arrayOf(getAbsolutePath("${module.name}/src")),
|
||||||
@@ -428,27 +472,37 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
val kotlinFacetSettings = module.kotlinFacetSettings
|
val kotlinFacetSettings = module.kotlinFacetSettings
|
||||||
if (kotlinFacetSettings != null) {
|
if (kotlinFacetSettings != null) {
|
||||||
|
val compilerArguments = kotlinFacetSettings.compilerArguments
|
||||||
|
if (compilerArguments is K2MetadataCompilerArguments) {
|
||||||
|
val out = getAbsolutePath("${module.name}/out")
|
||||||
|
File(out).mkdirs()
|
||||||
|
compilerArguments.destination = out
|
||||||
|
}
|
||||||
|
|
||||||
module.jpsModule.container.setChild(
|
module.jpsModule.container.setChild(
|
||||||
JpsKotlinFacetModuleExtension.KIND,
|
JpsKotlinFacetModuleExtension.KIND,
|
||||||
JpsKotlinFacetModuleExtension(kotlinFacetSettings!!)
|
JpsKotlinFacetModuleExtension(kotlinFacetSettings)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sourceDirName = "${module.name}/src"
|
|
||||||
val filePrefix = "${module.name}_"
|
|
||||||
val sourceDestinationDir = File(workDir, sourceDirName)
|
|
||||||
val sourcesMapping = copyTestSources(testDataDir, sourceDestinationDir, filePrefix)
|
|
||||||
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
|
||||||
|
|
||||||
preProcessSources(sourceDestinationDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleDependencies.dependencies.forEach {
|
modulesTxt.dependencies.forEach {
|
||||||
JpsModuleRootModificationUtil.addDependency(
|
JpsModuleRootModificationUtil.addDependency(
|
||||||
it.from.jpsModule, it.to.jpsModule,
|
it.from.jpsModule, it.to.jpsModule,
|
||||||
it.scope, it.exported
|
it.scope, it.exported
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// configure module contents
|
||||||
|
generateModuleSources(modulesTxt)
|
||||||
|
modulesTxt.modules.forEach { module ->
|
||||||
|
val sourceDirName = "${module.name}/src"
|
||||||
|
val sourceDestinationDir = File(workDir, sourceDirName)
|
||||||
|
val sourcesMapping = copyTestSources(testDataDir, sourceDestinationDir, module.sourceFilePrefix)
|
||||||
|
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
||||||
|
|
||||||
|
preProcessSources(sourceDestinationDir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun addStdlib() {
|
protected open fun addStdlib() {
|
||||||
@@ -544,9 +598,4 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
||||||
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
|
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
|
||||||
|
|
||||||
private class DependencyDescriptor(val name: String, val exported: Boolean)
|
|
||||||
|
|
||||||
private fun parseDependency(dependency: String): DependencyDescriptor =
|
|
||||||
DependencyDescriptor(dependency.removeSuffix(EXPORTED_SUFFIX), dependency.endsWith(EXPORTED_SUFFIX))
|
|
||||||
|
|
||||||
private val EXPORTED_SUFFIX = "[exported]"
|
private val EXPORTED_SUFFIX = "[exported]"
|
||||||
|
|||||||
+26
-2
@@ -5,8 +5,32 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.jps.build
|
package org.jetbrains.kotlin.jps.build
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt
|
||||||
|
import org.jetbrains.kotlin.jps.build.dependeciestxt.MppJpsIncTestsGenerator
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractMultiplatformJpsTest : AbstractIncrementalJpsTest() {
|
abstract class AbstractMultiplatformJpsTest : AbstractIncrementalJpsTest() {
|
||||||
override fun doTest(testDataPath: String) {
|
override val modulesTxtFile: File
|
||||||
// temporary ignore jps-plugin/testData/incremental/multiplatform/multiModule tests
|
get() = File(testDataDir.parent, "dependencies.txt").also {
|
||||||
|
check(it.exists()) {
|
||||||
|
"`dependencies.txt` should be in parent dir. " +
|
||||||
|
"See jps-plugin/testData/incremental/multiplatform/multiModule/README.md for details"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val testDataSrc: File
|
||||||
|
get() = File(workDir, "generatedTestDataSources")
|
||||||
|
|
||||||
|
override fun generateModuleSources(modulesTxt: ModulesTxt) {
|
||||||
|
testDataSrc.mkdirs()
|
||||||
|
|
||||||
|
val testCaseName = testDataDir.name
|
||||||
|
|
||||||
|
val generator = MppJpsIncTestsGenerator(modulesTxt) { testDataSrc }
|
||||||
|
val testCase = generator.testCases.find { it.name == testCaseName } ?: error("Unsupported test case name: $testCaseName")
|
||||||
|
testCase.generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val ModulesTxt.Module.sourceFilePrefix: String
|
||||||
|
get() = indexedName
|
||||||
}
|
}
|
||||||
Generated
+85
@@ -181,6 +181,91 @@ public class MultiplatformJpsTestGenerated extends AbstractMultiplatformJpsTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class SimpleNewMpp extends AbstractMultiplatformJpsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInSimpleNewMpp() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("editingCKotlin")
|
||||||
|
public void testEditingCKotlin() throws Exception {
|
||||||
|
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingCKotlin/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("editingPJsKotlin")
|
||||||
|
public void testEditingPJsKotlin() throws Exception {
|
||||||
|
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJsKotlin/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("editingPJvmJava")
|
||||||
|
public void testEditingPJvmJava() throws Exception {
|
||||||
|
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJvmJava/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("editingPJvmKotlin")
|
||||||
|
public void testEditingPJvmKotlin() throws Exception {
|
||||||
|
runTest("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJvmKotlin/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingCKotlin")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EditingCKotlin extends AbstractMultiplatformJpsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEditingCKotlin() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingCKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJsKotlin")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EditingPJsKotlin extends AbstractMultiplatformJpsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEditingPJsKotlin() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJsKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJvmJava")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EditingPJvmJava extends AbstractMultiplatformJpsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEditingPJvmJava() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJvmJava"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJvmKotlin")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class EditingPJvmKotlin extends AbstractMultiplatformJpsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInEditingPJvmKotlin() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform/multiModule/simpleNewMpp/editingPJvmKotlin"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate")
|
@TestMetadata("jps-plugin/testData/incremental/multiplatform/multiModule/ultimate")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+60
-27
@@ -12,6 +12,9 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
|||||||
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||||
import org.jetbrains.kotlin.config.CompilerSettings
|
import org.jetbrains.kotlin.config.CompilerSettings
|
||||||
import org.jetbrains.kotlin.config.KotlinFacetSettings
|
import org.jetbrains.kotlin.config.KotlinFacetSettings
|
||||||
|
import org.jetbrains.kotlin.config.KotlinModuleKind.COMPILATION_AND_SOURCE_SET_HOLDER
|
||||||
|
import org.jetbrains.kotlin.config.KotlinModuleKind.SOURCE_SET_HOLDER
|
||||||
|
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt.Dependency.Kind.*
|
||||||
import org.jetbrains.kotlin.platform.impl.isCommon
|
import org.jetbrains.kotlin.platform.impl.isCommon
|
||||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -20,7 +23,7 @@ import kotlin.reflect.full.findAnnotation
|
|||||||
import kotlin.reflect.full.memberProperties
|
import kotlin.reflect.full.memberProperties
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dependencies description file.
|
* Modules description file.
|
||||||
* See [README.md] for more details.
|
* See [README.md] for more details.
|
||||||
*/
|
*/
|
||||||
data class ModulesTxt(
|
data class ModulesTxt(
|
||||||
@@ -46,13 +49,18 @@ data class ModulesTxt(
|
|||||||
val usages = mutableListOf<Dependency>()
|
val usages = mutableListOf<Dependency>()
|
||||||
|
|
||||||
val isCommonModule
|
val isCommonModule
|
||||||
get() = kotlinFacetSettings?.platform.isCommon
|
get() =
|
||||||
|
kotlinFacetSettings?.platform.isCommon ||
|
||||||
|
kotlinFacetSettings?.kind == SOURCE_SET_HOLDER
|
||||||
|
|
||||||
val isJvmModule
|
val isJvmModule
|
||||||
get() = kotlinFacetSettings?.platform.isJvm
|
get() = kotlinFacetSettings?.platform.isJvm
|
||||||
|
|
||||||
val expectedBy
|
val expectedBy
|
||||||
get() = dependencies.filter { it.expectedBy }
|
get() = dependencies.filter {
|
||||||
|
it.kind == EXPECTED_BY ||
|
||||||
|
it.kind == INCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
@Flag
|
@Flag
|
||||||
var edit: Boolean = false
|
var edit: Boolean = false
|
||||||
@@ -79,20 +87,26 @@ data class ModulesTxt(
|
|||||||
val from: Module,
|
val from: Module,
|
||||||
val to: Module,
|
val to: Module,
|
||||||
val scope: JpsJavaDependencyScope,
|
val scope: JpsJavaDependencyScope,
|
||||||
val expectedBy: Boolean,
|
val kind: Kind,
|
||||||
val exported: Boolean
|
val exported: Boolean
|
||||||
) {
|
) {
|
||||||
val effectivelyExported
|
val effectivelyExported
|
||||||
get() = expectedBy || exported
|
get() = kind == EXPECTED_BY || exported
|
||||||
|
|
||||||
init {
|
init {
|
||||||
from.dependencies.add(this)
|
from.dependencies.add(this)
|
||||||
to.usages.add(this)
|
to.usages.add(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Kind {
|
||||||
|
DEPENDENCY,
|
||||||
|
EXPECTED_BY,
|
||||||
|
INCLUDE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DependenciesTxtBuilder {
|
class ModulesTxtBuilder {
|
||||||
val modules = mutableMapOf<String, ModuleRef>()
|
val modules = mutableMapOf<String, ModuleRef>()
|
||||||
private val dependencies = mutableListOf<DependencyBuilder>()
|
private val dependencies = mutableListOf<DependencyBuilder>()
|
||||||
|
|
||||||
@@ -112,7 +126,13 @@ class DependenciesTxtBuilder {
|
|||||||
if (kotlinFacetSettings != null) {
|
if (kotlinFacetSettings != null) {
|
||||||
kotlinFacetSettings.implementedModuleNames =
|
kotlinFacetSettings.implementedModuleNames =
|
||||||
result.dependencies.asSequence()
|
result.dependencies.asSequence()
|
||||||
.filter { it.expectedBy }
|
.filter { it.kind == EXPECTED_BY }
|
||||||
|
.map { it.to.name }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
kotlinFacetSettings.sourceSetNames =
|
||||||
|
result.dependencies.asSequence()
|
||||||
|
.filter { it.kind == INCLUDE }
|
||||||
.map { it.to.name }
|
.map { it.to.name }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
@@ -127,12 +147,20 @@ class DependenciesTxtBuilder {
|
|||||||
val from: ModuleRef,
|
val from: ModuleRef,
|
||||||
val to: ModuleRef,
|
val to: ModuleRef,
|
||||||
val scope: JpsJavaDependencyScope,
|
val scope: JpsJavaDependencyScope,
|
||||||
val expectedBy: Boolean,
|
val kind: ModulesTxt.Dependency.Kind,
|
||||||
val exported: Boolean
|
val exported: Boolean
|
||||||
) {
|
) {
|
||||||
fun build(): ModulesTxt.Dependency {
|
fun build(): ModulesTxt.Dependency {
|
||||||
if (expectedBy) check(to.actual.isCommonModule) { "$this: ${to.actual} is not common module" }
|
when (kind) {
|
||||||
return ModulesTxt.Dependency(from.actual, to.actual, scope, expectedBy, exported)
|
DEPENDENCY -> Unit
|
||||||
|
EXPECTED_BY -> check(to.actual.isCommonModule) {
|
||||||
|
"$this: ${to.actual} is not common module"
|
||||||
|
}
|
||||||
|
INCLUDE -> check(to.actual.kotlinFacetSettings?.kind == SOURCE_SET_HOLDER) {
|
||||||
|
"$this: ${to.actual} is not source set holder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ModulesTxt.Dependency(from.actual, to.actual, scope, kind, exported)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,14 +169,11 @@ class DependenciesTxtBuilder {
|
|||||||
parseDeclaration(line)
|
parseDeclaration(line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// module.build() requires built dependencies
|
// dependencies need to be build first: module.build() requires it
|
||||||
val dependencies = dependencies.map { it.build() }
|
val dependencies = dependencies.map { it.build() }
|
||||||
return ModulesTxt(
|
val modules = modules.values.mapIndexed { index, moduleRef -> moduleRef.build(index) }
|
||||||
file,
|
|
||||||
fileTitle,
|
return ModulesTxt(file, fileTitle, modules, dependencies)
|
||||||
modules.values.mapIndexed { index, moduleRef -> moduleRef.build(index) },
|
|
||||||
dependencies
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseDeclaration(line: String) = doParseDeclaration(removeComments(line))
|
private fun parseDeclaration(line: String) = doParseDeclaration(removeComments(line))
|
||||||
@@ -200,11 +225,11 @@ class DependenciesTxtBuilder {
|
|||||||
val name = def.value.trim()
|
val name = def.value.trim()
|
||||||
|
|
||||||
val module = ModulesTxt.Module(name)
|
val module = ModulesTxt.Module(name)
|
||||||
val kotlinFacetSettings = KotlinFacetSettings()
|
val settings = KotlinFacetSettings()
|
||||||
module.kotlinFacetSettings = kotlinFacetSettings
|
module.kotlinFacetSettings = settings
|
||||||
|
|
||||||
kotlinFacetSettings.useProjectSettings = false
|
settings.useProjectSettings = false
|
||||||
kotlinFacetSettings.compilerSettings = CompilerSettings().also {
|
settings.compilerSettings = CompilerSettings().also {
|
||||||
it.additionalArguments = "-version -Xmulti-platform"
|
it.additionalArguments = "-version -Xmulti-platform"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,9 +240,11 @@ class DependenciesTxtBuilder {
|
|||||||
|
|
||||||
def.flags.forEach { flag ->
|
def.flags.forEach { flag ->
|
||||||
when (flag) {
|
when (flag) {
|
||||||
"common" -> kotlinFacetSettings.compilerArguments = K2MetadataCompilerArguments()
|
"sourceSetHolder" -> settings.kind = SOURCE_SET_HOLDER
|
||||||
"jvm" -> kotlinFacetSettings.compilerArguments = K2JVMCompilerArguments()
|
"compilationAndSourceSetHolder" -> settings.kind = COMPILATION_AND_SOURCE_SET_HOLDER
|
||||||
"js" -> kotlinFacetSettings.compilerArguments = K2JSCompilerArguments()
|
"common" -> settings.compilerArguments = K2MetadataCompilerArguments()
|
||||||
|
"jvm" -> settings.compilerArguments = K2JVMCompilerArguments()
|
||||||
|
"js" -> settings.compilerArguments = K2JSCompilerArguments()
|
||||||
else -> {
|
else -> {
|
||||||
val flagProperty = ModulesTxt.Module.flags[flag]
|
val flagProperty = ModulesTxt.Module.flags[flag]
|
||||||
if (flagProperty != null) flagProperty.set(module, true)
|
if (flagProperty != null) flagProperty.set(module, true)
|
||||||
@@ -243,13 +270,18 @@ class DependenciesTxtBuilder {
|
|||||||
} else {
|
} else {
|
||||||
var exported = false
|
var exported = false
|
||||||
var scope: JpsJavaDependencyScope? = null
|
var scope: JpsJavaDependencyScope? = null
|
||||||
var expectedBy = false
|
var kind: ModulesTxt.Dependency.Kind = DEPENDENCY
|
||||||
|
|
||||||
fun setScope(newScope: JpsJavaDependencyScope) {
|
fun setScope(newScope: JpsJavaDependencyScope) {
|
||||||
check(scope == null) { "`$this: $from -> $to` dependency is already flagged as $scope" }
|
check(scope == null) { "`$this: $from -> $to` dependency is already flagged as $scope" }
|
||||||
scope = newScope
|
scope = newScope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setKind(newKind: ModulesTxt.Dependency.Kind) {
|
||||||
|
check(kind == DEPENDENCY) { "`$this: $from -> $to` dependency is already flagged as $kind" }
|
||||||
|
kind = newKind
|
||||||
|
}
|
||||||
|
|
||||||
flags.forEach { flag ->
|
flags.forEach { flag ->
|
||||||
when (flag) {
|
when (flag) {
|
||||||
"exported" -> exported = true
|
"exported" -> exported = true
|
||||||
@@ -257,7 +289,8 @@ class DependenciesTxtBuilder {
|
|||||||
"test" -> setScope(JpsJavaDependencyScope.TEST)
|
"test" -> setScope(JpsJavaDependencyScope.TEST)
|
||||||
"runtime" -> setScope(JpsJavaDependencyScope.RUNTIME)
|
"runtime" -> setScope(JpsJavaDependencyScope.RUNTIME)
|
||||||
"provided" -> setScope(JpsJavaDependencyScope.PROVIDED)
|
"provided" -> setScope(JpsJavaDependencyScope.PROVIDED)
|
||||||
"expectedBy" -> expectedBy = true
|
"expectedBy" -> setKind(EXPECTED_BY)
|
||||||
|
"include" -> setKind(INCLUDE)
|
||||||
else -> error("Unknown dependency flag `$flag`")
|
else -> error("Unknown dependency flag `$flag`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,7 +299,7 @@ class DependenciesTxtBuilder {
|
|||||||
from = moduleRef(from),
|
from = moduleRef(from),
|
||||||
to = moduleRef(to),
|
to = moduleRef(to),
|
||||||
scope = scope ?: JpsJavaDependencyScope.COMPILE,
|
scope = scope ?: JpsJavaDependencyScope.COMPILE,
|
||||||
expectedBy = expectedBy,
|
kind = kind,
|
||||||
exported = exported
|
exported = exported
|
||||||
).also {
|
).also {
|
||||||
dependencies.add(it)
|
dependencies.add(it)
|
||||||
|
|||||||
+8
-2
@@ -15,7 +15,7 @@ fun actualizeMppJpsIncTestCaseDirs(rootDir: String, dir: String) {
|
|||||||
val dependenciesTxtFile = File(dirFile, "dependencies.txt")
|
val dependenciesTxtFile = File(dirFile, "dependencies.txt")
|
||||||
if (dependenciesTxtFile.exists()) {
|
if (dependenciesTxtFile.exists()) {
|
||||||
val fileTitle = "$dir/${dirFile.name}/dependencies.txt"
|
val fileTitle = "$dir/${dirFile.name}/dependencies.txt"
|
||||||
val dependenciesTxt = DependenciesTxtBuilder().readFile(dependenciesTxtFile, fileTitle)
|
val dependenciesTxt = ModulesTxtBuilder().readFile(dependenciesTxtFile, fileTitle)
|
||||||
|
|
||||||
MppJpsIncTestsGenerator(dependenciesTxt) { File(dirFile, it.name) }
|
MppJpsIncTestsGenerator(dependenciesTxt) { File(dirFile, it.name) }
|
||||||
.actualizeTestCasesDirs(dirFile)
|
.actualizeTestCasesDirs(dirFile)
|
||||||
@@ -178,7 +178,13 @@ class MppJpsIncTestsGenerator(val txt: ModulesTxt, val testCaseDirProvider: (Tes
|
|||||||
override fun generate() {
|
override fun generate() {
|
||||||
generateBaseContent()
|
generateBaseContent()
|
||||||
check(commonModule.isCommonModule)
|
check(commonModule.isCommonModule)
|
||||||
val implModules = commonModule.usages.filter { it.expectedBy }.map { it.from }
|
val implModules = commonModule.usages
|
||||||
|
.asSequence()
|
||||||
|
.filter {
|
||||||
|
it.kind == ModulesTxt.Dependency.Kind.EXPECTED_BY ||
|
||||||
|
it.kind == ModulesTxt.Dependency.Kind.INCLUDE
|
||||||
|
}
|
||||||
|
.map { it.from }
|
||||||
|
|
||||||
commonModule.contentsSettings = ModuleContentSettings(commonModule, serviceNameSuffix = "New")
|
commonModule.contentsSettings = ModuleContentSettings(commonModule, serviceNameSuffix = "New")
|
||||||
implModules.forEach { implModule ->
|
implModules.forEach { implModule ->
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ Referring to undefined module is allowed (`jvm` module will be created at this c
|
|||||||
This modules can be defined after reference. Several declarations for same module is not allowed.
|
This modules can be defined after reference. Several declarations for same module is not allowed.
|
||||||
|
|
||||||
Supported module flags:
|
Supported module flags:
|
||||||
- `common`
|
- `common` (old MPP)
|
||||||
|
- `sourceSetHolder`, `compilationAndSourceSetHolder` (new MPP)
|
||||||
- `jvm` (default)
|
- `jvm` (default)
|
||||||
- `js`
|
- `js`
|
||||||
- `edit`, `editJvm`, `editExcpetActual` - see jps-plugin/testData/incremental/multiplatform/multiModule/README.md
|
- `edit`, `editJvm`, `editExcpetActual` - see jps-plugin/testData/incremental/multiplatform/multiModule/README.md
|
||||||
@@ -32,5 +33,6 @@ Supported dependency flags:
|
|||||||
- `test`
|
- `test`
|
||||||
- `runtime`
|
- `runtime`
|
||||||
- `provided`
|
- `provided`
|
||||||
- `expectedBy`
|
- `expectedBy` (old MPP)
|
||||||
|
- `included` (new MPP)
|
||||||
- `exproted`
|
- `exproted`
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
c [sourceSetHolder, edit, editExpectActual]
|
||||||
|
|
||||||
|
pJvm [compilationAndSourceSetHolder, jvm, edit, editJvm]
|
||||||
|
pJvm -> c [include]
|
||||||
|
|
||||||
|
pJs [compilationAndSourceSetHolder, js, edit]
|
||||||
|
pJs -> c [include]
|
||||||
Vendored
Vendored
Vendored
Reference in New Issue
Block a user