diff --git a/.idea/artifacts/KotlinPlugin.xml b/.idea/artifacts/KotlinPlugin.xml
index 9d9f0fe34ac..6ac1e70177d 100644
--- a/.idea/artifacts/KotlinPlugin.xml
+++ b/.idea/artifacts/KotlinPlugin.xml
@@ -44,7 +44,14 @@
+
+
+
+
+
+
+
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
index 2fdc51743d2..056003f3e65 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java
@@ -51,7 +51,7 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
-import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
+import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.plugin.MainFunctionDetector;
import org.jetbrains.jet.utils.KotlinPaths;
@@ -327,10 +327,12 @@ public class KotlinToJVMBytecodeCompiler {
) {
CompilerConfiguration configuration = environment.getConfiguration();
File incrementalCacheDir = configuration.get(JVMConfigurationKeys.INCREMENTAL_CACHE_BASE_DIR);
+ IncrementalCacheProvider incrementalCacheProvider = IncrementalCacheProvider.object$.getInstance();
+
Collection packagesWithRemovedFiles =
- incrementalCacheDir == null || moduleId == null
+ incrementalCacheDir == null || moduleId == null || incrementalCacheProvider == null
? null
- : new IncrementalCache(incrementalCacheDir).getPackagesWithRemovedFiles(moduleId, environment.getSourceFiles());
+ : incrementalCacheProvider.getIncrementalCache(incrementalCacheDir).getPackagesWithRemovedFiles(moduleId, environment.getSourceFiles());
GenerationState generationState = new GenerationState(
environment.getProject(), ClassBuilderFactories.BINARIES, Progress.DEAF,
exhaust.getModuleDescriptor(), exhaust.getBindingContext(), sourceFiles,
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java
index 5bd9b739ea5..ea61a9122f4 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java
@@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
+import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
@@ -145,13 +146,15 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
try {
module.addFragmentProvider(DependencyKind.BINARIES, injector.getJavaDescriptorResolver().getPackageFragmentProvider());
- if (incrementalCacheDir != null && moduleIds != null) {
+ IncrementalCacheProvider incrementalCacheProvider = IncrementalCacheProvider.object$.getInstance();
+ if (incrementalCacheDir != null && moduleIds != null && incrementalCacheProvider != null) {
+ IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(incrementalCacheDir);
for (String moduleId : moduleIds) {
module.addFragmentProvider(
DependencyKind.SOURCES,
new IncrementalPackageFragmentProvider(
files, module, globalContext.getStorageManager(), injector.getDescriptorDeserializers(),
- new IncrementalCache(incrementalCacheDir), moduleId, injector.getJavaDescriptorResolver()
+ incrementalCache, moduleId, injector.getJavaDescriptorResolver()
)
);
}
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 ce28f9699f1..3ebda40fd84 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
@@ -16,205 +16,14 @@
package org.jetbrains.jet.lang.resolve.kotlin.incremental
-import java.io.File
-import com.intellij.util.io.PersistentMap
-import com.intellij.util.io.PersistentHashMap
-import com.intellij.util.io.KeyDescriptor
-import java.io.DataOutput
-import com.intellij.util.io.IOUtil
-import java.io.DataInput
import org.jetbrains.jet.lang.resolve.name.FqName
-import com.intellij.util.io.DataExternalizer
-import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass
-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
-import java.util.HashSet
import org.jetbrains.jet.lang.psi.JetFile
-import java.util.HashMap
-public class IncrementalCache(baseDir: File) {
- class object {
- val PROTO_MAP = "proto.tab"
- val CONSTANTS_MAP = "constants.tab"
- val PACKAGE_SOURCES = "package-sources.tab"
+public trait IncrementalCache {
+ public fun getPackagesWithRemovedFiles(moduleId: String, compiledSourceFiles: Collection): Collection
- private fun getConstantsHash(bytes: ByteArray): Int {
- val result = TreeMap() // keys order should defined to check hash of a map
+ public fun getRemovedPackageParts(moduleId: String, compiledSourceFiles: Collection): Collection
- 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
- = PersistentHashMap(File(baseDir, CONSTANTS_MAP), EnumeratorStringDescriptor(), IntInlineKeyDescriptor())
-
- // Format of serialization to string: -->
- private val packageSourcesData: PersistentHashMap
- = PersistentHashMap(File(baseDir, PACKAGE_SOURCES), EnumeratorStringDescriptor(), EnumeratorStringDescriptor())
-
- ;{
- 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)
- }
-
- override fun read(`in`: DataInput): ClassOrPackageId {
- val module = IOUtil.readString(`in`)!!
- val fqName = FqName(IOUtil.readString(`in`)!!)
- return ClassOrPackageId(module, fqName)
- }
-
- override fun getHashCode(value: ClassOrPackageId?): Int {
- return value?.hashCode() ?: -1
- }
-
- override fun isEqual(val1: ClassOrPackageId?, val2: ClassOrPackageId?): Boolean {
- return val1 == val2
- }
- }, object : DataExternalizer {
- override fun save(out: DataOutput, value: ByteArray?) {
- out.writeInt(value!!.size)
- out.write(value)
- }
-
- override fun read(`in`: DataInput): ByteArray {
- val length = `in`.readInt()
- val buf = ByteArray(length)
- `in`.readFully(buf)
- return buf
- }
- })
- }
-
- public fun saveFileToCache(moduleId: String, sourceFiles: Collection, file: File): Boolean {
- val fileBytes = file.readBytes()
- val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(fileBytes)
- if (classNameAndHeader == null) return false
-
- val (className, header) = classNameAndHeader
- val classFqName = className.getFqNameForClassNameWithoutDollars()
- val annotationDataEncoded = header.annotationData
- if (annotationDataEncoded != null) {
- val data = BitEncoding.decodeBytes(annotationDataEncoded)
- when (header.kind) {
- KotlinClassHeader.Kind.PACKAGE_FACADE -> {
- return putData(moduleId, classFqName.parent(), data)
- }
- KotlinClassHeader.Kind.CLASS -> {
- return putData(moduleId, classFqName, data)
- }
- }
- }
- 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, getConstantsHash(fileBytes))
- }
-
- return false
- }
-
- private fun putData(moduleId: String, fqName: FqName, data: ByteArray): Boolean {
- val id = ClassOrPackageId(moduleId, fqName)
- val oldData = protoData[id]
- if (Arrays.equals(data, oldData)) {
- return false
- }
- protoData.put(id, data)
- 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
- }
-
- private fun putPackagePartSourceData(moduleId: String, sourceFile: File, className: JvmClassName?) {
- val key = moduleId + File.pathSeparator + sourceFile.getAbsolutePath()
-
- if (className != null) {
- packageSourcesData.put(key, className.getInternalName())
- }
- else {
- packageSourcesData.remove(key)
- }
- }
-
- public fun clearPackagePartSourceData(moduleId: String, sourceFile: File) {
- putPackagePartSourceData(moduleId, sourceFile, null)
- }
-
- public fun getPackagesWithRemovedFiles(moduleId: String, compiledSourceFiles: Collection): Collection {
- return getRemovedPackageParts(moduleId, compiledSourceFiles).map { it.getFqNameForClassNameWithoutDollars().parent() }
- }
-
- public fun getRemovedPackageParts(moduleId: String, compiledSourceFiles: Collection): Collection {
- val sourceFileToCurrentFqNameMap = HashMap()
- for (sourceFile in compiledSourceFiles) {
- sourceFileToCurrentFqNameMap[File(sourceFile.getVirtualFile()!!.getPath())] = sourceFile.getPackageFqName()
- }
-
- val result = HashSet()
-
- packageSourcesData.processKeysWithExistingMapping { key ->
- if (key!!.startsWith(moduleId + File.pathSeparator)) {
- val indexOf = key.indexOf(File.pathSeparator)
- val sourceFile = File(key.substring(indexOf + 1))
-
- val packagePartClassName = JvmClassName.byInternalName(packageSourcesData[key]!!)
- if (!sourceFile.exists()) {
- result.add(packagePartClassName)
- }
- else {
- val previousPackageFqName = packagePartClassName.getFqNameForClassNameWithoutDollars().parent()
- val currentPackageFqName = sourceFileToCurrentFqNameMap[sourceFile]
- if (currentPackageFqName != null && currentPackageFqName != previousPackageFqName) {
- result.add(packagePartClassName)
- }
- }
- }
-
- true
- }
-
- return result
- }
-
- public fun getPackageData(moduleId: String, fqName: FqName): ByteArray? {
- return protoData[ClassOrPackageId(moduleId, fqName)]
- }
-
- public fun close() {
- protoData.close()
- constantsData.close()
- packageSourcesData.close()
- }
-
- private data class ClassOrPackageId(val moduleId: String, val fqName: FqName) {
- }
+ public fun getPackageData(moduleId: String, fqName: FqName): ByteArray?
}
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCacheProvider.kt b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCacheProvider.kt
new file mode 100644
index 00000000000..0886ae72eb4
--- /dev/null
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/incremental/IncrementalCacheProvider.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.lang.resolve.kotlin.incremental
+
+import java.io.File
+import java.util.ServiceLoader
+
+public trait IncrementalCacheProvider {
+ public fun getIncrementalCache(baseDir: File): IncrementalCache
+
+ public class object {
+ public fun getInstance(): IncrementalCacheProvider? {
+ val serviceLoader = ServiceLoader.load(javaClass(), javaClass().getClassLoader())
+ val implementations = serviceLoader.toList()
+ if (implementations.size > 1) {
+ throw IllegalStateException("More than one IncrementalCacheProvider: " + implementations)
+ }
+ return implementations.firstOrNull()
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 3b839745ff3..29ac30ed576 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -165,7 +165,7 @@
-
+
diff --git a/jps-plugin/jps-plugin.iml b/jps-plugin/jps-plugin.iml
index a7f222b8c6d..5ccd205933f 100644
--- a/jps-plugin/jps-plugin.iml
+++ b/jps-plugin/jps-plugin.iml
@@ -17,8 +17,8 @@
-
-
+
+
diff --git a/jps-plugin/src/META-INF/services/org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider b/jps-plugin/src/META-INF/services/org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider
new file mode 100644
index 00000000000..eadf409aee9
--- /dev/null
+++ b/jps-plugin/src/META-INF/services/org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider
@@ -0,0 +1 @@
+org.jetbrains.jet.jps.incremental.IncrementalCacheProviderImpl
\ No newline at end of file
diff --git a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java
index 2091b635e95..da5842fa0f1 100644
--- a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java
+++ b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java
@@ -37,7 +37,7 @@ import org.jetbrains.jet.compiler.runner.OutputItemsCollectorImpl;
import org.jetbrains.jet.compiler.runner.SimpleOutputItem;
import org.jetbrains.jet.config.IncrementalCompilation;
import org.jetbrains.jet.jps.JpsKotlinCompilerSettings;
-import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
+import org.jetbrains.jet.jps.incremental.IncrementalCacheImpl;
import org.jetbrains.jet.utils.PathUtil;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.BuildTarget;
@@ -209,7 +209,7 @@ public class KotlinBuilder extends ModuleLevelBuilder {
}
}
- IncrementalCache cache = new IncrementalCache(KotlinBuilderModuleScriptGenerator.getIncrementalCacheDir(context));
+ IncrementalCacheImpl cache = new IncrementalCacheImpl(KotlinBuilderModuleScriptGenerator.getIncrementalCacheDir(context));
try {
for (ModuleBuildTarget target : chunk.getTargets()) {
diff --git a/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt
new file mode 100644
index 00000000000..083e5b46c6c
--- /dev/null
+++ b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2010-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.jps.incremental
+
+import java.io.File
+import com.intellij.util.io.PersistentMap
+import com.intellij.util.io.PersistentHashMap
+import com.intellij.util.io.KeyDescriptor
+import java.io.DataOutput
+import com.intellij.util.io.IOUtil
+import java.io.DataInput
+import org.jetbrains.jet.lang.resolve.name.FqName
+import com.intellij.util.io.DataExternalizer
+import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass
+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
+import java.util.HashSet
+import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache
+
+public class IncrementalCacheImpl(baseDir: File): IncrementalCache {
+ class object {
+ val PROTO_MAP = "proto.tab"
+ val CONSTANTS_MAP = "constants.tab"
+ val PACKAGE_SOURCES = "package-sources.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
+ = PersistentHashMap(File(baseDir, CONSTANTS_MAP), EnumeratorStringDescriptor(), IntInlineKeyDescriptor())
+
+ // Format of serialization to string: -->
+ private val packageSourcesData: PersistentHashMap
+ = PersistentHashMap(File(baseDir, PACKAGE_SOURCES), EnumeratorStringDescriptor(), EnumeratorStringDescriptor())
+
+ ;{
+ 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)
+ }
+
+ override fun read(`in`: DataInput): ClassOrPackageId {
+ val module = IOUtil.readString(`in`)!!
+ val fqName = FqName(IOUtil.readString(`in`)!!)
+ return ClassOrPackageId(module, fqName)
+ }
+
+ override fun getHashCode(value: ClassOrPackageId?): Int {
+ return value?.hashCode() ?: -1
+ }
+
+ override fun isEqual(val1: ClassOrPackageId?, val2: ClassOrPackageId?): Boolean {
+ return val1 == val2
+ }
+ }, object : DataExternalizer {
+ override fun save(out: DataOutput, value: ByteArray?) {
+ out.writeInt(value!!.size)
+ out.write(value)
+ }
+
+ override fun read(`in`: DataInput): ByteArray {
+ val length = `in`.readInt()
+ val buf = ByteArray(length)
+ `in`.readFully(buf)
+ return buf
+ }
+ })
+ }
+
+ public fun saveFileToCache(moduleId: String, sourceFiles: Collection, file: File): Boolean {
+ val fileBytes = file.readBytes()
+ val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(fileBytes)
+ if (classNameAndHeader == null) return false
+
+ val (className, header) = classNameAndHeader
+ val classFqName = className.getFqNameForClassNameWithoutDollars()
+ val annotationDataEncoded = header.annotationData
+ if (annotationDataEncoded != null) {
+ val data = BitEncoding.decodeBytes(annotationDataEncoded)
+ when (header.kind) {
+ KotlinClassHeader.Kind.PACKAGE_FACADE -> {
+ return putData(moduleId, classFqName.parent(), data)
+ }
+ KotlinClassHeader.Kind.CLASS -> {
+ return putData(moduleId, classFqName, data)
+ }
+ }
+ }
+ 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, getConstantsHash(fileBytes))
+ }
+
+ return false
+ }
+
+ private fun putData(moduleId: String, fqName: FqName, data: ByteArray): Boolean {
+ val id = ClassOrPackageId(moduleId, fqName)
+ val oldData = protoData[id]
+ if (Arrays.equals(data, oldData)) {
+ return false
+ }
+ protoData.put(id, data)
+ 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
+ }
+
+ private fun putPackagePartSourceData(moduleId: String, sourceFile: File, className: JvmClassName?) {
+ val key = moduleId + File.pathSeparator + sourceFile.getAbsolutePath()
+
+ if (className != null) {
+ packageSourcesData.put(key, className.getInternalName())
+ }
+ else {
+ packageSourcesData.remove(key)
+ }
+ }
+
+ public fun clearPackagePartSourceData(moduleId: String, sourceFile: File) {
+ putPackagePartSourceData(moduleId, sourceFile, null)
+ }
+
+ public override fun getPackagesWithRemovedFiles(moduleId: String, compiledSourceFiles: Collection): Collection {
+ return getRemovedPackageParts(moduleId, compiledSourceFiles).map { it.getFqNameForClassNameWithoutDollars().parent() }
+ }
+
+ public override fun getRemovedPackageParts(moduleId: String, compiledSourceFiles: Collection): Collection {
+ val sourceFileToCurrentFqNameMap = HashMap()
+ for (sourceFile in compiledSourceFiles) {
+ sourceFileToCurrentFqNameMap[File(sourceFile.getVirtualFile()!!.getPath())] = sourceFile.getPackageFqName()
+ }
+
+ val result = HashSet()
+
+ packageSourcesData.processKeysWithExistingMapping { key ->
+ if (key!!.startsWith(moduleId + File.pathSeparator)) {
+ val indexOf = key.indexOf(File.pathSeparator)
+ val sourceFile = File(key.substring(indexOf + 1))
+
+ val packagePartClassName = JvmClassName.byInternalName(packageSourcesData[key]!!)
+ if (!sourceFile.exists()) {
+ result.add(packagePartClassName)
+ }
+ else {
+ val previousPackageFqName = packagePartClassName.getFqNameForClassNameWithoutDollars().parent()
+ val currentPackageFqName = sourceFileToCurrentFqNameMap[sourceFile]
+ if (currentPackageFqName != null && currentPackageFqName != previousPackageFqName) {
+ result.add(packagePartClassName)
+ }
+ }
+ }
+
+ true
+ }
+
+ return result
+ }
+
+ public override fun getPackageData(moduleId: String, fqName: FqName): ByteArray? {
+ return protoData[ClassOrPackageId(moduleId, fqName)]
+ }
+
+ public fun close() {
+ protoData.close()
+ constantsData.close()
+ packageSourcesData.close()
+ }
+
+ private data class ClassOrPackageId(val moduleId: String, val fqName: FqName) {
+ }
+}
\ No newline at end of file
diff --git a/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementlaCacheProviderImpl.kt b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementlaCacheProviderImpl.kt
new file mode 100644
index 00000000000..5b94b207b71
--- /dev/null
+++ b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementlaCacheProviderImpl.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.jps.incremental
+
+import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider
+import java.io.File
+import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache
+
+public class IncrementalCacheProviderImpl: IncrementalCacheProvider {
+ override fun getIncrementalCache(baseDir: File): IncrementalCache {
+ return IncrementalCacheImpl(baseDir)
+ }
+}
\ No newline at end of file