Checking for changes in class proto.

This commit is contained in:
Evgeny Gerashchenko
2014-05-16 23:06:46 +04:00
parent c51cb26046
commit c4e167d7bc
6 changed files with 64 additions and 23 deletions
@@ -33,29 +33,29 @@ import java.util.Arrays
public class IncrementalCache(baseDir: File) { public class IncrementalCache(baseDir: File) {
class object { class object {
val PACKAGE_MAP: String = "package.tab" val PROTO_MAP: String = "proto.tab"
} }
private val packageFacadeData: PersistentMap<PackageFacadeId, ByteArray> private val protoData: PersistentMap<ClassOrPackageId, ByteArray>
{ {
packageFacadeData = PersistentHashMap<PackageFacadeId, ByteArray>(File(baseDir, PACKAGE_MAP), object : KeyDescriptor<PackageFacadeId> { protoData = PersistentHashMap<ClassOrPackageId, ByteArray>(File(baseDir, PROTO_MAP), object : KeyDescriptor<ClassOrPackageId> {
override fun save(out: DataOutput, value: PackageFacadeId?) { override fun save(out: DataOutput, value: ClassOrPackageId?) {
IOUtil.writeString(value!!.moduleId, out) IOUtil.writeString(value!!.moduleId, out)
IOUtil.writeString(value.fqName.asString(), out) IOUtil.writeString(value.fqName.asString(), out)
} }
override fun read(`in`: DataInput): PackageFacadeId { override fun read(`in`: DataInput): ClassOrPackageId {
val module = IOUtil.readString(`in`)!! val module = IOUtil.readString(`in`)!!
val fqName = FqName(IOUtil.readString(`in`)!!) val fqName = FqName(IOUtil.readString(`in`)!!)
return PackageFacadeId(module, fqName) return ClassOrPackageId(module, fqName)
} }
override fun getHashCode(value: PackageFacadeId?): Int { override fun getHashCode(value: ClassOrPackageId?): Int {
return value?.hashCode() ?: -1 return value?.hashCode() ?: -1
} }
override fun isEqual(val1: PackageFacadeId?, val2: PackageFacadeId?): Boolean { override fun isEqual(val1: ClassOrPackageId?, val2: ClassOrPackageId?): Boolean {
return val1 == val2 return val1 == val2
} }
}, object : DataExternalizer<ByteArray> { }, object : DataExternalizer<ByteArray> {
@@ -78,32 +78,41 @@ public class IncrementalCache(baseDir: File) {
if (classNameAndHeader == null) return false if (classNameAndHeader == null) return false
val (className, header) = classNameAndHeader val (className, header) = classNameAndHeader
if (header.kind == KotlinClassHeader.Kind.PACKAGE_FACADE) { val classFqName = className.getFqNameForClassNameWithoutDollars()
val fqName = className.getFqNameForClassNameWithoutDollars().parent() val annotationDataEncoded = header.annotationData
val data = BitEncoding.decodeBytes(header.annotationData!!) if (annotationDataEncoded != null) {
val oldData = getPackageData(moduleId, fqName) val data = BitEncoding.decodeBytes(annotationDataEncoded)
if (Arrays.equals(data, oldData)) { when (header.kind) {
return false KotlinClassHeader.Kind.PACKAGE_FACADE -> {
return putData(moduleId, classFqName.parent(), data)
}
KotlinClassHeader.Kind.CLASS -> {
return putData(moduleId, classFqName, data)
}
} }
putPackageData(moduleId, fqName, data)
return true
} }
// TODO Check class signatures, too!
return false return false
} }
private fun putPackageData(moduleId: String, fqName: FqName, data: ByteArray) { private fun putData(moduleId: String, fqName: FqName, data: ByteArray): Boolean {
packageFacadeData.put(PackageFacadeId(moduleId, fqName), data) val id = ClassOrPackageId(moduleId, fqName)
val oldData = protoData[id]
if (Arrays.equals(data, oldData)) {
return false
}
protoData.put(id, data)
return true
} }
public fun getPackageData(moduleId: String, fqName: FqName): ByteArray? { public fun getPackageData(moduleId: String, fqName: FqName): ByteArray? {
return packageFacadeData[PackageFacadeId(moduleId, fqName)] return protoData[ClassOrPackageId(moduleId, fqName)]
} }
public fun close() { public fun close() {
packageFacadeData.close() protoData.close()
} }
private data class PackageFacadeId(val moduleId: String, val fqName: FqName) { private data class ClassOrPackageId(val moduleId: String, val fqName: FqName) {
} }
} }
@@ -116,6 +116,10 @@ public class IncrementalJpsTest : JpsBuildTestCase() {
doTest() doTest()
} }
fun testClassSignatureChanged() {
doTest()
}
private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase() { private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase() {
private val logBuf = StringBuilder() private val logBuf = StringBuilder()
public val log: String public val log: String
@@ -127,7 +131,7 @@ public class IncrementalJpsTest : JpsBuildTestCase() {
fun String.replaceHashWithStar(): String { fun String.replaceHashWithStar(): String {
val lastHyphen = this.lastIndexOf('-') val lastHyphen = this.lastIndexOf('-')
if (lastHyphen != -1 && substring(lastHyphen + 1).matches("[0-9a-f]{8}\\.class")) { if (lastHyphen != -1 && substring(lastHyphen + 1).matches("[0-9a-f]{1,8}\\.class")) {
return substring(0, lastHyphen) + "-*.class" return substring(0, lastHyphen) + "-*.class"
} }
return this return this
@@ -0,0 +1,13 @@
Cleaning output files:
out/production/module/test/Klass.class
End of files
Compiling files:
src/class.kt
End of files
Cleaning output files:
out/production/module/test/TestPackage-usage-*.class
out/production/module/test/TestPackage.class
End of files
Compiling files:
src/usage.kt
End of files
@@ -0,0 +1,5 @@
package test
class Klass {
fun foo() = ":)"
}
@@ -0,0 +1,5 @@
package test
class Klass {
fun foo() = 123
}
@@ -0,0 +1,5 @@
package test
fun usage(a: Klass) {
a.foo()
}