Avoid another case of reading file content when building stubs

Do not read file content in isKotlinInternalCompiledFile() if possible
This commit is contained in:
Dmitry Jemerov
2017-04-18 18:02:10 +02:00
parent 83169ad781
commit f801c5f3f8
4 changed files with 21 additions and 12 deletions
@@ -32,7 +32,7 @@ object IDEKotlinBinaryClassCache {
/**
* Checks if this file is a compiled Kotlin class file (not necessarily ABI-compatible with the current plugin)
*/
fun isKotlinJvmCompiledFile(file: VirtualFile): Boolean {
fun isKotlinJvmCompiledFile(file: VirtualFile, fileContent: ByteArray? = null): Boolean {
if (file.extension != JavaClassFileType.INSTANCE!!.defaultExtension) {
return false
}
@@ -41,7 +41,7 @@ object IDEKotlinBinaryClassCache {
if (cached != null) {
return cached.isKotlinBinary
}
return getKotlinBinaryClass(file) != null
return getKotlinBinaryClass(file, fileContent) != null
}
fun getKotlinBinaryClass(file: VirtualFile, fileContent: ByteArray? = null): KotlinJvmBinaryClass? {
@@ -49,16 +49,17 @@ fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
* Checks if this file is a compiled "internal" Kotlin class, i.e. a Kotlin class (not necessarily ABI-compatible with the current plugin)
* which should NOT be decompiled (and, as a result, shown under the library in the Project view, be searchable via Find class, etc.)
*/
fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
if (!IDEKotlinBinaryClassCache.isKotlinJvmCompiledFile(file)) {
fun isKotlinInternalCompiledFile(file: VirtualFile, fileContent: ByteArray): Boolean {
if (!IDEKotlinBinaryClassCache.isKotlinJvmCompiledFile(file, fileContent)) {
return false
}
if (ClassFileViewProvider.isInnerClass(file)) {
val innerClass = ClassFileViewProvider.isInnerClass(file, fileContent)
if (innerClass) {
return true
}
val (header, classId) = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file) ?: return false
val (header, classId) = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file, fileContent) ?: return false
if (classId.isLocal) return true
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.types.asFlexibleType
import org.jetbrains.kotlin.types.isFlexible
import java.io.IOException
class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
private val stubBuilder = KotlinClsStubBuilder()
@@ -47,14 +48,21 @@ class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
override fun createFileViewProvider(file: VirtualFile, manager: PsiManager, physical: Boolean): KotlinDecompiledFileViewProvider {
val project = manager.project
return KotlinDecompiledFileViewProvider(manager, file, physical) { provider ->
return KotlinDecompiledFileViewProvider(manager, file, physical) factory@{ provider ->
val virtualFile = provider.virtualFile
val fileIndex = ServiceManager.getService(project, FileIndexFacade::class.java)
when {
!fileIndex.isInLibraryClasses(virtualFile) && fileIndex.isInSource(virtualFile) -> null
isKotlinInternalCompiledFile(virtualFile) -> null
else -> KtClsFile(provider)
if (!fileIndex.isInLibraryClasses(virtualFile) && fileIndex.isInSource(virtualFile)) return@factory null
val content = try {
virtualFile.contentsToByteArray(false)
}
catch (e: IOException) {
return@factory null
}
if (isKotlinInternalCompiledFile(virtualFile, content))
null
else
KtClsFile(provider)
}
}
}
@@ -44,7 +44,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
override fun buildFileStub(content: FileContent): PsiFileStub<*>? {
val file = content.file
if (isKotlinInternalCompiledFile(file)) {
if (isKotlinInternalCompiledFile(file, content.content)) {
return null
}