Checking for constants values in incremental compiler.

This commit is contained in:
Evgeny Gerashchenko
2014-05-21 22:21:35 +04:00
parent af173484cb
commit e89b59a745
10 changed files with 91 additions and 6 deletions
@@ -30,16 +30,39 @@ import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader
import org.jetbrains.jet.descriptors.serialization.BitEncoding
import org.jetbrains.jet.utils.intellij.*
import java.util.Arrays
import com.intellij.util.io.IntInlineKeyDescriptor
import org.jetbrains.org.objectweb.asm.*
import com.intellij.util.io.EnumeratorStringDescriptor
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames
import org.jetbrains.jet.lang.resolve.java.JvmClassName
import java.util.TreeMap
public class IncrementalCache(baseDir: File) {
class object {
val PROTO_MAP: String = "proto.tab"
val PROTO_MAP = "proto.tab"
val CONSTANTS_MAP = "constants.tab"
private fun getConstantsHash(bytes: ByteArray): Int {
val result = TreeMap<String, Any>() // keys order should defined to check hash of a map
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
if (value != null) {
result[name] = value
}
return null
}
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return result.hashCode()
}
}
private val protoData: PersistentMap<ClassOrPackageId, ByteArray>
private val constantsData = PersistentHashMap(File(baseDir, CONSTANTS_MAP), EnumeratorStringDescriptor(), IntInlineKeyDescriptor())
{
protoData = PersistentHashMap<ClassOrPackageId, ByteArray>(File(baseDir, PROTO_MAP), object : KeyDescriptor<ClassOrPackageId> {
;{
protoData = PersistentHashMap(File(baseDir, PROTO_MAP), object : KeyDescriptor<ClassOrPackageId> {
override fun save(out: DataOutput, value: ClassOrPackageId?) {
IOUtil.writeString(value!!.moduleId, out)
IOUtil.writeString(value.fqName.asString(), out)
@@ -74,7 +97,8 @@ public class IncrementalCache(baseDir: File) {
}
public fun saveFileToCache(moduleId: String, file: File): Boolean {
val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(file.readBytes())
val fileBytes = file.readBytes()
val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(fileBytes)
if (classNameAndHeader == null) return false
val (className, header) = classNameAndHeader
@@ -91,6 +115,9 @@ public class IncrementalCache(baseDir: File) {
}
}
}
if (header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART) {
return putConstantsData(className, getConstantsHash(fileBytes))
}
return false
}
@@ -105,12 +132,24 @@ public class IncrementalCache(baseDir: File) {
return true
}
private fun putConstantsData(packagePartClass: JvmClassName, constantsHash: Int): Boolean {
val key = packagePartClass.getInternalName()
val oldHash = constantsData[key]
if (oldHash == constantsHash) {
return false
}
constantsData.put(key, constantsHash)
return true
}
public fun getPackageData(moduleId: String, fqName: FqName): ByteArray? {
return protoData[ClassOrPackageId(moduleId, fqName)]
}
public fun close() {
protoData.close()
constantsData.close()
}
private data class ClassOrPackageId(val moduleId: String, val fqName: FqName) {