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.roots.libraries.PersistentLibraryKind
|
||||||
import com.intellij.openapi.util.io.JarUtil
|
import com.intellij.openapi.util.io.JarUtil
|
||||||
import com.intellij.openapi.vfs.*
|
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.js.resolve.JsPlatform
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
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<*>? {
|
fun detectLibraryKind(roots: Array<VirtualFile>): PersistentLibraryKind<*>? {
|
||||||
val jarFile = roots.firstOrNull() ?: return null
|
val jarFile = roots.firstOrNull() ?: return null
|
||||||
if (jarFile.fileSystem is JarFileSystem) {
|
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) {
|
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? {
|
fun getLibraryJar(roots: Array<VirtualFile>, jarPattern: Pattern): VirtualFile? {
|
||||||
return roots.firstOrNull { jarPattern.matcher(it.name).matches() }
|
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