From 2fbd8c4bebdd1094509d9733e4f4b49c482b2b2f Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Thu, 10 Aug 2017 15:59:56 +0300 Subject: [PATCH] Introduce ChangesCollector Original commit: 6fedf07f56ccf8861fdb0e76e5caa1d3bda6728e --- .../AbstractJsProtoComparisonTest.kt | 48 ++++++++++--------- .../AbstractJvmProtoComparisonTest.kt | 17 ++----- .../AbstractProtoComparisonTest.kt | 39 +++++++++------ .../kotlin/jps/build/KotlinBuilder.kt | 11 +++-- 4 files changed, 60 insertions(+), 55 deletions(-) diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt index 547ad15ea69..4359b01d3e0 100644 --- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt +++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt @@ -21,11 +21,8 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants import org.jetbrains.kotlin.cli.js.K2JSCompiler import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.config.Services -import org.jetbrains.kotlin.incremental.ClassProtoData -import org.jetbrains.kotlin.incremental.Difference -import org.jetbrains.kotlin.incremental.difference as differenceImpl -import org.jetbrains.kotlin.incremental.PackagePartProtoData import org.jetbrains.kotlin.incremental.ProtoData +import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.utils.TestMessageCollector import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl @@ -72,28 +69,33 @@ abstract class AbstractJsProtoComparisonTest : AbstractProtoComparisonTest() for ((sourceFile, protoBytes, _) in incrementalResults.packageParts) { - val proto = ProtoBuf.PackageFragment.parseFrom(protoBytes, JsSerializerProtocol.extensionRegistry) - val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames) - - proto.class_List.forEach { - val classId = nameResolver.getClassId(it.fqName) - classes[classId] = ClassProtoData(it, nameResolver) - } - - proto.`package`.apply { - val packageFqName = if (hasExtension(JsProtoBuf.packageFqName)) { - nameResolver.getPackageFqName(getExtension(JsProtoBuf.packageFqName)) - } - else FqName.ROOT - - val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt")) - classes[packagePartClassId] = PackagePartProtoData(this, nameResolver) - } + classes.putAll(getProtoData(sourceFile, protoBytes)) } return classes } - override fun difference(oldData: ProtoData, newData: ProtoData): Difference? = - differenceImpl(oldData, newData) + override fun ProtoData.toProtoData(): ProtoData? = this } + +fun getProtoData(sourceFile: File, metadata: ByteArray): Map { + val classes = hashMapOf() + val proto = ProtoBuf.PackageFragment.parseFrom(metadata, JsSerializerProtocol.extensionRegistry) + val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames) + + proto.class_List.forEach { + val classId = nameResolver.getClassId(it.fqName) + classes[classId] = ClassProtoData(it, nameResolver) + } + + proto.`package`.apply { + val packageFqName = if (hasExtension(JsProtoBuf.packageFqName)) { + nameResolver.getPackageFqName(getExtension(JsProtoBuf.packageFqName)) + } + else FqName.ROOT + + val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt")) + classes[packagePartClassId] = PackagePartProtoData(this, nameResolver, packageFqName) + } + return classes +} \ No newline at end of file diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt index f14ea22eab1..628fcab36aa 100644 --- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt +++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt @@ -16,9 +16,7 @@ package org.jetbrains.kotlin.jps.incremental -import org.jetbrains.kotlin.incremental.Difference -import org.jetbrains.kotlin.incremental.LocalFileKotlinClass -import org.jetbrains.kotlin.incremental.difference +import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.storage.ProtoMapValue import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader @@ -36,25 +34,20 @@ abstract class AbstractJvmProtoComparisonTest : AbstractProtoComparisonTest { - ProtoMapValue(false, bytes, strings) + ProtoMapValue(false, bytes, strings).toProtoData(packageFqName) } KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> { - ProtoMapValue(true, bytes, strings) + ProtoMapValue(true, bytes, strings).toProtoData(packageFqName) } else -> { null diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt index a74fba2f39f..9e1c15e1268 100644 --- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt +++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt @@ -17,7 +17,7 @@ package org.jetbrains.kotlin.jps.incremental import org.jetbrains.kotlin.TestWithWorkingDir -import org.jetbrains.kotlin.incremental.Difference +import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.utils.Printer @@ -25,7 +25,7 @@ import java.io.File abstract class AbstractProtoComparisonTest : TestWithWorkingDir() { protected abstract fun compileAndGetClasses(sourceDir: File, outputDir: File): Map - protected abstract fun difference(oldData: PROTO_DATA, newData: PROTO_DATA): Difference? + protected abstract fun PROTO_DATA.toProtoData(): ProtoData? protected open fun expectedOutputFile(testDir: File): File = File(testDir, "result.out") @@ -48,32 +48,41 @@ abstract class AbstractProtoComparisonTest : TestWithWorkingDir() { } (oldClassMap.keys.intersect(newClassMap.keys)).sortedBy { it.toString() }.forEach { classId -> - val oldData = oldClassMap[classId]!! - val newData = newClassMap[classId]!! - val diff = difference(oldData, newData) + val oldData = oldClassMap[classId]!!.toProtoData() + val newData = newClassMap[classId]!!.toProtoData() - if (diff == null) { + if (oldData == null || newData == null) { p.println("SKIPPED $classId") return@forEach } - diff.rawProtoDifference?.let { + val rawProtoDifference = when { + oldData is ClassProtoData && newData is ClassProtoData -> { + ProtoCompareGenerated(oldData.nameResolver, newData.nameResolver).difference(oldData.proto, newData.proto) + } + oldData is PackagePartProtoData && newData is PackagePartProtoData -> { + ProtoCompareGenerated(oldData.nameResolver, newData.nameResolver).difference(oldData.proto, newData.proto) + } + else -> null + } + rawProtoDifference?.let { if (it.isNotEmpty()) { p.println("PROTO DIFFERENCE in $classId: ${it.sortedBy { it.name }.joinToString()}") } } - val changes = arrayListOf() - if (diff.isClassAffected) { - changes.add("CLASS_SIGNATURE") - } - if (diff.changedMembersNames.isNotEmpty()) { - changes.add("MEMBERS\n ${diff.changedMembersNames.sorted()}") - } - if (changes.isEmpty()) { + val changesInfo = ChangesCollector().apply { collectProtoChanges(oldData, newData) }.changes() + if (changesInfo.isEmpty()) { return@forEach } + val changes = changesInfo.map { + when (it) { + is ChangeInfo.SignatureChanged -> "CLASS_SIGNATURE" + is ChangeInfo.MembersChanged -> "MEMBERS\n ${it.names.sorted()}" + } + }.sorted() + p.println("CHANGES in $classId: ${changes.joinToString()}") } diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index da1f8c92fa8..1f131ee18c6 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -314,8 +314,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { context.checkCanceled() - val changesInfo = generatedFiles.entries.fold(CompilationResult.NO_CHANGES) { acc, (target, files) -> - acc + updateIncrementalCache(files, incrementalCaches[target]!!) + val changesCollector = ChangesCollector() + for ((target, files) in generatedFiles) { + updateIncrementalCache(files, incrementalCaches[target]!!, changesCollector) } updateLookupStorage(chunk, lookupTracker, dataManager, dirtyFilesHolder, filesToCompile) @@ -323,7 +324,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { return OK } - changesInfo.processChangesUsingLookups(filesToCompile.values().toSet(), dataManager, fsOperations, incrementalCaches.values) + changesCollector.processChangesUsingLookups(filesToCompile.values().toSet(), dataManager, fsOperations, incrementalCaches.values) return OK } @@ -432,7 +433,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { for (target in chunk.targets) { val cache = incrementalCaches[target]!! val removedAndDirtyFiles = filesToCompile[target] + dirtyFilesHolder.getRemovedFiles(target).map(::File) - cache.markOutputClassesDirty(removedAndDirtyFiles) + cache.markDirty(removedAndDirtyFiles) } } @@ -774,7 +775,7 @@ private class JpsICReporter : ICReporter { } } -private fun CompilationResult.processChangesUsingLookups( +private fun ChangesCollector.processChangesUsingLookups( compiledFiles: Set, dataManager: BuildDataManager, fsOperations: FSOperationsHelper,