diff --git a/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt index 243073627bd..745c538685f 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt +++ b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt @@ -43,26 +43,10 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache { val PROTO_MAP = "proto.tab" val CONSTANTS_MAP = "constants.tab" val PACKAGE_SOURCES = "package-sources.tab" - - private fun getConstantsMap(bytes: ByteArray): Map { - val result = HashMap() - - 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 - } } private val protoMap = ProtoMap() - private val constantsData: PersistentHashMap> - = PersistentHashMap(File(baseDir, CONSTANTS_MAP), EnumeratorStringDescriptor(), ConstantsMapExternalizer()) + private val constantsMap = ConstantsMap() // Format of serialization to string: --> private val packageSourcesData: PersistentHashMap @@ -93,7 +77,7 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache { if (header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART) { assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" } putPackagePartSourceData(moduleId, sourceFiles.first(), className) - return putConstantsData(className, getConstantsMap(fileBytes)) + return constantsMap.process(className, fileBytes) } return false @@ -103,17 +87,6 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache { packageSourcesData.remove(getKeyForPackagePart(moduleId, sourceFile)) } - private fun putConstantsData(packagePartClass: JvmClassName, constantsMap: Map): Boolean { - val key = packagePartClass.getInternalName() - - val oldMap = constantsData[key] - if (oldMap == constantsMap) { - return false - } - constantsData.put(key, constantsMap) - return true - } - private fun getKeyForPackagePart(moduleId: String, sourceFile: File): String { return moduleId + File.pathSeparator + sourceFile.getAbsolutePath() } @@ -154,7 +127,7 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache { public fun close() { protoMap.close() - constantsData.close() + constantsMap.close() packageSourcesData.close() } @@ -188,7 +161,49 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache { } } - private class ConstantsMapExternalizer: DataExternalizer> { + private inner class ConstantsMap { + private val map: PersistentHashMap> = PersistentHashMap( + File(baseDir, CONSTANTS_MAP), + EnumeratorStringDescriptor(), + ConstantsMapExternalizer + ) + + private fun getConstantsMap(bytes: ByteArray): Map { + val result = HashMap() + + 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 + } + + public fun process(packagePartClass: JvmClassName, bytes: ByteArray): Boolean { + return put(packagePartClass, getConstantsMap(bytes)) + } + + private fun put(packagePartClass: JvmClassName, constantsMap: Map): Boolean { + val key = packagePartClass.getInternalName() + + val oldMap = map[key] + if (oldMap == constantsMap) { + return false + } + map.put(key, constantsMap) + return true + } + + public fun close() { + map.close() + } + } + + private object ConstantsMapExternalizer: DataExternalizer> { override fun save(out: DataOutput, map: Map?) { out.writeInt(map!!.size) for (name in map.keySet().toSortedList()) { @@ -244,7 +259,7 @@ public class IncrementalCacheImpl(val baseDir: File): IncrementalCache { private enum class Kind { INT FLOAT LONG DOUBLE STRING } - } + } } private object ByteArrayExternalizer: DataExternalizer {