+25
-23
@@ -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<Proto
|
||||
val classes = hashMapOf<ClassId, ProtoData>()
|
||||
|
||||
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<ClassId, ProtoData> {
|
||||
val classes = hashMapOf<ClassId, ProtoData>()
|
||||
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
|
||||
}
|
||||
+5
-12
@@ -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<Loca
|
||||
return localClassFiles.associateBy { it.classId }
|
||||
}
|
||||
|
||||
override fun difference(oldData: LocalFileKotlinClass, newData: LocalFileKotlinClass): Difference? {
|
||||
val oldProto = oldData.readProto() ?: return null
|
||||
val newProto = newData.readProto() ?: return null
|
||||
return difference(oldProto, newProto)
|
||||
}
|
||||
|
||||
private fun KotlinJvmBinaryClass.readProto(): ProtoMapValue? {
|
||||
override fun LocalFileKotlinClass.toProtoData(): ProtoData? {
|
||||
assert(classHeader.metadataVersion.isCompatible()) { "Incompatible class ($classHeader): $location" }
|
||||
|
||||
val bytes by lazy { BitEncoding.decodeBytes(classHeader.data!!) }
|
||||
val strings by lazy { classHeader.strings!! }
|
||||
val packageFqName = classId.packageFqName
|
||||
|
||||
return when (classHeader.kind) {
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
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
|
||||
|
||||
+24
-15
@@ -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<PROTO_DATA> : TestWithWorkingDir() {
|
||||
protected abstract fun compileAndGetClasses(sourceDir: File, outputDir: File): Map<ClassId, PROTO_DATA>
|
||||
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<PROTO_DATA> : 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<String>()
|
||||
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()}")
|
||||
}
|
||||
|
||||
|
||||
@@ -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<File>,
|
||||
dataManager: BuildDataManager,
|
||||
fsOperations: FSOperationsHelper,
|
||||
|
||||
Reference in New Issue
Block a user