From 5a2ed364fe6b147d29972add96b442196cb64c86 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Wed, 6 Jun 2018 16:33:09 +0300 Subject: [PATCH] jps: checkCachesVersions for js and common (BuildMetaInfo save/check) --- .../jetbrains/kotlin/build/BuildMetaInfo.kt | 75 +++++++++++++++ .../kotlin/build/CommonBuildMetaInfo.kt | 60 ++++++++++++ .../jetbrains/kotlin/build/JsBuildMetaInfo.kt | 59 ++++++++++++ .../kotlin/build/JvmBuildMetaInfo.kt | 95 +++++++++---------- ...ldMetaInfoTest.kt => BuildMetaInfoTest.kt} | 59 +++++++----- .../AbstractIncrementalLazyCachesTest.kt | 12 ++- .../build/dependeciestxt/DependenciesTxt.kt | 2 +- .../kotlin/jps/build/KotlinBuilder.kt | 35 ++----- .../jps/build/MessageCollectorAdapter.kt | 2 +- .../jps/incremental/JpsIncrementalCache.kt | 4 +- .../KotlinCommonModuleBuildTarget.kt | 12 ++- .../platforms/KotlinJsModuleBuildTarget.kt | 11 ++- .../platforms/KotlinJvmModuleBuildTarget.kt | 67 +++---------- .../jps/platforms/KotlinModuleBuildTarget.kt | 88 +++++++++++++++-- .../kotlin/jps/platforms/TargetPlatform.kt | 6 +- 15 files changed, 411 insertions(+), 176 deletions(-) create mode 100644 build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt create mode 100644 build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt create mode 100644 build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt rename build-common/test/org/jetbrains/kotlin/build/{JvmBuildMetaInfoTest.kt => BuildMetaInfoTest.kt} (58%) diff --git a/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt new file mode 100644 index 00000000000..9478ea5e7de --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.build + +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.config.isPreRelease +import kotlin.reflect.KClass + +interface BuildMetaInfo { + val isEAP: Boolean + val compilerBuildVersion: String + val languageVersionString: String + val apiVersionString: String + val coroutinesEnable: Boolean + val coroutinesWarn: Boolean + val coroutinesError: Boolean + val multiplatformEnable: Boolean + val metadataVersionMajor: Int + val metadataVersionMinor: Int + val metadataVersionPatch: Int + val ownVersion: Int + val coroutinesVersion: Int + val multiplatformVersion: Int +} + +abstract class BuildMetaInfoFactory(private val metaInfoClass: KClass) { + protected abstract fun create( + isEAP: Boolean, + compilerBuildVersion: String, + languageVersionString: String, + apiVersionString: String, + coroutinesEnable: Boolean, + coroutinesWarn: Boolean, + coroutinesError: Boolean, + multiplatformEnable: Boolean, + ownVersion: Int, + coroutinesVersion: Int, + multiplatformVersion: Int + ): T + + fun create(args: CommonCompilerArguments): T { + val languageVersion = args.languageVersion?.let((LanguageVersion)::fromVersionString) ?: LanguageVersion.LATEST_STABLE + + return create( + isEAP = languageVersion.isPreRelease(), + compilerBuildVersion = KotlinCompilerVersion.VERSION, + languageVersionString = languageVersion.versionString, + apiVersionString = args.apiVersion ?: languageVersion.versionString, + coroutinesEnable = args.coroutinesState == CommonCompilerArguments.ENABLE, + coroutinesWarn = args.coroutinesState == CommonCompilerArguments.WARN, + coroutinesError = args.coroutinesState == CommonCompilerArguments.ERROR, + multiplatformEnable = args.multiPlatform, + ownVersion = OWN_VERSION, + coroutinesVersion = COROUTINES_VERSION, + multiplatformVersion = MULTIPLATFORM_VERSION + ) + } + + fun serializeToString(info: T): String = + serializeToPlainText(info, metaInfoClass) + + fun deserializeFromString(str: String): T? = + deserializeFromPlainText(str, metaInfoClass) + + companion object { + const val OWN_VERSION: Int = 0 + const val COROUTINES_VERSION: Int = 0 + const val MULTIPLATFORM_VERSION: Int = 0 + } +} \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt new file mode 100644 index 00000000000..ecb48a94132 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.build + +import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion +import org.jetbrains.kotlin.utils.JsMetadataVersion + +/** + * If you want to add a new field, check its type is supported by [serializeToPlainText], [deserializeFromPlainText] + */ +data class CommonBuildMetaInfo( + override val isEAP: Boolean, + override val compilerBuildVersion: String, + override val languageVersionString: String, + override val apiVersionString: String, + override val coroutinesEnable: Boolean, + override val coroutinesWarn: Boolean, + override val coroutinesError: Boolean, + override val multiplatformEnable: Boolean, + override val metadataVersionMajor: Int, + override val metadataVersionMinor: Int, + override val metadataVersionPatch: Int, + override val ownVersion: Int, + override val coroutinesVersion: Int, + override val multiplatformVersion: Int +) : BuildMetaInfo { + companion object : BuildMetaInfoFactory(CommonBuildMetaInfo::class) { + override fun create( + isEAP: Boolean, + compilerBuildVersion: String, + languageVersionString: String, + apiVersionString: String, + coroutinesEnable: Boolean, + coroutinesWarn: Boolean, + coroutinesError: Boolean, + multiplatformEnable: Boolean, + ownVersion: Int, + coroutinesVersion: Int, + multiplatformVersion: Int + ) = CommonBuildMetaInfo( + isEAP = isEAP, + compilerBuildVersion = compilerBuildVersion, + languageVersionString = languageVersionString, + apiVersionString = apiVersionString, + coroutinesEnable = coroutinesEnable, + coroutinesWarn = coroutinesWarn, + coroutinesError = coroutinesError, + multiplatformEnable = multiplatformEnable, + metadataVersionMajor = JvmMetadataVersion.INSTANCE.major, + metadataVersionMinor = JvmMetadataVersion.INSTANCE.minor, + metadataVersionPatch = JvmMetadataVersion.INSTANCE.patch, + ownVersion = ownVersion, + coroutinesVersion = coroutinesVersion, + multiplatformVersion = multiplatformVersion + ) + } +} \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt new file mode 100644 index 00000000000..067eef8acf9 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.build + +import org.jetbrains.kotlin.utils.JsMetadataVersion + +/** + * If you want to add a new field, check its type is supported by [serializeToPlainText], [deserializeFromPlainText] + */ +data class JsBuildMetaInfo( + override val isEAP: Boolean, + override val compilerBuildVersion: String, + override val languageVersionString: String, + override val apiVersionString: String, + override val coroutinesEnable: Boolean, + override val coroutinesWarn: Boolean, + override val coroutinesError: Boolean, + override val multiplatformEnable: Boolean, + override val metadataVersionMajor: Int, + override val metadataVersionMinor: Int, + override val metadataVersionPatch: Int, + override val ownVersion: Int, + override val coroutinesVersion: Int, + override val multiplatformVersion: Int +) : BuildMetaInfo { + companion object : BuildMetaInfoFactory(JsBuildMetaInfo::class) { + override fun create( + isEAP: Boolean, + compilerBuildVersion: String, + languageVersionString: String, + apiVersionString: String, + coroutinesEnable: Boolean, + coroutinesWarn: Boolean, + coroutinesError: Boolean, + multiplatformEnable: Boolean, + ownVersion: Int, + coroutinesVersion: Int, + multiplatformVersion: Int + ) = JsBuildMetaInfo( + isEAP = isEAP, + compilerBuildVersion = compilerBuildVersion, + languageVersionString = languageVersionString, + apiVersionString = apiVersionString, + coroutinesEnable = coroutinesEnable, + coroutinesWarn = coroutinesWarn, + coroutinesError = coroutinesError, + multiplatformEnable = multiplatformEnable, + metadataVersionMajor = JsMetadataVersion.INSTANCE.major, + metadataVersionMinor = JsMetadataVersion.INSTANCE.minor, + metadataVersionPatch = JsMetadataVersion.INSTANCE.patch, + ownVersion = ownVersion, + coroutinesVersion = coroutinesVersion, + multiplatformVersion = multiplatformVersion + ) + } +} \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt index 8535f48db76..c27f83aa783 100644 --- a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt @@ -16,10 +16,6 @@ package org.jetbrains.kotlin.build -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.config.KotlinCompilerVersion -import org.jetbrains.kotlin.config.LanguageVersion -import org.jetbrains.kotlin.config.isPreRelease import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion @@ -27,54 +23,55 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion * If you want to add a new field, check its type is supported by [serializeToPlainText], [deserializeFromPlainText] */ data class JvmBuildMetaInfo( - val isEAP: Boolean, - val compilerBuildVersion: String, - val languageVersionString: String, - val apiVersionString: String, - val coroutinesEnable: Boolean, - val coroutinesWarn: Boolean, - val coroutinesError: Boolean, - val multiplatformEnable: Boolean, - val metadataVersionMajor: Int, - val metadataVersionMinor: Int, - val metadataVersionPatch: Int, - val bytecodeVersionMajor: Int, - val bytecodeVersionMinor: Int, - val bytecodeVersionPatch: Int, - val ownVersion: Int = JvmBuildMetaInfo.OWN_VERSION, - val coroutinesVersion: Int = JvmBuildMetaInfo.COROUTINES_VERSION, - val multiplatformVersion: Int = JvmBuildMetaInfo.MULTIPLATFORM_VERSION -) { - companion object { - const val OWN_VERSION: Int = 0 - const val COROUTINES_VERSION: Int = 0 - const val MULTIPLATFORM_VERSION: Int = 0 - - fun serializeToString(info: JvmBuildMetaInfo): String = - serializeToPlainText(info) - - fun deserializeFromString(str: String): JvmBuildMetaInfo? = - deserializeFromPlainText(str) - } -} - -fun JvmBuildMetaInfo(args: CommonCompilerArguments): JvmBuildMetaInfo { - val languageVersion = args.languageVersion?.let((LanguageVersion)::fromVersionString) ?: LanguageVersion.LATEST_STABLE - - return JvmBuildMetaInfo( - isEAP = languageVersion.isPreRelease(), - compilerBuildVersion = KotlinCompilerVersion.VERSION, - languageVersionString = languageVersion.versionString, - apiVersionString = args.apiVersion ?: languageVersion.versionString, - coroutinesEnable = args.coroutinesState == CommonCompilerArguments.ENABLE, - coroutinesWarn = args.coroutinesState == CommonCompilerArguments.WARN, - coroutinesError = args.coroutinesState == CommonCompilerArguments.ERROR, - multiplatformEnable = args.multiPlatform, + override val isEAP: Boolean, + override val compilerBuildVersion: String, + override val languageVersionString: String, + override val apiVersionString: String, + override val coroutinesEnable: Boolean, + override val coroutinesWarn: Boolean, + override val coroutinesError: Boolean, + override val multiplatformEnable: Boolean, + override val metadataVersionMajor: Int, + override val metadataVersionMinor: Int, + override val metadataVersionPatch: Int, + val bytecodeVersionMajor: Int, + val bytecodeVersionMinor: Int, + val bytecodeVersionPatch: Int, + override val ownVersion: Int, + override val coroutinesVersion: Int, + override val multiplatformVersion: Int +) : BuildMetaInfo { + companion object : BuildMetaInfoFactory(JvmBuildMetaInfo::class) { + override fun create( + isEAP: Boolean, + compilerBuildVersion: String, + languageVersionString: String, + apiVersionString: String, + coroutinesEnable: Boolean, + coroutinesWarn: Boolean, + coroutinesError: Boolean, + multiplatformEnable: Boolean, + ownVersion: Int, + coroutinesVersion: Int, + multiplatformVersion: Int + ) = JvmBuildMetaInfo( + isEAP = isEAP, + compilerBuildVersion = compilerBuildVersion, + languageVersionString = languageVersionString, + apiVersionString = apiVersionString, + coroutinesEnable = coroutinesEnable, + coroutinesWarn = coroutinesWarn, + coroutinesError = coroutinesError, + multiplatformEnable = multiplatformEnable, metadataVersionMajor = JvmMetadataVersion.INSTANCE.major, metadataVersionMinor = JvmMetadataVersion.INSTANCE.minor, metadataVersionPatch = JvmMetadataVersion.INSTANCE.patch, bytecodeVersionMajor = JvmBytecodeBinaryVersion.INSTANCE.major, bytecodeVersionMinor = JvmBytecodeBinaryVersion.INSTANCE.minor, - bytecodeVersionPatch = JvmBytecodeBinaryVersion.INSTANCE.patch - ) + bytecodeVersionPatch = JvmBytecodeBinaryVersion.INSTANCE.patch, + ownVersion = ownVersion, + coroutinesVersion = coroutinesVersion, + multiplatformVersion = multiplatformVersion + ) + } } diff --git a/build-common/test/org/jetbrains/kotlin/build/JvmBuildMetaInfoTest.kt b/build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt similarity index 58% rename from build-common/test/org/jetbrains/kotlin/build/JvmBuildMetaInfoTest.kt rename to build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt index e5b230f1b54..17cc4f04ba9 100644 --- a/build-common/test/org/jetbrains/kotlin/build/JvmBuildMetaInfoTest.kt +++ b/build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt @@ -22,52 +22,61 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.junit.Assert.assertNotEquals import org.junit.Test -class JvmBuildMetaInfoTest : TestCase() { +class BuildMetaInfoTest : TestCase() { @Test - fun testSerialization() { + fun testJvmSerialization() { val args = K2JVMCompilerArguments() - val info = JvmBuildMetaInfo(args) + val info = JvmBuildMetaInfo.create(args) val actual = JvmBuildMetaInfo.serializeToString(info) val expectedKeys = listOf( - "apiVersionString", - "bytecodeVersionMajor", - "bytecodeVersionMinor", - "bytecodeVersionPatch", - "compilerBuildVersion", - "coroutinesEnable", - "coroutinesError", - "coroutinesVersion", - "coroutinesWarn", - "isEAP", - "languageVersionString", - "metadataVersionMajor", - "metadataVersionMinor", - "metadataVersionPatch", - "multiplatformEnable", - "multiplatformVersion", - "ownVersion" + "apiVersionString", + "bytecodeVersionMajor", + "bytecodeVersionMinor", + "bytecodeVersionPatch", + "compilerBuildVersion", + "coroutinesEnable", + "coroutinesError", + "coroutinesVersion", + "coroutinesWarn", + "isEAP", + "languageVersionString", + "metadataVersionMajor", + "metadataVersionMinor", + "metadataVersionPatch", + "multiplatformEnable", + "multiplatformVersion", + "ownVersion" ) assertEquals(expectedKeys, actual.split("\r\n", "\n").map { line -> line.split("=").first() }) } @Test - fun testSerializationDeserialization() { + fun testJvmSerializationDeserialization() { val args = K2JVMCompilerArguments() - val info = JvmBuildMetaInfo(args) + val info = JvmBuildMetaInfo.create(args) val serialized = JvmBuildMetaInfo.serializeToString(info) val deserialized = JvmBuildMetaInfo.deserializeFromString(serialized) assertEquals(info, deserialized) } @Test - fun testEquals() { + fun testJsSerializationDeserialization() { + val args = K2JVMCompilerArguments() + val info = JvmBuildMetaInfo.create(args) + val serialized = JvmBuildMetaInfo.serializeToString(info) + val deserialized = JvmBuildMetaInfo.deserializeFromString(serialized) + assertEquals(info, deserialized) + } + + @Test + fun testJvmEquals() { val args1 = K2JVMCompilerArguments() args1.coroutinesState = CommonCompilerArguments.ENABLE - val info1 = JvmBuildMetaInfo(args1) + val info1 = JvmBuildMetaInfo.create(args1) val args2 = K2JVMCompilerArguments() args2.coroutinesState = CommonCompilerArguments.WARN - val info2 = JvmBuildMetaInfo(args2) + val info2 = JvmBuildMetaInfo.create(args2) assertNotEquals(info1, info2) assertEquals(info1, info2.copy(coroutinesEnable = true, coroutinesWarn = false)) diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalLazyCachesTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalLazyCachesTest.kt index bdab61993f6..533a0091c0f 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalLazyCachesTest.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/AbstractIncrementalLazyCachesTest.kt @@ -18,15 +18,17 @@ package org.jetbrains.kotlin.jps.build import com.intellij.testFramework.UsefulTestCase import org.jetbrains.jps.builders.BuildTarget +import org.jetbrains.jps.builders.CompileScopeTestBuilder import org.jetbrains.jps.builders.storage.BuildDataPaths +import org.jetbrains.jps.incremental.CompileContextImpl import org.jetbrains.kotlin.config.IncrementalCompilation -import org.jetbrains.kotlin.incremental.CacheVersion import org.jetbrains.kotlin.incremental.KOTLIN_CACHE_DIRECTORY_NAME import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import org.jetbrains.kotlin.incremental.testingUtils.Modification import org.jetbrains.kotlin.incremental.testingUtils.ModifyContent import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget +import org.jetbrains.kotlin.jps.platforms.kotlinBuildTargets import org.jetbrains.kotlin.utils.Printer import java.io.File @@ -91,11 +93,15 @@ abstract class AbstractIncrementalLazyCachesTest : AbstractIncrementalJpsTest() dumpCachesForTarget(p, paths, KotlinDataContainerTarget, versions.dataContainerVersion().formatVersionFile) + // for getting kotlin platform only + val dummyCompileContext = CompileContextImpl.createContextForTests(CompileScopeTestBuilder.make().build(), projectDescriptor) + for (target in targets.sortedBy { it.presentableName }) { - val jvmMetaBuildInfo = jvmBuildMetaInfoFile(target, dataManager) + val kotlinModuleBuildTarget = dummyCompileContext.kotlinBuildTargets[target]!! + val metaBuildInfo = kotlinModuleBuildTarget.buildMetaInfoFile(target, dataManager) dumpCachesForTarget(p, paths, target, versions.normalVersion(target).formatVersionFile, - jvmMetaBuildInfo, + metaBuildInfo, subdirectory = KOTLIN_CACHE_DIRECTORY_NAME) } diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt index 6dc02d73831..1ea6234088c 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/dependeciestxt/DependenciesTxt.kt @@ -34,7 +34,7 @@ data class DependenciesTxt( var index: Int = -1 val indexedName - get() = "${index / 10}${index % 10}_$name" + get() = "${index.toString().padStart(2, '0')}_$name" /** * Facet should not be created for old tests diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index f1b45e105cb..2dec1d15e92 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -63,7 +63,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { const val KOTLIN_BUILDER_NAME: String = "Kotlin Builder" val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder") - const val JVM_BUILD_META_INFO_FILE_NAME = "jvm-build-meta-info.txt" const val SKIP_CACHE_VERSION_CHECK_PROPERTY = "kotlin.jps.skip.cache.version.check" const val JPS_KOTLIN_HOME_PROPERTY = "jps.kotlin.home" @@ -259,7 +258,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { private fun doBuild( chunk: ModuleChunk, - representativeTarget: KotlinModuleBuildTarget, + representativeTarget: KotlinModuleBuildTarget<*>, context: CompileContext, kotlinDirtyFilesHolder: KotlinDirtySourceFilesHolder, messageCollector: MessageCollectorAdapter, @@ -345,7 +344,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val generatedFiles = getGeneratedFiles(context, chunk, environment.outputItemsCollector) registerOutputItems(outputConsumer, generatedFiles) - saveVersions(context, chunk, commonArguments) + representativeTarget.saveVersions(context, chunk, commonArguments) if (targets.any { hasKotlin[it] == null }) { fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = kotlinDirtyFilesHolder.allDirtyFiles) @@ -476,26 +475,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { dataManager.cleanLookupStorage(LOG) } - private fun saveVersions(context: CompileContext, chunk: ModuleChunk, commonArguments: CommonCompilerArguments) { - val dataManager = context.projectDescriptor.dataManager - val targets = chunk.targets - val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths) - cacheVersionsProvider.allVersions(targets).forEach { it.saveIfNeeded() } - - val isJsModule = context.kotlinBuildTargets[chunk.representativeTarget()] is KotlinJsModuleBuildTarget - if (!isJsModule) { - val jvmBuildMetaInfo = JvmBuildMetaInfo(commonArguments) - val serializedMetaInfo = JvmBuildMetaInfo.serializeToString(jvmBuildMetaInfo) - - for (target in chunk.targets) { - jvmBuildMetaInfoFile(target, dataManager).writeText(serializedMetaInfo) - } - } - } - private fun doCompileModuleChunk( chunk: ModuleChunk, - kotlinTarget: KotlinModuleBuildTarget, + kotlinTarget: KotlinModuleBuildTarget<*>, commonArguments: CommonCompilerArguments, context: CompileContext, dirtyFilesHolder: KotlinDirtySourceFilesHolder, @@ -537,15 +519,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { } } - val isDoneSomething = kotlinTarget.compileModuleChunk( - chunk, commonArguments, dirtyFilesHolder, environment - ) + val isDoneSomething = kotlinTarget.compileModuleChunk(chunk, commonArguments, dirtyFilesHolder, environment) return if (isDoneSomething) environment.outputItemsCollector else null } private fun createCompileEnvironment( - kotlinModuleBuilderTarget: KotlinModuleBuildTarget, + kotlinModuleBuilderTarget: KotlinModuleBuildTarget<*>, incrementalCaches: Map, lookupTracker: LookupTracker, exceptActualTracer: ExpectActualTracker, @@ -753,7 +733,4 @@ fun getDependentTargets( } private fun getDependenciesRecursively(module: JpsModule, kind: JpsJavaClasspathKind): Set = - JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().modules - -fun jvmBuildMetaInfoFile(target: ModuleBuildTarget, dataManager: BuildDataManager): File = - File(dataManager.dataPaths.getTargetDataRoot(target), KotlinBuilder.JVM_BUILD_META_INFO_FILE_NAME) \ No newline at end of file + JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().modules \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.kt index 421ebbd61cf..60ba5e93e24 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/MessageCollectorAdapter.kt @@ -17,7 +17,7 @@ import java.io.File class MessageCollectorAdapter( private val context: CompileContext, - private val kotlinTarget: KotlinModuleBuildTarget? + private val kotlinTarget: KotlinModuleBuildTarget<*>? ) : MessageCollector { private var hasErrors = false diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt index 10f0c650669..52875842765 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/JpsIncrementalCache.kt @@ -59,7 +59,7 @@ class JpsIncrementalJsCache( } private class KotlinIncrementalStorageProvider( - private val target: KotlinModuleBuildTarget, + private val target: KotlinModuleBuildTarget<*>, private val paths: BuildDataPaths ) : StorageProvider() { init { @@ -73,7 +73,7 @@ private class KotlinIncrementalStorageProvider( override fun createStorage(targetDataDir: File): JpsIncrementalCache = target.createCacheStorage(paths) } -fun BuildDataManager.getKotlinCache(target: KotlinModuleBuildTarget?): JpsIncrementalCache? = +fun BuildDataManager.getKotlinCache(target: KotlinModuleBuildTarget<*>?): JpsIncrementalCache? = if (target == null || !target.hasCaches) null else getStorage(target.jpsModuleBuildTarget, KotlinIncrementalStorageProvider(target, dataPaths)) diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt index f54ab93f672..f900f7b9f42 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinCommonModuleBuildTarget.kt @@ -12,17 +12,25 @@ import org.jetbrains.jps.incremental.ModuleBuildTarget import org.jetbrains.jps.model.library.JpsOrderRootType import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.util.JpsPathUtil +import org.jetbrains.kotlin.build.CommonBuildMetaInfo import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder -import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings +private const val COMMON_BUILD_META_INFO_FILE_NAME = "common-build-meta-info.txt" + class KotlinCommonModuleBuildTarget(context: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : - KotlinModuleBuildTarget(context, jpsModuleBuildTarget) { + KotlinModuleBuildTarget(context, jpsModuleBuildTarget) { + + override val buildMetaInfoFactory + get() = CommonBuildMetaInfo + + override val buildMetaInfoFileName + get() = COMMON_BUILD_META_INFO_FILE_NAME override fun compileModuleChunk( chunk: ModuleChunk, diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt index d02ac9f7df1..9f5e650efc0 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJsModuleBuildTarget.kt @@ -13,6 +13,7 @@ import org.jetbrains.jps.model.library.JpsOrderRootType import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.util.JpsPathUtil import org.jetbrains.kotlin.build.GeneratedFile +import org.jetbrains.kotlin.build.JsBuildMetaInfo import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner @@ -39,8 +40,16 @@ import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX import java.io.File import java.net.URI +private const val JS_BUILD_META_INFO_FILE_NAME = "js-build-meta-info.txt" + class KotlinJsModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : - KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) { + KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) { + + override val buildMetaInfoFactory + get() = JsBuildMetaInfo + + override val buildMetaInfoFileName: String + get() = JS_BUILD_META_INFO_FILE_NAME val isFirstBuild: Boolean get() { diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt index e0306df8e30..9f839bf3054 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinJvmModuleBuildTarget.kt @@ -16,7 +16,6 @@ import org.jetbrains.jps.builders.java.JavaBuilderUtil import org.jetbrains.jps.builders.storage.BuildDataPaths import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.jps.incremental.ModuleBuildTarget -import org.jetbrains.jps.incremental.storage.BuildDataManager import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsSdkDependency import org.jetbrains.kotlin.build.GeneratedFile @@ -27,15 +26,15 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner -import org.jetbrains.kotlin.config.ApiVersion -import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.Services -import org.jetbrains.kotlin.incremental.* +import org.jetbrains.kotlin.incremental.ChangesCollector +import org.jetbrains.kotlin.incremental.IncrementalCompilationComponentsImpl +import org.jetbrains.kotlin.incremental.IncrementalJvmCache import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.updateIncrementalCache import org.jetbrains.kotlin.jps.build.KotlinBuilder import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder -import org.jetbrains.kotlin.jps.build.jvmBuildMetaInfoFile import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJvmCache import org.jetbrains.kotlin.jps.model.k2JvmCompilerArguments @@ -49,56 +48,18 @@ import org.jetbrains.org.objectweb.asm.ClassReader import java.io.File import java.io.IOException +private const val JVM_BUILD_META_INFO_FILE_NAME = "jvm-build-meta-info.txt" + class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildTarget: ModuleBuildTarget) : - KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) { + KotlinModuleBuildTarget(compileContext, jpsModuleBuildTarget) { override fun createCacheStorage(paths: BuildDataPaths) = JpsIncrementalJvmCache(jpsModuleBuildTarget, paths) - override fun checkCachesVersions(chunk: ModuleChunk, dataManager: BuildDataManager, actions: MutableSet) { - val args = compilerArgumentsForChunk(chunk) - val currentBuildMetaInfo = JvmBuildMetaInfo(args) + override val buildMetaInfoFactory + get() = JvmBuildMetaInfo - for (target in chunk.targets) { - val file = jvmBuildMetaInfoFile(target, dataManager) - if (!file.exists()) continue - - val lastBuildMetaInfo = - try { - JvmBuildMetaInfo.deserializeFromString(file.readText()) ?: continue - } catch (e: Exception) { - KotlinBuilder.LOG.error("Could not deserialize jvm build meta info", e) - continue - } - - val lastBuildLangVersion = LanguageVersion.fromVersionString(lastBuildMetaInfo.languageVersionString) - val lastBuildApiVersion = ApiVersion.parse(lastBuildMetaInfo.apiVersionString) - val currentLangVersion = - args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE - val currentApiVersion = - args.apiVersion?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(currentLangVersion) - - val reasonToRebuild = when { - currentLangVersion != lastBuildLangVersion -> { - "Language version was changed ($lastBuildLangVersion -> $currentLangVersion)" - } - - currentApiVersion != lastBuildApiVersion -> { - "Api version was changed ($lastBuildApiVersion -> $currentApiVersion)" - } - - lastBuildLangVersion != LanguageVersion.KOTLIN_1_0 && lastBuildMetaInfo.isEAP && !currentBuildMetaInfo.isEAP -> { - // If EAP->Non-EAP build with IC, then rebuild all kotlin - "Last build was compiled with EAP-plugin" - } - else -> null - } - - if (reasonToRebuild != null) { - KotlinBuilder.LOG.info("$reasonToRebuild. Performing non-incremental rebuild (kotlin only)") - actions.add(CacheVersion.Action.REBUILD_ALL_KOTLIN) - } - } - } + override val buildMetaInfoFileName + get() = JVM_BUILD_META_INFO_FILE_NAME override fun makeServices( builder: Services.Builder, @@ -174,7 +135,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT return true } - fun generateModuleDescription(chunk: ModuleChunk, dirtyFilesHolder: KotlinDirtySourceFilesHolder): File? { + private fun generateModuleDescription(chunk: ModuleChunk, dirtyFilesHolder: KotlinDirtySourceFilesHolder): File? { val builder = KotlinModuleXmlBuilder() var hasDirtySources = false @@ -241,7 +202,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT } } - fun findClassPathRoots(): Collection { + private fun findClassPathRoots(): Collection { return allDependencies.classes().roots.filter { file -> if (!file.exists()) { val extension = file.extension @@ -256,7 +217,7 @@ class KotlinJvmModuleBuildTarget(compileContext: CompileContext, jpsModuleBuildT } } - fun findModularJdkRoot(): File? { + private fun findModularJdkRoot(): File? { // List of paths to JRE modules in the following format: // jrt:///Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home!/java.base val urls = JpsJavaExtensionService.dependencies(module) diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt index 64c237213fa..24c0f8513c2 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/KotlinModuleBuildTarget.kt @@ -15,18 +15,26 @@ import org.jetbrains.jps.model.java.JpsJavaClasspathKind import org.jetbrains.jps.model.java.JpsJavaExtensionService import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.util.JpsPathUtil +import org.jetbrains.kotlin.build.BuildMetaInfo +import org.jetbrains.kotlin.build.BuildMetaInfoFactory import org.jetbrains.kotlin.build.GeneratedFile import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment +import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.IncrementalCompilation +import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.incremental.CacheVersion import org.jetbrains.kotlin.incremental.ChangesCollector import org.jetbrains.kotlin.incremental.ExpectActualTrackerImpl import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.jps.build.* +import org.jetbrains.kotlin.jps.build.KotlinBuilder +import org.jetbrains.kotlin.jps.build.KotlinCommonModuleSourceRoot +import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder +import org.jetbrains.kotlin.jps.build.isKotlinSourceFile +import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments import org.jetbrains.kotlin.jps.model.productionOutputFilePath @@ -40,7 +48,10 @@ import java.io.File /** * Properties and actions for Kotlin test / production module build target. */ -abstract class KotlinModuleBuildTarget(val context: CompileContext, val jpsModuleBuildTarget: ModuleBuildTarget) { +abstract class KotlinModuleBuildTarget( + val context: CompileContext, + val jpsModuleBuildTarget: ModuleBuildTarget +) { val module: JpsModule get() = jpsModuleBuildTarget.module @@ -69,9 +80,9 @@ abstract class KotlinModuleBuildTarget(val context: CompileContext, val jpsModul ?: throw ProjectBuildException("No output directory found for " + this) } - val friendBuildTargets: List + val friendBuildTargets: List> get() { - val result = mutableListOf() + val result = mutableListOf>() if (isTests) { result.addIfNotNull(context.kotlinBuildTargets[module.productionBuildTarget]) @@ -224,7 +235,7 @@ abstract class KotlinModuleBuildTarget(val context: CompileContext, val jpsModul * Should be used only for particular target in chunk (jvm) */ protected fun collectSourcesToCompile( - target: KotlinModuleBuildTarget, + target: KotlinModuleBuildTarget, dirtyFilesHolder: KotlinDirtySourceFilesHolder ): Collection { // Should not be cached since may be vary in different rounds @@ -241,7 +252,7 @@ abstract class KotlinModuleBuildTarget(val context: CompileContext, val jpsModul * Should be used only for particular target in chunk (jvm) */ protected fun checkShouldCompileAndLog( - target: KotlinModuleBuildTarget, + target: KotlinModuleBuildTarget, dirtyFilesHolder: KotlinDirtySourceFilesHolder, moduleSources: Collection ): Boolean { @@ -257,7 +268,70 @@ abstract class KotlinModuleBuildTarget(val context: CompileContext, val jpsModul return hasDirtyOrRemovedSources } - open fun checkCachesVersions(chunk: ModuleChunk, dataManager: BuildDataManager, actions: MutableSet) { + abstract val buildMetaInfoFactory: BuildMetaInfoFactory + abstract val buildMetaInfoFileName: String + + fun buildMetaInfoFile(target: ModuleBuildTarget, dataManager: BuildDataManager): File = + File(dataManager.dataPaths.getTargetDataRoot(target), buildMetaInfoFileName) + + fun saveVersions(context: CompileContext, chunk: ModuleChunk, commonArguments: CommonCompilerArguments) { + val dataManager = context.projectDescriptor.dataManager + val targets = chunk.targets + val cacheVersionsProvider = CacheVersionProvider(dataManager.dataPaths) + cacheVersionsProvider.allVersions(targets).forEach { it.saveIfNeeded() } + + val buildMetaInfo = buildMetaInfoFactory.create(commonArguments) + val serializedMetaInfo = buildMetaInfoFactory.serializeToString(buildMetaInfo) + + for (target in chunk.targets) { + buildMetaInfoFile(target, dataManager).writeText(serializedMetaInfo) + } + } + + fun checkCachesVersions(chunk: ModuleChunk, dataManager: BuildDataManager, actions: MutableSet) { + val args = compilerArgumentsForChunk(chunk) + val currentBuildMetaInfo = buildMetaInfoFactory.create(args) + + for (target in chunk.targets) { + val file = buildMetaInfoFile(target, dataManager) + if (!file.exists()) continue + + val lastBuildMetaInfo = + try { + buildMetaInfoFactory.deserializeFromString(file.readText()) ?: continue + } catch (e: Exception) { + KotlinBuilder.LOG.error("Could not deserialize build meta info", e) + continue + } + + val lastBuildLangVersion = LanguageVersion.fromVersionString(lastBuildMetaInfo.languageVersionString) + val lastBuildApiVersion = ApiVersion.parse(lastBuildMetaInfo.apiVersionString) + val currentLangVersion = + args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE + val currentApiVersion = + args.apiVersion?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(currentLangVersion) + + val reasonToRebuild = when { + currentLangVersion != lastBuildLangVersion -> { + "Language version was changed ($lastBuildLangVersion -> $currentLangVersion)" + } + + currentApiVersion != lastBuildApiVersion -> { + "Api version was changed ($lastBuildApiVersion -> $currentApiVersion)" + } + + lastBuildLangVersion != LanguageVersion.KOTLIN_1_0 && lastBuildMetaInfo.isEAP && !currentBuildMetaInfo.isEAP -> { + // If EAP->Non-EAP build with IC, then rebuild all kotlin + "Last build was compiled with EAP-plugin" + } + else -> null + } + + if (reasonToRebuild != null) { + KotlinBuilder.LOG.info("$reasonToRebuild. Performing non-incremental rebuild (kotlin only)") + actions.add(CacheVersion.Action.REBUILD_ALL_KOTLIN) + } + } } } \ No newline at end of file diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt index 1f85c07e7a9..2e81b65791d 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/platforms/TargetPlatform.kt @@ -45,16 +45,16 @@ val CompileContext.kotlinBuildTargets: KotlinBuildTargets } class KotlinBuildTargets internal constructor(val compileContext: CompileContext) { - private val byJpsModuleBuildTarget = ConcurrentHashMap() + private val byJpsModuleBuildTarget = ConcurrentHashMap>() private val isKotlinJsStdlibJar = ConcurrentHashMap() @JvmName("getNullable") - operator fun get(target: ModuleBuildTarget?): KotlinModuleBuildTarget? { + operator fun get(target: ModuleBuildTarget?): KotlinModuleBuildTarget<*>? { if (target == null) return null return get(target) } - operator fun get(target: ModuleBuildTarget): KotlinModuleBuildTarget? { + operator fun get(target: ModuleBuildTarget): KotlinModuleBuildTarget<*>? { if (target.module.moduleType != JpsJavaModuleType.INSTANCE) return null return byJpsModuleBuildTarget.computeIfAbsent(target) {