Move DirectoryBasedClassFinder and DirectoryBasedDataFinder from intellij

This commit is contained in:
Ilya Kirillov
2021-12-16 13:13:17 +03:00
parent dbb3ebb8df
commit b222bf88a0
3 changed files with 93 additions and 1 deletions
@@ -9,10 +9,10 @@ dependencies {
api(project(":core:deserialization.common.jvm"))
api(project(":core:deserialization"))
implementation(project(":compiler:psi:cls-psi-stub-builder"))
implementation(project(":core:deserialization.common.jvm.impl"))
implementation(project(":core:compiler.common.jvm"))
api(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
}
sourceSets {
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.psi.stubs.file.builder
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.classId
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import java.io.InputStream
class DirectoryBasedClassFinder(
val packageDirectory: VirtualFile,
val directoryPackageFqName: FqName
) : KotlinClassFinder {
override fun findKotlinClassOrContent(javaClass: JavaClass): KotlinClassFinder.Result? = findKotlinClassOrContent(javaClass.classId!!)
override fun findKotlinClassOrContent(classId: ClassId): KotlinClassFinder.Result? {
if (classId.packageFqName != directoryPackageFqName) {
return null
}
val targetName = classId.relativeClassName.pathSegments().joinToString("$", postfix = ".class")
val virtualFile = packageDirectory.findChild(targetName)
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
return IDEKotlinBinaryClassCache.getInstance().getKotlinBinaryClass(virtualFile)?.let(::KotlinClass)
}
return null
}
// TODO
override fun findMetadata(classId: ClassId): InputStream? = null
// TODO
override fun hasMetadataPackage(fqName: FqName): Boolean = false
// TODO: load built-ins from packageDirectory?
override fun findBuiltInsData(packageFqName: FqName): InputStream? = null
}
/**
* Checks if this file is a compiled Kotlin class file ABI-compatible with the current plugin
*/
private fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
val ideKotlinBinaryClassCache = IDEKotlinBinaryClassCache.getInstance()
if (!ideKotlinBinaryClassCache.isKotlinJvmCompiledFile(file)) return false
val kotlinClass = ideKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file)
return kotlinClass != null && kotlinClass.metadataVersion.isCompatible()
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.psi.stubs.file.builder
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.findKotlinClass
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
class DirectoryBasedDataFinder(
val classFinder: DirectoryBasedClassFinder,
val log: Logger
) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? {
val binaryClass = classFinder.findKotlinClass(classId) ?: return null
val classHeader = binaryClass.classHeader
val data = classHeader.data
if (data == null) {
log.error("Annotation data missing for ${binaryClass.classId}")
return null
}
val strings = classHeader.strings
if (strings == null) {
log.error("String table not found in class ${binaryClass.classId}")
return null
}
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(data, strings)
return ClassData(nameResolver, classProto, classHeader.metadataVersion, KotlinJvmBinarySourceElement(binaryClass))
}
}