Avoid multiple subsequent reading of the same class-file in front-end
^KT-23466 Fixed
This commit is contained in:
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.load.java
|
||||
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaPackageImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
@@ -33,10 +32,10 @@ class JavaClassFinderImpl : AbstractJavaClassFinder() {
|
||||
super.initialize(trace, codeAnalyzer)
|
||||
}
|
||||
|
||||
override fun findClass(classId: ClassId): JavaClass? = javaFacade.findClass(classId, javaSearchScope)
|
||||
override fun findClass(request: JavaClassFinder.Request): JavaClass? = javaFacade.findClass(request, javaSearchScope)
|
||||
|
||||
override fun findPackage(fqName: FqName) = javaFacade.findPackage(fqName.asString(), javaSearchScope)?.let { JavaPackageImpl(it, javaSearchScope) }
|
||||
|
||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String>? = javaFacade.knownClassNamesInPackage(packageFqName)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -201,11 +201,16 @@ class BinaryJavaClass(
|
||||
override fun visitAnnotation(desc: String, visible: Boolean) =
|
||||
BinaryJavaAnnotation.addAnnotation(annotations, desc, context, signatureParser)
|
||||
|
||||
override fun findInnerClass(name: Name): JavaClass? {
|
||||
override fun findInnerClass(name: Name): JavaClass? = findInnerClass(name, classFileContent = null)
|
||||
|
||||
fun findInnerClass(name: Name, classFileContent: ByteArray?): JavaClass? {
|
||||
val access = ownInnerClassNameToAccess[name] ?: return null
|
||||
|
||||
return virtualFile.parent.findChild("${virtualFile.nameWithoutExtension}$$name.class")?.let {
|
||||
BinaryJavaClass(it, fqName.child(name), context.copyForMember(), signatureParser, access, this)
|
||||
BinaryJavaClass(
|
||||
it, fqName.child(name), context.copyForMember(), signatureParser, access, this,
|
||||
classFileContent
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-6
@@ -28,14 +28,17 @@ class KotlinBinaryClassCache : Disposable {
|
||||
private class RequestCache {
|
||||
internal var virtualFile: VirtualFile? = null
|
||||
internal var modificationStamp: Long = 0
|
||||
internal var virtualFileKotlinClass: VirtualFileKotlinClass? = null
|
||||
internal var result: KotlinClassFinder.Result? = null
|
||||
|
||||
fun cache(file: VirtualFile, aClass: VirtualFileKotlinClass?): VirtualFileKotlinClass? {
|
||||
fun cache(
|
||||
file: VirtualFile,
|
||||
result: KotlinClassFinder.Result?
|
||||
): KotlinClassFinder.Result? {
|
||||
virtualFile = file
|
||||
virtualFileKotlinClass = aClass
|
||||
this.result = result
|
||||
modificationStamp = file.modificationStamp
|
||||
|
||||
return aClass
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +56,9 @@ class KotlinBinaryClassCache : Disposable {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getKotlinBinaryClass(file: VirtualFile, fileContent: ByteArray? = null): KotlinJvmBinaryClass? {
|
||||
fun getKotlinBinaryClassOrClassFileContent(
|
||||
file: VirtualFile, fileContent: ByteArray? = null
|
||||
): KotlinClassFinder.Result? {
|
||||
if (file.fileType !== JavaClassFileType.INSTANCE) return null
|
||||
|
||||
if (file.name == PsiJavaModule.MODULE_INFO_CLS_FILE) return null
|
||||
@@ -62,7 +67,7 @@ class KotlinBinaryClassCache : Disposable {
|
||||
val requestCache = service.cache.get()
|
||||
|
||||
if (file.modificationStamp == requestCache.modificationStamp && file == requestCache.virtualFile) {
|
||||
return requestCache.virtualFileKotlinClass
|
||||
return requestCache.result
|
||||
}
|
||||
|
||||
val aClass = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
|
||||
+11
-6
@@ -27,14 +27,17 @@ class KotlinBinaryClassCache : Disposable {
|
||||
private class RequestCache {
|
||||
internal var virtualFile: VirtualFile? = null
|
||||
internal var modificationStamp: Long = 0
|
||||
internal var virtualFileKotlinClass: VirtualFileKotlinClass? = null
|
||||
internal var result: KotlinClassFinder.Result? = null
|
||||
|
||||
fun cache(file: VirtualFile, aClass: VirtualFileKotlinClass?): VirtualFileKotlinClass? {
|
||||
fun cache(
|
||||
file: VirtualFile,
|
||||
result: KotlinClassFinder.Result?
|
||||
): KotlinClassFinder.Result? {
|
||||
virtualFile = file
|
||||
virtualFileKotlinClass = aClass
|
||||
this.result = result
|
||||
modificationStamp = file.modificationStamp
|
||||
|
||||
return aClass
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,14 +55,16 @@ class KotlinBinaryClassCache : Disposable {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getKotlinBinaryClass(file: VirtualFile, fileContent: ByteArray? = null): KotlinJvmBinaryClass? {
|
||||
fun getKotlinBinaryClassOrClassFileContent(
|
||||
file: VirtualFile, fileContent: ByteArray? = null
|
||||
): KotlinClassFinder.Result? {
|
||||
if (file.fileType !== JavaClassFileType.INSTANCE) return null
|
||||
|
||||
val service = ServiceManager.getService(KotlinBinaryClassCache::class.java)
|
||||
val requestCache = service.cache.get()
|
||||
|
||||
if (file.modificationStamp == requestCache.modificationStamp && file == requestCache.virtualFile) {
|
||||
return requestCache.virtualFileKotlinClass
|
||||
return requestCache.result
|
||||
}
|
||||
|
||||
val aClass = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
|
||||
+11
-6
@@ -27,14 +27,17 @@ class KotlinBinaryClassCache : Disposable {
|
||||
private class RequestCache {
|
||||
internal var virtualFile: VirtualFile? = null
|
||||
internal var modificationStamp: Long = 0
|
||||
internal var virtualFileKotlinClass: VirtualFileKotlinClass? = null
|
||||
internal var result: KotlinClassFinder.Result? = null
|
||||
|
||||
fun cache(file: VirtualFile, aClass: VirtualFileKotlinClass?): VirtualFileKotlinClass? {
|
||||
fun cache(
|
||||
file: VirtualFile,
|
||||
result: KotlinClassFinder.Result?
|
||||
): KotlinClassFinder.Result? {
|
||||
virtualFile = file
|
||||
virtualFileKotlinClass = aClass
|
||||
this.result = result
|
||||
modificationStamp = file.modificationStamp
|
||||
|
||||
return aClass
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,14 +55,16 @@ class KotlinBinaryClassCache : Disposable {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getKotlinBinaryClass(file: VirtualFile, fileContent: ByteArray? = null): KotlinJvmBinaryClass? {
|
||||
fun getKotlinBinaryClassOrClassFileContent(
|
||||
file: VirtualFile, fileContent: ByteArray? = null
|
||||
): KotlinClassFinder.Result? {
|
||||
if (file.fileType !== JavaClassFileType.INSTANCE) return null
|
||||
|
||||
val service = ServiceManager.getService(KotlinBinaryClassCache::class.java)
|
||||
val requestCache = service.cache.get()
|
||||
|
||||
if (file.modificationStamp == requestCache.modificationStamp && file == requestCache.virtualFile) {
|
||||
return requestCache.virtualFileKotlinClass
|
||||
return requestCache.result
|
||||
}
|
||||
|
||||
val aClass = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
|
||||
@@ -27,12 +27,12 @@ import org.jetbrains.kotlin.utils.sure
|
||||
abstract class VirtualFileFinder : KotlinClassFinder {
|
||||
abstract fun findVirtualFileWithHeader(classId: ClassId): VirtualFile?
|
||||
|
||||
override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? {
|
||||
override fun findKotlinClassOrContent(classId: ClassId): KotlinClassFinder.Result? {
|
||||
val file = findVirtualFileWithHeader(classId) ?: return null
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClass(file)
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClassOrClassFileContent(file)
|
||||
}
|
||||
|
||||
override fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? {
|
||||
override fun findKotlinClassOrContent(javaClass: JavaClass): KotlinClassFinder.Result? {
|
||||
var file = (javaClass as? VirtualFileBoundJavaClass)?.virtualFile ?: return null
|
||||
|
||||
if (javaClass.outerClass != null) {
|
||||
@@ -41,7 +41,7 @@ abstract class VirtualFileFinder : KotlinClassFinder {
|
||||
file = file.parent!!.findChild(classFileName(javaClass) + ".class").sure { "Virtual file not found for $javaClass" }
|
||||
}
|
||||
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClass(file)
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClassOrClassFileContent(file)
|
||||
}
|
||||
|
||||
private fun classFileName(jClass: JavaClass): String {
|
||||
|
||||
+6
-3
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.kotlin
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder.Result.KotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||
@@ -56,17 +57,19 @@ class VirtualFileKotlinClass private constructor(
|
||||
private val perfCounter = PerformanceCounter.create("Binary class from Kotlin file")
|
||||
|
||||
@Deprecated("Use KotlinBinaryClassCache")
|
||||
fun create(file: VirtualFile, fileContent: ByteArray?): VirtualFileKotlinClass? {
|
||||
fun create(file: VirtualFile, fileContent: ByteArray?): KotlinClassFinder.Result? {
|
||||
return perfCounter.time {
|
||||
assert(file.fileType == JavaClassFileType.INSTANCE) { "Trying to read binary data from a non-class file $file" }
|
||||
|
||||
try {
|
||||
val byteContent = fileContent ?: file.contentsToByteArray(false)
|
||||
if (!byteContent.isEmpty()) {
|
||||
return@time FileBasedKotlinClass.create(byteContent) {
|
||||
name, classVersion, header, innerClasses ->
|
||||
val kotlinJvmBinaryClass = FileBasedKotlinClass.create(byteContent) { name, classVersion, header, innerClasses ->
|
||||
VirtualFileKotlinClass(file, name, classVersion, header, innerClasses)
|
||||
}
|
||||
|
||||
return@time kotlinJvmBinaryClass?.let(::KotlinClass)
|
||||
?: KotlinClassFinder.Result.ClassFileContent(byteContent)
|
||||
}
|
||||
}
|
||||
catch (e: FileNotFoundException) {
|
||||
|
||||
+2
-2
@@ -18,11 +18,11 @@ package org.jetbrains.kotlin.resolve.jvm
|
||||
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
interface KotlinCliJavaFileManager : JavaFileManager {
|
||||
fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass?
|
||||
fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass?
|
||||
fun knownClassNamesInPackage(packageFqName: FqName): Set<String>?
|
||||
}
|
||||
|
||||
+6
-4
@@ -43,6 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder;
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass;
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl;
|
||||
@@ -104,9 +105,10 @@ public class KotlinJavaPsiFacade {
|
||||
return emptyModifierList;
|
||||
}
|
||||
|
||||
public JavaClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) {
|
||||
public JavaClass findClass(@NotNull JavaClassFinder.Request request, @NotNull GlobalSearchScope scope) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
|
||||
|
||||
ClassId classId = request.getClassId();
|
||||
String qualifiedName = classId.asSingleFqName().asString();
|
||||
|
||||
if (shouldUseSlowResolve()) {
|
||||
@@ -119,7 +121,7 @@ public class KotlinJavaPsiFacade {
|
||||
|
||||
for (KotlinPsiElementFinderWrapper finder : finders()) {
|
||||
if (finder instanceof CliFinder) {
|
||||
JavaClass aClass = ((CliFinder) finder).findClass(classId, scope);
|
||||
JavaClass aClass = ((CliFinder) finder).findClass(request, scope);
|
||||
if (aClass != null) return aClass;
|
||||
}
|
||||
else {
|
||||
@@ -383,8 +385,8 @@ public class KotlinJavaPsiFacade {
|
||||
return javaFileManager.findClass(qualifiedName, scope);
|
||||
}
|
||||
|
||||
public JavaClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) {
|
||||
return javaFileManager.findClass(classId, scope);
|
||||
public JavaClass findClass(@NotNull JavaClassFinder.Request request, @NotNull GlobalSearchScope scope) {
|
||||
return javaFileManager.findClass(request, scope);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user