From e89b59a74589682fd594e2d0e79bd5842151d049 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Wed, 21 May 2014 22:21:35 +0400 Subject: [PATCH] Checking for constants values in incremental compiler. --- .../kotlin/incremental/IncrementalCache.kt | 47 +++++++++++++++++-- .../jet/jps/build/IncrementalJpsTest.kt | 10 +++- .../incremental/constantUnchanged/build.log | 7 +++ .../incremental/constantUnchanged/const.kt | 3 ++ .../constantUnchanged/const.kt.new | 3 ++ .../incremental/constantUnchanged/usage.kt | 4 ++ .../incremental/constantValue/build.log | 13 +++++ .../incremental/constantValue/const.kt | 3 ++ .../incremental/constantValue/const.kt.new | 3 ++ .../incremental/constantValue/usage.kt | 4 ++ 10 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 jps-plugin/testData/incremental/constantUnchanged/build.log create mode 100644 jps-plugin/testData/incremental/constantUnchanged/const.kt create mode 100644 jps-plugin/testData/incremental/constantUnchanged/const.kt.new create mode 100644 jps-plugin/testData/incremental/constantUnchanged/usage.kt create mode 100644 jps-plugin/testData/incremental/constantValue/build.log create mode 100644 jps-plugin/testData/incremental/constantValue/const.kt create mode 100644 jps-plugin/testData/incremental/constantValue/const.kt.new create mode 100644 jps-plugin/testData/incremental/constantValue/usage.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt index 76821d5f433..8fa9a76432a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCache.kt @@ -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() // 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 + private val constantsData = PersistentHashMap(File(baseDir, CONSTANTS_MAP), EnumeratorStringDescriptor(), IntInlineKeyDescriptor()) - { - protoData = PersistentHashMap(File(baseDir, PROTO_MAP), object : KeyDescriptor { + ;{ + protoData = PersistentHashMap(File(baseDir, PROTO_MAP), object : KeyDescriptor { 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) { diff --git a/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt b/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt index 6b47071ae27..343e814fa96 100644 --- a/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt +++ b/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt @@ -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 diff --git a/jps-plugin/testData/incremental/constantUnchanged/build.log b/jps-plugin/testData/incremental/constantUnchanged/build.log new file mode 100644 index 00000000000..dad2c9128da --- /dev/null +++ b/jps-plugin/testData/incremental/constantUnchanged/build.log @@ -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 diff --git a/jps-plugin/testData/incremental/constantUnchanged/const.kt b/jps-plugin/testData/incremental/constantUnchanged/const.kt new file mode 100644 index 00000000000..1572968f89f --- /dev/null +++ b/jps-plugin/testData/incremental/constantUnchanged/const.kt @@ -0,0 +1,3 @@ +package test + +val CONST = "foo" diff --git a/jps-plugin/testData/incremental/constantUnchanged/const.kt.new b/jps-plugin/testData/incremental/constantUnchanged/const.kt.new new file mode 100644 index 00000000000..1572968f89f --- /dev/null +++ b/jps-plugin/testData/incremental/constantUnchanged/const.kt.new @@ -0,0 +1,3 @@ +package test + +val CONST = "foo" diff --git a/jps-plugin/testData/incremental/constantUnchanged/usage.kt b/jps-plugin/testData/incremental/constantUnchanged/usage.kt new file mode 100644 index 00000000000..cb0f4ce8687 --- /dev/null +++ b/jps-plugin/testData/incremental/constantUnchanged/usage.kt @@ -0,0 +1,4 @@ +package test + +deprecated(CONST + CONST) +class Usage diff --git a/jps-plugin/testData/incremental/constantValue/build.log b/jps-plugin/testData/incremental/constantValue/build.log new file mode 100644 index 00000000000..dbdb31fbbf0 --- /dev/null +++ b/jps-plugin/testData/incremental/constantValue/build.log @@ -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 diff --git a/jps-plugin/testData/incremental/constantValue/const.kt b/jps-plugin/testData/incremental/constantValue/const.kt new file mode 100644 index 00000000000..1572968f89f --- /dev/null +++ b/jps-plugin/testData/incremental/constantValue/const.kt @@ -0,0 +1,3 @@ +package test + +val CONST = "foo" diff --git a/jps-plugin/testData/incremental/constantValue/const.kt.new b/jps-plugin/testData/incremental/constantValue/const.kt.new new file mode 100644 index 00000000000..c94f1955d6d --- /dev/null +++ b/jps-plugin/testData/incremental/constantValue/const.kt.new @@ -0,0 +1,3 @@ +package test + +val CONST = "bar" diff --git a/jps-plugin/testData/incremental/constantValue/usage.kt b/jps-plugin/testData/incremental/constantValue/usage.kt new file mode 100644 index 00000000000..cb0f4ce8687 --- /dev/null +++ b/jps-plugin/testData/incremental/constantValue/usage.kt @@ -0,0 +1,4 @@ +package test + +deprecated(CONST + CONST) +class Usage