Refactor: Extract and expose local class data finder as separate class

This commit is contained in:
Pavel V. Talanov
2014-11-18 15:16:22 +03:00
parent 9e784e7018
commit 41f2c71081
2 changed files with 75 additions and 39 deletions
@@ -17,7 +17,6 @@
package org.jetbrains.jet.plugin.decompiler.textBuilder
import org.jetbrains.jet.lang.resolve.name.ClassId
import org.jetbrains.jet.descriptors.serialization.ClassDataFinder
import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor
@@ -31,13 +30,10 @@ import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPacka
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.descriptors.serialization.context.DeserializationComponents
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.descriptors.serialization.ClassData
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.jet.plugin.decompiler.isKotlinWithCompatibleAbiVersion
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
@@ -73,40 +69,14 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
return membersScope.getDescriptors()
}
private val localClassFinder = object : KotlinClassFinder {
override fun findKotlinClass(javaClass: JavaClass) = findKotlinClass(javaClass.classId)
override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? {
if (classId.getPackageFqName() != directoryPackageFqName) {
return null
}
val segments = DeserializedResolverUtils.kotlinFqNameToJavaFqName(classId.getRelativeClassName()).pathSegments()
val targetName = segments.joinToString("$", postfix = ".class")
val virtualFile = packageDirectory.findChild(targetName)
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)
}
return null
}
}
private val localClassFinder = LocalClassFinder(packageDirectory, directoryPackageFqName)
private val localClassDataFinder = LocalClassDataFinder(localClassFinder, LOG)
private val storageManager = LockBasedStorageManager.NO_LOCKS
private val annotationAndConstantLoader =
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, storageManager, localClassFinder, LOGGING_REPORTER)
private val classDataFinder = object : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? {
val binaryClass = localClassFinder.findKotlinClass(classId) ?: return null
val data = binaryClass.getClassHeader().annotationData
if (data == null) {
LOG.error("Annotation data missing for ${binaryClass.getClassId()}")
return null
}
return JavaProtoBufUtil.readClassDataFrom(data)
}
}
private val packageFragmentProvider = object : PackageFragmentProvider {
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
return listOf(createDummyPackageFragment(fqName))
@@ -132,7 +102,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
}
private val deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
storageManager, moduleDescriptor, localClassDataFinder, annotationAndConstantLoader, packageFragmentProvider,
JavaFlexibleTypeCapabilitiesDeserializer
)
@@ -140,12 +110,6 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
return MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
}
private val JavaClass.classId: ClassId
get() {
val outer = getOuterClass()
return if (outer == null) ClassId.topLevel(getFqName()!!) else outer.classId.createNestedClassId(getName())
}
class object {
private val LOG = Logger.getInstance(javaClass<DeserializerForDecompiler>())
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.decompiler.textBuilder
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.lang.resolve.name.ClassId
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils
import org.jetbrains.jet.plugin.decompiler.isKotlinWithCompatibleAbiVersion
import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.descriptors.serialization.ClassDataFinder
import org.jetbrains.jet.descriptors.serialization.ClassData
import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil
import com.intellij.openapi.diagnostic.Logger
class LocalClassFinder(
val packageDirectory: VirtualFile,
val directoryPackageFqName: FqName
) : KotlinClassFinder {
override fun findKotlinClass(javaClass: JavaClass) = findKotlinClass(javaClass.classId)
override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? {
if (classId.getPackageFqName() != directoryPackageFqName) {
return null
}
val segments = DeserializedResolverUtils.kotlinFqNameToJavaFqName(classId.getRelativeClassName()).pathSegments()
val targetName = segments.joinToString("$", postfix = ".class")
val virtualFile = packageDirectory.findChild(targetName)
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)
}
return null
}
}
class LocalClassDataFinder(
val localClassFinder: LocalClassFinder,
val log: Logger
) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? {
val binaryClass = localClassFinder.findKotlinClass(classId) ?: return null
val data = binaryClass.getClassHeader().annotationData
if (data == null) {
log.error("Annotation data missing for ${binaryClass.getClassId()}")
return null
}
return JavaProtoBufUtil.readClassDataFrom(data)
}
}
private val JavaClass.classId: ClassId
get() {
val outer = getOuterClass()
return if (outer == null) ClassId.topLevel(getFqName()!!) else outer.classId.createNestedClassId(getName())
}