diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt index be4c3f432d1..543c3f44ca6 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/framework/LibraryKinds.kt @@ -24,6 +24,8 @@ import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.roots.libraries.PersistentLibraryKind import com.intellij.openapi.util.io.JarUtil import com.intellij.openapi.vfs.* +import org.jetbrains.kotlin.idea.vfilefinder.KnownLibraryKindForIndex +import org.jetbrains.kotlin.idea.vfilefinder.getLibraryKindForJar import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform @@ -59,7 +61,11 @@ fun getLibraryPlatform(project: Project, library: Library): TargetPlatform { fun detectLibraryKind(roots: Array): PersistentLibraryKind<*>? { val jarFile = roots.firstOrNull() ?: return null if (jarFile.fileSystem is JarFileSystem) { - return detectLibraryKindFromJarContents(jarFile) + return when (jarFile.getLibraryKindForJar()) { + KnownLibraryKindForIndex.COMMON -> CommonLibraryKind + KnownLibraryKindForIndex.JS -> JSLibraryKind + KnownLibraryKindForIndex.UNKNOWN -> null + } } return when (jarFile.extension) { @@ -69,29 +75,6 @@ fun detectLibraryKind(roots: Array): PersistentLibraryKind<*>? { } } -private fun detectLibraryKindFromJarContents(jarRoot: VirtualFile): PersistentLibraryKind<*>? { - var result: PersistentLibraryKind<*>? = null - VfsUtil.visitChildrenRecursively(jarRoot, object : VirtualFileVisitor>() { - override fun visitFile(file: VirtualFile): Boolean = - when (file.extension) { - "class" -> false - - "kjsm" -> { - result = JSLibraryKind - false - } - - MetadataPackageFragment.METADATA_FILE_EXTENSION -> { - result = CommonLibraryKind - false - } - - else -> true - } - }) - return result -} - fun getLibraryJar(roots: Array, jarPattern: Pattern): VirtualFile? { return roots.firstOrNull { jarPattern.matcher(it.name).matches() } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/vfilefinder/KotlinLibraryKindIndex.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/vfilefinder/KotlinLibraryKindIndex.kt new file mode 100644 index 00000000000..6d0d8821ddd --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/vfilefinder/KotlinLibraryKindIndex.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.vfilefinder + +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileVisitor +import com.intellij.openapi.vfs.VirtualFileWithId +import com.intellij.psi.search.EverythingGlobalScope +import com.intellij.util.indexing.* +import com.intellij.util.io.DataExternalizer +import com.intellij.util.io.EnumDataDescriptor +import org.jetbrains.kotlin.idea.caches.FileAttributeService +import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragment + +enum class KnownLibraryKindForIndex { + COMMON, JS, UNKNOWN +} + +private val KOTLIN_LIBRARY_KIND_FILE_ATTRIBUTE: String = "kotlin-library-kind".apply { + ServiceManager.getService(FileAttributeService::class.java)?.register(this, 1) +} + +fun VirtualFile.getLibraryKindForJar(): KnownLibraryKindForIndex { + if (this !is VirtualFileWithId) return detectLibraryKindFromJarContentsForIndex(this) + + val service = + ServiceManager.getService(FileAttributeService::class.java) + ?: return detectLibraryKindFromJarContentsForIndex(this) + + service + .readEnumAttribute(KOTLIN_LIBRARY_KIND_FILE_ATTRIBUTE, this, KnownLibraryKindForIndex::class.java) + ?.let { return it.value } + + return detectLibraryKindFromJarContentsForIndex(this).also { newValue -> + service.writeEnumAttribute(KOTLIN_LIBRARY_KIND_FILE_ATTRIBUTE, this, newValue) + } +} + +private fun detectLibraryKindFromJarContentsForIndex(jarRoot: VirtualFile): KnownLibraryKindForIndex { + var result: KnownLibraryKindForIndex? = null + VfsUtil.visitChildrenRecursively(jarRoot, object : VirtualFileVisitor() { + override fun visitFile(file: VirtualFile): Boolean = + when (file.extension) { + "class" -> false + + "kjsm" -> { + result = KnownLibraryKindForIndex.JS + false + } + + MetadataPackageFragment.METADATA_FILE_EXTENSION -> { + result = KnownLibraryKindForIndex.COMMON + false + } + + else -> true + } + }) + return result ?: KnownLibraryKindForIndex.UNKNOWN +}