Refactor: Extract and expose local class data finder as separate class
This commit is contained in:
+3
-39
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.jet.plugin.decompiler.textBuilder
|
package org.jetbrains.jet.plugin.decompiler.textBuilder
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.ClassId
|
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.descriptors.serialization.JavaProtoBufUtil
|
||||||
import org.jetbrains.jet.lang.descriptors.*
|
import org.jetbrains.jet.lang.descriptors.*
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor
|
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.resolver.ErrorReporter
|
||||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
|
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
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.descriptors.serialization.context.DeserializationComponents
|
||||||
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
|
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
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.lang.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.jet.plugin.decompiler.isKotlinWithCompatibleAbiVersion
|
|
||||||
|
|
||||||
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
||||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||||
@@ -73,40 +69,14 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
|
|||||||
return membersScope.getDescriptors()
|
return membersScope.getDescriptors()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val localClassFinder = object : KotlinClassFinder {
|
private val localClassFinder = LocalClassFinder(packageDirectory, directoryPackageFqName)
|
||||||
override fun findKotlinClass(javaClass: JavaClass) = findKotlinClass(javaClass.classId)
|
private val localClassDataFinder = LocalClassDataFinder(localClassFinder, LOG)
|
||||||
|
|
||||||
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 storageManager = LockBasedStorageManager.NO_LOCKS
|
private val storageManager = LockBasedStorageManager.NO_LOCKS
|
||||||
|
|
||||||
private val annotationAndConstantLoader =
|
private val annotationAndConstantLoader =
|
||||||
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, storageManager, localClassFinder, LOGGING_REPORTER)
|
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 {
|
private val packageFragmentProvider = object : PackageFragmentProvider {
|
||||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||||
return listOf(createDummyPackageFragment(fqName))
|
return listOf(createDummyPackageFragment(fqName))
|
||||||
@@ -132,7 +102,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val deserializationComponents = DeserializationComponents(
|
private val deserializationComponents = DeserializationComponents(
|
||||||
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
|
storageManager, moduleDescriptor, localClassDataFinder, annotationAndConstantLoader, packageFragmentProvider,
|
||||||
JavaFlexibleTypeCapabilitiesDeserializer
|
JavaFlexibleTypeCapabilitiesDeserializer
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -140,12 +110,6 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
|
|||||||
return MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
|
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 {
|
class object {
|
||||||
private val LOG = Logger.getInstance(javaClass<DeserializerForDecompiler>())
|
private val LOG = Logger.getInstance(javaClass<DeserializerForDecompiler>())
|
||||||
|
|
||||||
|
|||||||
+72
@@ -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())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user