Optimize library kind detection and make it interruptible
This commit is contained in:
@@ -32,6 +32,7 @@ import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.caches.resolve.LibraryModuleInfo
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryDetectionUtil
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected
|
||||
@@ -210,7 +211,7 @@ class LibraryInfo(val project: Project, val library: Library) : IdeaModuleInfo,
|
||||
}
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = TargetPlatformDetector.getPlatform(library)
|
||||
get() = CommonLibraryDetectionUtil.getLibraryPlatform(library)
|
||||
|
||||
override val sourcesModuleInfo: SourceForBinaryModuleInfo
|
||||
get() = LibrarySourceInfo(project, library)
|
||||
|
||||
+3
-3
@@ -30,7 +30,7 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.idea.core.util.CachedValue
|
||||
import org.jetbrains.kotlin.idea.core.util.getValue
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryDetectionUtil
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
@@ -72,7 +72,7 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
||||
val libraries = LinkedHashSet<Library>()
|
||||
val sdks = LinkedHashSet<Sdk>()
|
||||
|
||||
val platform = TargetPlatformDetector.getPlatform(library)
|
||||
val platform = CommonLibraryDetectionUtil.getLibraryPlatform(library)
|
||||
|
||||
for (module in getLibraryUsageIndex().modulesLibraryIsUsedIn[library]) {
|
||||
if (!processedModules.add(module)) continue
|
||||
@@ -84,7 +84,7 @@ class LibraryDependenciesCacheImpl(private val project: Project) : LibraryDepend
|
||||
|
||||
override fun visitLibraryOrderEntry(libraryOrderEntry: LibraryOrderEntry, value: Unit) {
|
||||
val otherLibrary = libraryOrderEntry.library
|
||||
if (otherLibrary != null && compatiblePlatforms(platform, TargetPlatformDetector.getPlatform(otherLibrary))) {
|
||||
if (otherLibrary != null && compatiblePlatforms(platform, CommonLibraryDetectionUtil.getLibraryPlatform(otherLibrary))) {
|
||||
libraries.add(otherLibrary)
|
||||
}
|
||||
}
|
||||
|
||||
+29
-8
@@ -16,31 +16,52 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.framework
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.caches.JarUserDataManager
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragment
|
||||
|
||||
object CommonLibraryDetectionUtil {
|
||||
@JvmStatic
|
||||
fun isCommonLibrary(library: Library): Boolean {
|
||||
if (library is LibraryEx && library.isDisposed) return false
|
||||
fun getLibraryPlatform(library: Library): TargetPlatform {
|
||||
if (library is LibraryEx && library.isDisposed) return JvmPlatform
|
||||
|
||||
for (root in library.getFiles(OrderRootType.CLASSES)) {
|
||||
val hasMetadata = JarUserDataManager.hasFileWithProperty(HasCommonKotlinMetadataInJar, root)
|
||||
if (hasMetadata != null) {
|
||||
return hasMetadata
|
||||
ProgressManager.checkCanceled()
|
||||
val jarRoot = JarFileSystem.getInstance().getVirtualFileForJar(root) ?: root
|
||||
val hasCommonMetadata = JarUserDataManager.hasFileWithProperty(HasCommonKotlinMetadataInJar, jarRoot)
|
||||
if (hasCommonMetadata == true) {
|
||||
return TargetPlatform.Default
|
||||
}
|
||||
val hasJSMetadata = JarUserDataManager.hasFileWithProperty(KotlinJavaScriptLibraryDetectionUtil.HasKotlinJSMetadataInJar, root)
|
||||
if (hasJSMetadata == true) {
|
||||
return JsPlatform
|
||||
}
|
||||
|
||||
if (!VfsUtilCore.processFilesRecursively(root) { !isKotlinMetadataFile(it) }) {
|
||||
return true
|
||||
var platform: TargetPlatform? = null
|
||||
VfsUtilCore.processFilesRecursively(root) { file ->
|
||||
if (file.fileType == JavaClassFileType.INSTANCE)
|
||||
platform = JvmPlatform
|
||||
else if (isKotlinMetadataFile(file))
|
||||
platform = TargetPlatform.Default
|
||||
else if (KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file))
|
||||
platform = JsPlatform
|
||||
|
||||
platform == null
|
||||
}
|
||||
platform?.let { return it }
|
||||
}
|
||||
|
||||
return false
|
||||
return JvmPlatform
|
||||
}
|
||||
|
||||
private fun isKotlinMetadataFile(file: VirtualFile): Boolean =
|
||||
|
||||
+4
-2
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.framework
|
||||
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
@@ -36,9 +37,10 @@ object KotlinJavaScriptLibraryDetectionUtil {
|
||||
|
||||
@JvmStatic fun isKotlinJavaScriptLibrary(classesRoots: List<VirtualFile>): Boolean {
|
||||
// Prevent clashing with java runtime
|
||||
if (JavaRuntimeDetectionUtil.getJavaRuntimeVersion(classesRoots) != null) return false
|
||||
if (JavaRuntimeDetectionUtil.getRuntimeJar(classesRoots) != null) return false
|
||||
|
||||
classesRoots.forEach { root ->
|
||||
ProgressManager.checkCanceled()
|
||||
val hasMetadata = HasKotlinJSMetadataInJar.hasMetadataFromCache(root)
|
||||
if (hasMetadata != null) {
|
||||
return hasMetadata
|
||||
@@ -52,7 +54,7 @@ object KotlinJavaScriptLibraryDetectionUtil {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isJsFileWithMetadata(file: VirtualFile): Boolean {
|
||||
fun isJsFileWithMetadata(file: VirtualFile): Boolean {
|
||||
if (!file.isDirectory && JavaScript.EXTENSION == file.extension) {
|
||||
val content = try {
|
||||
file.contentsToByteArray(false)
|
||||
|
||||
@@ -19,14 +19,10 @@ package org.jetbrains.kotlin.idea.project;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryDetectionUtil;
|
||||
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil;
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform;
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactoryKt;
|
||||
@@ -75,14 +71,4 @@ public class TargetPlatformDetector {
|
||||
return ProjectStructureUtil.getCachedPlatformForModule(module);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TargetPlatform getPlatform(@NotNull Library library) {
|
||||
if (KotlinJavaScriptLibraryDetectionUtil.isKotlinJavaScriptLibrary(library)) {
|
||||
return JsPlatform.INSTANCE;
|
||||
}
|
||||
if (CommonLibraryDetectionUtil.isCommonLibrary(library)) {
|
||||
return TargetPlatform.Default.INSTANCE;
|
||||
}
|
||||
return JvmPlatform.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user