From 41f2c71081881ca5b563d4c043c72b62b77494e5 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 18 Nov 2014 15:16:22 +0300 Subject: [PATCH] Refactor: Extract and expose local class data finder as separate class --- .../textBuilder/DeserializerForDecompiler.kt | 42 +---------- .../textBuilder/LocalClassFinder.kt | 72 +++++++++++++++++++ 2 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/LocalClassFinder.kt diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt index cc45ca4832a..f21ccb068ed 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt @@ -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 { 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()) diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/LocalClassFinder.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/LocalClassFinder.kt new file mode 100644 index 00000000000..a26b6886eb7 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/LocalClassFinder.kt @@ -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()) + } \ No newline at end of file