Checking for constants values in incremental compiler.
This commit is contained in:
+43
-4
@@ -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) {
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.jetbrains.jet.jps.build
|
||||
|
||||
import org.jetbrains.ether.IncrementalTestCase
|
||||
import org.jetbrains.jps.builders.JpsBuildTestCase
|
||||
import kotlin.properties.Delegates
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import java.io.File
|
||||
import org.jetbrains.jps.builders.CompileScopeTestBuilder
|
||||
import org.jetbrains.jps.builders.BuildResult
|
||||
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerBase
|
||||
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
@@ -120,6 +118,14 @@ public class IncrementalJpsTest : JpsBuildTestCase() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testConstantValue() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testConstantUnchanged() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
private class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase() {
|
||||
private val logBuf = StringBuilder()
|
||||
public val log: String
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/TestPackage-const-*.class
|
||||
out/production/module/test/TestPackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/const.kt
|
||||
End of files
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
val CONST = "foo"
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
val CONST = "foo"
|
||||
@@ -0,0 +1,4 @@
|
||||
package test
|
||||
|
||||
deprecated(CONST + CONST)
|
||||
class Usage
|
||||
@@ -0,0 +1,13 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/TestPackage-const-*.class
|
||||
out/production/module/test/TestPackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/const.kt
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/test/Usage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/usage.kt
|
||||
End of files
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
val CONST = "foo"
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
val CONST = "bar"
|
||||
@@ -0,0 +1,4 @@
|
||||
package test
|
||||
|
||||
deprecated(CONST + CONST)
|
||||
class Usage
|
||||
Reference in New Issue
Block a user