From ee36de9602dd1c108d9556454c8b26c397416ce3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 19 Aug 2015 17:21:13 +0300 Subject: [PATCH] Simplify jar-processor framework --- .../kotlin/idea/caches/JarUserDataManager.kt | 77 ++++++++++--------- .../kotlin/idea/decompiler/DecompiledUtils.kt | 25 ++---- .../KotlinJavaScriptLibraryDetectionUtil.kt | 32 ++------ 3 files changed, 50 insertions(+), 84 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt index 5ce5bce9975..b782e56dc78 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/JarUserDataManager.kt @@ -24,32 +24,42 @@ import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.util.application.runReadAction public object JarUserDataManager { - val fileAttributeService: FileAttributeService? = ServiceManager.getService(javaClass()) - - public fun register(collector: JarUserDataCollector<*>) { - fileAttributeService?.register(collector.key.toString(), collector.version) + enum class State { + INIT, + HAS_FILE, + NO_FILE } - public fun > getValue(collector: JarUserDataCollector, file: VirtualFile): T? { + val version = 1 + + val fileAttributeService: FileAttributeService? = ServiceManager.getService(javaClass()) + + public fun register(counter: JarBooleanPropertyCounter) { + fileAttributeService?.register(counter.key.toString(), version) + } + + public fun hasFileWithProperty(counter: JarBooleanPropertyCounter, file: VirtualFile): Boolean? { val jarFile = findJarRoot(file) ?: return null - val stored = jarFile.getUserData(collector.key) - if (stored != null && jarFile.timeStamp == stored.second) { - return stored.first + val stored = jarFile.getUserData(counter.key) + if (stored != null && jarFile.timeStamp == stored.timestamp) { + return stored.hasFileWithProperty } if (stored == null && fileAttributeService != null) { - val savedData = fileAttributeService.readAttribute(collector.key.toString(), jarFile, collector.stateClass) + val savedData = fileAttributeService.readAttribute(counter.key.toString(), jarFile, javaClass()) if (savedData != null && savedData.value != null) { - jarFile.putUserData(collector.key, savedData.value to savedData.timeStamp) + val hasFileWithProperty = savedData.value == State.HAS_FILE + + jarFile.putUserData(counter.key, PropertyData(hasFileWithProperty, savedData.timeStamp)) if (jarFile.timeStamp == savedData.timeStamp) { - return savedData.value + return hasFileWithProperty } } } - scheduleJarProcessing(collector, jarFile) + scheduleJarProcessing(counter, jarFile) return null } @@ -63,44 +73,35 @@ public object JarUserDataManager { return jarFile } - private fun > scheduleJarProcessing(collector: JarUserDataCollector, jarFile: VirtualFile) { - if (jarFile.getUserData(collector.key) != null) return + private fun scheduleJarProcessing(counter: JarBooleanPropertyCounter, jarFile: VirtualFile) { + if (jarFile.getUserData(counter.key) != null) return - jarFile.putUserData(collector.key, collector.init to jarFile.timeStamp) + jarFile.putUserData(counter.key, PropertyData(null, jarFile.timeStamp)) ApplicationManager.getApplication().executeOnPooledThread { runReadAction { - var result = collector.notFoundState - - VfsUtilCore.processFilesRecursively(jarFile) { file -> - if (collector.process(file) == collector.stopState) { - result = collector.stopState - - // stop processing - false - } - else { - // continue processing - true - } + val hasFileWithProperty = !VfsUtilCore.processFilesRecursively(jarFile) { file -> + !counter.hasProperty(file) } - val savedData = fileAttributeService?.writeAttribute(collector.key.toString(), jarFile, result) - jarFile.putUserData(collector.key, result to (savedData?.timeStamp ?: jarFile.timeStamp)) + val state = if (hasFileWithProperty) State.HAS_FILE else State.NO_FILE + + val savedData = fileAttributeService?.writeAttribute(counter.key.toString(), jarFile, state) + + jarFile.putUserData( + counter.key, + PropertyData(hasFileWithProperty, (savedData?.timeStamp ?: jarFile.timeStamp))) } } } - interface JarUserDataCollector> { - val key: Key> - val stateClass: Class + data class PropertyData(val hasFileWithProperty: Boolean?, val timestamp: Long) - val version: Int get() = 1 + abstract class JarBooleanPropertyCounter(keyName: String) { + val key: Key = Key.create(keyName) - val init: State - val stopState: State - val notFoundState: State + abstract fun hasProperty(file: VirtualFile): Boolean - fun process(file: VirtualFile): State + override fun toString() = "Counter: $key" } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt index 4c7f25932c4..e58e2ec98ab 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt @@ -17,14 +17,9 @@ package org.jetbrains.kotlin.idea.decompiler import com.intellij.ide.highlighter.JavaClassFileType -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.impl.FilePropertyPusher import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.VirtualFile -import com.intellij.pom.java.LanguageLevel import com.intellij.psi.ClassFileViewProvider -import com.intellij.util.messages.MessageBus import org.jetbrains.kotlin.idea.caches.JarUserDataManager import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass @@ -39,7 +34,7 @@ public fun isKotlinJvmCompiledFile(file: VirtualFile): Boolean { return false } - if (JarUserDataManager.getValue(HasCompiledKotlinInJar, file) == HasCompiledKotlinInJar.JarKotlinState.NO_KOTLIN) { + if (HasCompiledKotlinInJar.isInNoKotlinJar(file)) { return false } @@ -81,19 +76,9 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { public fun isKotlinJavaScriptInternalCompiledFile(file: VirtualFile): Boolean = isKotlinJsMetaFile(file) && file.getNameWithoutExtension().contains('.') -public object HasCompiledKotlinInJar : JarUserDataManager.JarUserDataCollector { - public enum class JarKotlinState { - HAS_KOTLIN, - NO_KOTLIN, - COUNTING - } +public object HasCompiledKotlinInJar : JarUserDataManager.JarBooleanPropertyCounter(HasCompiledKotlinInJar::class.simpleName!!) { + override fun hasProperty(file: VirtualFile) = isKotlinJvmCompiledFile(file) - override val key = Key.create>(HasCompiledKotlinInJar::class.simpleName!!) - override val stateClass = javaClass() - - override val init = JarKotlinState.COUNTING - override val stopState = JarKotlinState.HAS_KOTLIN - override val notFoundState = JarKotlinState.NO_KOTLIN - - override fun process(file: VirtualFile) = if (isKotlinJvmCompiledFile(file)) JarKotlinState.HAS_KOTLIN else JarKotlinState.NO_KOTLIN + fun isInNoKotlinJar(file: VirtualFile): Boolean = + JarUserDataManager.hasFileWithProperty(HasCompiledKotlinInJar, file) == false } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt index 41eb3ac86b4..2d0ec40d72c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/KotlinJavaScriptLibraryDetectionUtil.kt @@ -38,12 +38,9 @@ public object KotlinJavaScriptLibraryDetectionUtil { if (JavaRuntimeDetectionUtil.getJavaRuntimeVersion(classesRoots) != null) return false classesRoots.forEach { root -> - val cachedResult = JarUserDataManager.getValue(HasKotlinJSMetadataInJar, root) - - @suppress("NON_EXHAUSTIVE_WHEN") - when (cachedResult) { - HasKotlinJSMetadataInJar.JsMetadataState.HAS_JS_METADATA -> return true - HasKotlinJSMetadataInJar.JsMetadataState.NO_JS_METADATA -> return false + val hasMetadata = HasKotlinJSMetadataInJar.hasMetadataFromCache(root) + if (hasMetadata != null) { + return hasMetadata } if (!VfsUtilCore.processFilesRecursively(root, { isJsFileWithMetadata(root) })) { @@ -59,26 +56,9 @@ public object KotlinJavaScriptLibraryDetectionUtil { JavaScript.EXTENSION == file.getExtension() && KotlinJavascriptMetadataUtils.hasMetadata(String(file.contentsToByteArray(false))) - public object HasKotlinJSMetadataInJar : JarUserDataManager.JarUserDataCollector { - public enum class JsMetadataState { - HAS_JS_METADATA, - NO_JS_METADATA, - COUNTING - } + public object HasKotlinJSMetadataInJar : JarUserDataManager.JarBooleanPropertyCounter(HasKotlinJSMetadataInJar::class.simpleName!!) { + override fun hasProperty(file: VirtualFile) = KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file) - override val key = Key.create>(HasKotlinJSMetadataInJar::class.simpleName!!) - override val stateClass = javaClass() - - override val init = JsMetadataState.COUNTING - override val stopState = JsMetadataState.HAS_JS_METADATA - override val notFoundState = JsMetadataState.NO_JS_METADATA - - override fun process(file: VirtualFile): JsMetadataState { - return if (KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file)) { - JsMetadataState.HAS_JS_METADATA - } else { - JsMetadataState.NO_JS_METADATA - } - } + fun hasMetadataFromCache(root: VirtualFile): Boolean? = JarUserDataManager.hasFileWithProperty(HasKotlinJSMetadataInJar, root) } }