add KotlinJavaScriptDeserializeForDecompiler
This commit is contained in:
+13
-53
@@ -18,24 +18,15 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleParameters
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.BinaryClassAnnotationAndConstantLoaderImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeCapabilitiesDeserializer
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
|
||||
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||
@@ -44,14 +35,22 @@ public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDec
|
||||
return DeserializerForDecompiler(classFile.getParent()!!, packageFqName)
|
||||
}
|
||||
|
||||
public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val directoryPackageFqName: FqName) : ResolverForDecompiler {
|
||||
public class DeserializerForDecompiler(
|
||||
packageDirectory: VirtualFile,
|
||||
directoryPackageFqName: FqName
|
||||
) : DeserializerForDecompilerBase(packageDirectory, directoryPackageFqName) {
|
||||
|
||||
private val storageManager = LockBasedStorageManager.NO_LOCKS
|
||||
private val moduleDescriptor = createDummyModule("module for building decompiled sources")
|
||||
private val classFinder = DirectoryBasedClassFinder(packageDirectory, directoryPackageFqName)
|
||||
|
||||
private fun createDummyModule(name: String) = ModuleDescriptorImpl(Name.special("<$name>"), storageManager, ModuleParameters.Empty)
|
||||
override val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG)
|
||||
|
||||
override fun resolveTopLevelClass(classId: ClassId) = deserializationComponents.deserializeClass(classId)
|
||||
override val annotationAndConstantLoader =
|
||||
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, storageManager, classFinder, LoggingErrorReporter(LOG))
|
||||
|
||||
override val deserializationComponents: DeserializationComponents = DeserializationComponents(
|
||||
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
|
||||
ResolveEverythingToKotlinAnyLocalClassResolver, JavaFlexibleTypeCapabilitiesDeserializer
|
||||
)
|
||||
|
||||
override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection<DeclarationDescriptor> {
|
||||
assert(packageFqName == directoryPackageFqName) { "Was called for $packageFqName but only $directoryPackageFqName is expected" }
|
||||
@@ -71,45 +70,6 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
|
||||
return membersScope.getDescriptors()
|
||||
}
|
||||
|
||||
private val classFinder = DirectoryBasedClassFinder(packageDirectory, directoryPackageFqName)
|
||||
private val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG)
|
||||
|
||||
private val annotationAndConstantLoader =
|
||||
BinaryClassAnnotationAndConstantLoaderImpl(moduleDescriptor, storageManager, classFinder, LoggingErrorReporter(LOG))
|
||||
|
||||
private val packageFragmentProvider = object : PackageFragmentProvider {
|
||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||
return listOf(createDummyPackageFragment(fqName))
|
||||
}
|
||||
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||
throw UnsupportedOperationException("This method is not supposed to be called.")
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
moduleDescriptor.initialize(packageFragmentProvider)
|
||||
moduleDescriptor.addDependencyOnModule(moduleDescriptor)
|
||||
moduleDescriptor.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule())
|
||||
val moduleContainingMissingDependencies = createDummyModule("module containing missing dependencies for decompiled sources")
|
||||
moduleContainingMissingDependencies.addDependencyOnModule(moduleContainingMissingDependencies)
|
||||
moduleContainingMissingDependencies.initialize(
|
||||
PackageFragmentProviderForMissingDependencies(moduleContainingMissingDependencies)
|
||||
)
|
||||
moduleDescriptor.addDependencyOnModule(moduleContainingMissingDependencies)
|
||||
moduleDescriptor.seal()
|
||||
moduleContainingMissingDependencies.seal()
|
||||
}
|
||||
|
||||
private val deserializationComponents = DeserializationComponents(
|
||||
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
|
||||
ResolveEverythingToKotlinAnyLocalClassResolver, JavaFlexibleTypeCapabilitiesDeserializer
|
||||
)
|
||||
|
||||
private fun createDummyPackageFragment(fqName: FqName): MutablePackageFragmentDescriptor {
|
||||
return MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(javaClass<DeserializerForDecompiler>())
|
||||
}
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ModuleParameters
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
public abstract class DeserializerForDecompilerBase(
|
||||
val packageDirectory: VirtualFile ,
|
||||
val directoryPackageFqName: FqName
|
||||
) : ResolverForDecompiler {
|
||||
|
||||
protected abstract val deserializationComponents: DeserializationComponents
|
||||
|
||||
protected abstract val classDataFinder: ClassDataFinder
|
||||
|
||||
protected abstract val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, CompileTimeConstant<*>>
|
||||
|
||||
protected val storageManager: StorageManager = LockBasedStorageManager.NO_LOCKS
|
||||
|
||||
protected val moduleDescriptor: ModuleDescriptorImpl = createDummyModule("module for building decompiled sources")
|
||||
|
||||
protected val packageFragmentProvider: PackageFragmentProvider = object : PackageFragmentProvider {
|
||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||
return listOf(createDummyPackageFragment(fqName))
|
||||
}
|
||||
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||
throw UnsupportedOperationException("This method is not supposed to be called.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveTopLevelClass(classId: ClassId) = deserializationComponents.deserializeClass(classId)
|
||||
|
||||
protected fun createDummyPackageFragment(fqName: FqName): MutablePackageFragmentDescriptor =
|
||||
MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
|
||||
|
||||
private fun createDummyModule(name: String) = ModuleDescriptorImpl(Name.special("<$name>"), storageManager, ModuleParameters.Empty)
|
||||
|
||||
init {
|
||||
moduleDescriptor.initialize(packageFragmentProvider)
|
||||
moduleDescriptor.addDependencyOnModule(moduleDescriptor)
|
||||
moduleDescriptor.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule())
|
||||
val moduleContainingMissingDependencies = createDummyModule("module containing missing dependencies for decompiled sources")
|
||||
moduleContainingMissingDependencies.addDependencyOnModule(moduleContainingMissingDependencies)
|
||||
moduleContainingMissingDependencies.initialize(
|
||||
PackageFragmentProviderForMissingDependencies(moduleContainingMissingDependencies)
|
||||
)
|
||||
moduleDescriptor.addDependencyOnModule(moduleContainingMissingDependencies)
|
||||
moduleDescriptor.seal()
|
||||
moduleContainingMissingDependencies.seal()
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeCapabilitiesDeserializer
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptAnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths
|
||||
import org.jetbrains.kotlin.serialization.js.toPackageData
|
||||
import java.io.ByteArrayInputStream
|
||||
|
||||
public class KotlinJavaScriptDeserializerForDecompiler(
|
||||
classFile: VirtualFile
|
||||
) : DeserializerForDecompilerBase(classFile.getParent()!!, JsMetaFileUtils.getPackageFqName(classFile)) {
|
||||
|
||||
private val nameResolver = run {
|
||||
val moduleDirectory = JsMetaFileUtils.getModuleDirectory(packageDirectory)
|
||||
val stringsFileName = KotlinJavascriptSerializedResourcePaths.getStringTableFilePath(directoryPackageFqName)
|
||||
val stringsFile = moduleDirectory.findFileByRelativePath(stringsFileName)
|
||||
assert(stringsFile != null, "strings file not found: $stringsFileName")
|
||||
NameResolver.read(ByteArrayInputStream(stringsFile!!.contentsToByteArray(false)))
|
||||
}
|
||||
|
||||
private val metaFileFinder = DirectoryBasedKotlinJavaScriptMetaFileFinder(packageDirectory, directoryPackageFqName, nameResolver)
|
||||
|
||||
override val classDataFinder = DirectoryBasedKotlinJavaScriptDataFinder(metaFileFinder, LOG)
|
||||
|
||||
override val annotationAndConstantLoader = KotlinJavascriptAnnotationAndConstantLoader(moduleDescriptor)
|
||||
|
||||
override val deserializationComponents = DeserializationComponents(
|
||||
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
|
||||
ResolveEverythingToKotlinAnyLocalClassResolver, FlexibleTypeCapabilitiesDeserializer.Dynamic
|
||||
)
|
||||
|
||||
override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection<DeclarationDescriptor> {
|
||||
assert(packageFqName == directoryPackageFqName, "Was called for $packageFqName but only $directoryPackageFqName is expected.")
|
||||
val file = metaFileFinder.findKotlinJavascriptMetaFile(PackageClassUtils.getPackageClassId(packageFqName))
|
||||
if (file == null) {
|
||||
LOG.error("Could not read data for $packageFqName")
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val content = file.contentsToByteArray(false)
|
||||
val packageData = content.toPackageData(nameResolver)
|
||||
|
||||
val membersScope = DeserializedPackageMemberScope(
|
||||
createDummyPackageFragment(packageFqName),
|
||||
packageData.getPackageProto(),
|
||||
packageData.getNameResolver(),
|
||||
deserializationComponents
|
||||
) { emptyList() }
|
||||
return membersScope.getDescriptors()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(javaClass<KotlinJavaScriptDeserializerForDecompiler>())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user