Store computed library kind for jar in a file attribute
It should help to avoid visiting children of each jar in java projects LibraryEffectiveKindProviderImpl has it's own in-memory cache but it doesn't help when project is reopened #KT-25129 Fixed #KT-25034 Fixed
This commit is contained in:
@@ -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<VirtualFile>): 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<VirtualFile>): PersistentLibraryKind<*>? {
|
||||
}
|
||||
}
|
||||
|
||||
private fun detectLibraryKindFromJarContents(jarRoot: VirtualFile): PersistentLibraryKind<*>? {
|
||||
var result: PersistentLibraryKind<*>? = null
|
||||
VfsUtil.visitChildrenRecursively(jarRoot, object : VirtualFileVisitor<PersistentLibraryKind<*>>() {
|
||||
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<VirtualFile>, jarPattern: Pattern): VirtualFile? {
|
||||
return roots.firstOrNull { jarPattern.matcher(it.name).matches() }
|
||||
}
|
||||
|
||||
+65
@@ -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<Unit>() {
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user