KotlinAbiVersionIndex: refactoring after converting
This commit is contained in:
@@ -16,113 +16,85 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.versions
|
package org.jetbrains.kotlin.idea.versions
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet
|
|
||||||
import com.google.common.collect.Maps
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.fileTypes.StdFileTypes
|
import com.intellij.openapi.fileTypes.StdFileTypes
|
||||||
import com.intellij.openapi.util.Ref
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.util.indexing.*
|
import com.intellij.util.indexing.*
|
||||||
import com.intellij.util.io.ExternalIntegerKeyDescriptor
|
import com.intellij.util.io.ExternalIntegerKeyDescriptor
|
||||||
import com.intellij.util.io.KeyDescriptor
|
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
|
||||||
import org.jetbrains.kotlin.load.java.AbiVersionUtil
|
import org.jetbrains.kotlin.load.java.AbiVersionUtil
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
|
||||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
|
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Important! This is not a stub-based index. And it has its own version
|
* Important! This is not a stub-based index. And it has its own version
|
||||||
*/
|
*/
|
||||||
public class KotlinAbiVersionIndex private constructor() : ScalarIndexExtension<Int>() {
|
public object KotlinAbiVersionIndex : ScalarIndexExtension<Int>() {
|
||||||
|
|
||||||
override fun getName(): ID<Int, Void> {
|
override fun getName() = ID.create<Int, Void>(javaClass<KotlinAbiVersionIndex>().getCanonicalName())
|
||||||
return NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIndexer(): DataIndexer<Int, Void, FileContent> {
|
override fun getIndexer() = INDEXER
|
||||||
return INDEXER
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getKeyDescriptor(): KeyDescriptor<Int> {
|
override fun getKeyDescriptor() = ExternalIntegerKeyDescriptor()
|
||||||
return KEY_DESCRIPTOR
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInputFilter(): FileBasedIndex.InputFilter {
|
override fun getInputFilter() = FileBasedIndex.InputFilter() { file -> file.getFileType() == StdFileTypes.CLASS }
|
||||||
return INPUT_FILTER
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dependsOnFileContent(): Boolean {
|
override fun dependsOnFileContent() = true
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getVersion(): Int {
|
override fun getVersion() = VERSION
|
||||||
return VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
private val VERSION = 1
|
||||||
private val LOG = Logger.getInstance(javaClass<KotlinAbiVersionIndex>())
|
|
||||||
|
|
||||||
public val INSTANCE: KotlinAbiVersionIndex = KotlinAbiVersionIndex()
|
private val LOG = Logger.getInstance(javaClass<KotlinAbiVersionIndex>())
|
||||||
|
|
||||||
private val VERSION = 1
|
private val kotlinAnnotationsDesc = setOf(
|
||||||
|
OLD_JET_CLASS_ANNOTATION,
|
||||||
|
OLD_JET_PACKAGE_CLASS_ANNOTATION,
|
||||||
|
OLD_KOTLIN_CLASS,
|
||||||
|
OLD_KOTLIN_PACKAGE,
|
||||||
|
KOTLIN_CLASS,
|
||||||
|
KOTLIN_PACKAGE)
|
||||||
|
.map { asmDescByFqNameWithoutInnerClasses(it) }
|
||||||
|
|
||||||
private val NAME = ID.create<Int, Void>(javaClass<KotlinAbiVersionIndex>().getCanonicalName())
|
private val INDEXER = DataIndexer<Int, Void, FileContent>() { inputData: FileContent ->
|
||||||
private val KEY_DESCRIPTOR = ExternalIntegerKeyDescriptor()
|
var version: Int? = null
|
||||||
|
var annotationPresent = false
|
||||||
|
|
||||||
private val INPUT_FILTER = object : FileBasedIndex.InputFilter {
|
try {
|
||||||
override fun acceptInput(file: VirtualFile): Boolean {
|
val classReader = ClassReader(inputData.getContent())
|
||||||
return file.getFileType() == StdFileTypes.CLASS
|
classReader.accept(object : ClassVisitor(Opcodes.ASM5) {
|
||||||
}
|
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
|
||||||
}
|
if (!kotlinAnnotationsDesc.contains(desc)) {
|
||||||
|
return null
|
||||||
private val INDEXER = object : DataIndexer<Int, Void, FileContent> {
|
}
|
||||||
SuppressWarnings("deprecation")
|
annotationPresent = true
|
||||||
private val kotlinAnnotationsDesc = ImmutableSet.Builder<String>().add(asmDescByFqNameWithoutInnerClasses(OLD_JET_CLASS_ANNOTATION)).add(asmDescByFqNameWithoutInnerClasses(OLD_JET_PACKAGE_CLASS_ANNOTATION)).add(asmDescByFqNameWithoutInnerClasses(OLD_KOTLIN_CLASS)).add(asmDescByFqNameWithoutInnerClasses(OLD_KOTLIN_PACKAGE)).add(asmDescByFqNameWithoutInnerClasses(KOTLIN_CLASS)).add(asmDescByFqNameWithoutInnerClasses(KOTLIN_PACKAGE)).build()
|
return object : AnnotationVisitor(Opcodes.ASM5) {
|
||||||
|
override fun visit(name: String, value: Any) {
|
||||||
override fun map(inputData: FileContent): Map<Int, Void> {
|
if (ABI_VERSION_FIELD_NAME == name) {
|
||||||
val result = Maps.newHashMap<Int, Void>()
|
if (value is Int) {
|
||||||
val annotationPresent = Ref(false)
|
version = value
|
||||||
|
}
|
||||||
try {
|
else {
|
||||||
val classReader = ClassReader(inputData.getContent())
|
// Version is set to something weird
|
||||||
classReader.accept(object : ClassVisitor(Opcodes.ASM5) {
|
version = AbiVersionUtil.INVALID_VERSION
|
||||||
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
|
|
||||||
if (!kotlinAnnotationsDesc.contains(desc)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
annotationPresent.set(true)
|
|
||||||
return object : AnnotationVisitor(Opcodes.ASM5) {
|
|
||||||
override fun visit(name: String, value: Any) {
|
|
||||||
if (ABI_VERSION_FIELD_NAME == name) {
|
|
||||||
if (value is Int) {
|
|
||||||
result.put(value, null)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Version is set to something weird
|
|
||||||
result.put(AbiVersionUtil.INVALID_VERSION, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
|
}
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
|
||||||
LOG.warn("Could not index ABI version for file " + inputData.getFile() + ": " + e.getMessage())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (annotationPresent.get() && result.isEmpty()) {
|
|
||||||
// No version at all: the class is too old
|
|
||||||
result.put(AbiVersionUtil.INVALID_VERSION, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (e: Throwable) {
|
||||||
|
LOG.warn("Could not index ABI version for file " + inputData.getFile() + ": " + e.getMessage())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (annotationPresent && version == null) {
|
||||||
|
// No version at all: the class is too old
|
||||||
|
version = AbiVersionUtil.INVALID_VERSION
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != null) mapOf<Int, Void?>(version!! to null) else mapOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user