KotlinAbiVersionIndex: refactoring after converting

This commit is contained in:
Michael Nedzelsky
2015-06-09 16:19:28 +03:00
parent a396222652
commit 2e8c9fe362
@@ -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()
} }
} }