diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDecompiler.kt index 54b9356b280..e00e90eec67 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDecompiler.kt @@ -82,7 +82,7 @@ fun buildDecompiledTextForBuiltIns(builtInFile: VirtualFile): DecompiledText { } is BuiltInDefinitionFile.Compatible -> { val packageFqName = file.packageFqName - val resolver = KotlinBuiltInDeserializerForDecompiler(file.packageDirectory, packageFqName, file.nameResolver) + val resolver = KotlinBuiltInDeserializerForDecompiler(file.packageDirectory, packageFqName, file.proto, file.nameResolver) val declarations = arrayListOf() declarations.addAll(resolver.resolveDeclarationsInFacade(packageFqName)) for (classProto in file.classesToDecompile) { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDeserializerForDecompiler.kt index bdb501fbec9..705bd81df04 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInDeserializerForDecompiler.kt @@ -19,39 +19,47 @@ package org.jetbrains.kotlin.idea.decompiler.builtIns import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol -import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths +import org.jetbrains.kotlin.builtins.BuiltInsClassDataFinder import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf import org.jetbrains.kotlin.serialization.deserialization.* +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope class KotlinBuiltInDeserializerForDecompiler( packageDirectory: VirtualFile, packageFqName: FqName, + private val proto: BuiltInsProtoBuf.BuiltIns, private val nameResolver: NameResolver ) : DeserializerForDecompilerBase(packageDirectory, packageFqName) { override val targetPlatform: TargetPlatform get() = TargetPlatform.Default - private val classDataFinder = DirectoryBasedClassDataFinder( - packageDirectory, directoryPackageFqName, nameResolver, BuiltInsSerializedResourcePaths - ) - override val deserializationComponents = DeserializationComponents( - storageManager, moduleDescriptor, classDataFinder, AnnotationAndConstantLoaderImpl(moduleDescriptor, BuiltInSerializerProtocol), - packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), LoggingErrorReporter(LOG), + storageManager, moduleDescriptor, BuiltInsClassDataFinder(proto, nameResolver), + AnnotationAndConstantLoaderImpl(moduleDescriptor, BuiltInSerializerProtocol), packageFragmentProvider, + ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), LoggingErrorReporter(LOG), LookupTracker.DO_NOTHING, FlexibleTypeCapabilitiesDeserializer.ThrowException, ClassDescriptorFactory.EMPTY ) override fun resolveDeclarationsInFacade(facadeFqName: FqName): List { - return getDescriptorsFromPackageFile(facadeFqName, BuiltInsSerializedResourcePaths, LOG, nameResolver) + assert(facadeFqName == directoryPackageFqName) { + "Was called for $facadeFqName; only members of $directoryPackageFqName package are expected." + } + + val membersScope = DeserializedPackageMemberScope( + createDummyPackageFragment(facadeFqName), proto.`package`, nameResolver, packagePartSource = null, + components = deserializationComponents + ) { emptyList() } + + return membersScope.getContributedDescriptors().toList() } companion object { private val LOG = Logger.getInstance(KotlinBuiltInDeserializerForDecompiler::class.java) } -} \ No newline at end of file +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInStubBuilder.kt index 0d777be8dfa..a95ae19fad6 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInStubBuilder.kt @@ -16,18 +16,14 @@ package org.jetbrains.kotlin.idea.decompiler.builtIns -import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.compiled.ClsStubBuilder import com.intellij.psi.impl.compiled.ClassFileStubBuilder import com.intellij.psi.stubs.PsiFileStub import com.intellij.util.indexing.FileContent import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol -import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths +import org.jetbrains.kotlin.builtins.BuiltInsClassDataFinder import org.jetbrains.kotlin.idea.decompiler.common.AnnotationLoaderForStubBuilderImpl -import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder import org.jetbrains.kotlin.idea.decompiler.stubBuilder.* -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer import org.jetbrains.kotlin.serialization.deserialization.TypeTable @@ -49,7 +45,11 @@ class KotlinBuiltInStubBuilder : ClsStubBuilder() { val packageProto = file.proto.`package` val packageFqName = file.packageFqName val nameResolver = file.nameResolver - val components = createStubBuilderComponents(virtualFile, packageFqName, nameResolver) + val components = ClsStubBuilderComponents( + BuiltInsClassDataFinder(file.proto, nameResolver), + AnnotationLoaderForStubBuilderImpl(BuiltInSerializerProtocol), + virtualFile + ) val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable)) val fileStub = createFileStub(packageFqName) @@ -65,10 +65,4 @@ class KotlinBuiltInStubBuilder : ClsStubBuilder() { } } } - - private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName, nameResolver: NameResolver): ClsStubBuilderComponents { - val finder = DirectoryBasedClassDataFinder(file.parent!!, packageFqName, nameResolver, BuiltInsSerializedResourcePaths) - val annotationLoader = AnnotationLoaderForStubBuilderImpl(BuiltInSerializerProtocol) - return ClsStubBuilderComponents(finder, annotationLoader, file) - } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/ProtoBufUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/ProtoBufUtil.kt deleted file mode 100644 index 450e58e048f..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/ProtoBufUtil.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.common - -import com.google.protobuf.ExtensionRegistryLite -import org.jetbrains.kotlin.serialization.ProtoBuf -import java.io.ByteArrayInputStream - -fun ByteArray.toPackageProto(extensionRegistry: ExtensionRegistryLite): ProtoBuf.Package { - return ProtoBuf.Package.parseFrom(ByteArrayInputStream(this), extensionRegistry)!! -} - -fun ByteArray.toClassProto(extensionRegistry: ExtensionRegistryLite): ProtoBuf.Class { - return ProtoBuf.Class.parseFrom(ByteArrayInputStream(this), extensionRegistry) -} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/directoryBasedFinders.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/directoryBasedFinders.kt deleted file mode 100644 index c53b7c5fe83..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/directoryBasedFinders.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.common - -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.serialization.ClassData -import org.jetbrains.kotlin.serialization.ClassDataWithSource -import org.jetbrains.kotlin.serialization.SerializedResourcePaths -import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder -import org.jetbrains.kotlin.serialization.deserialization.NameResolver - -class DirectoryBasedClassDataFinder( - private val packageDirectory: VirtualFile, - private val directoryPackageFqName: FqName, - private val nameResolver: NameResolver, - private val paths: SerializedResourcePaths -) : ClassDataFinder { - fun findFileForClass(classId: ClassId): VirtualFile? { - if (classId.packageFqName != directoryPackageFqName) return null - - val pathRelativeToDir = paths.getClassMetadataPath(classId).substringAfterLast("/") - return packageDirectory.findChild(pathRelativeToDir) - } - - override fun findClassData(classId: ClassId): ClassDataWithSource? { - val virtualFile = findFileForClass(classId) ?: return null - - val content = virtualFile.contentsToByteArray(false) - val classProto = content.toClassProto(paths.extensionRegistry) - return ClassDataWithSource(ClassData(nameResolver, classProto)) - } -} - diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptDeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptDeserializerForDecompiler.kt index 8f399be50df..152ce7c5744 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptDeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptDeserializerForDecompiler.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.idea.decompiler.js import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver @@ -27,8 +26,11 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.* +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol +import org.jetbrains.kotlin.serialization.js.KotlinJavascriptClassDataFinder import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths import java.io.ByteArrayInputStream @@ -46,19 +48,37 @@ class KotlinJavaScriptDeserializerForDecompiler( override val targetPlatform: TargetPlatform get() = JsPlatform - private val finder = DirectoryBasedClassDataFinder(packageDirectory, directoryPackageFqName, nameResolver, KotlinJavascriptSerializedResourcePaths) + private val classDataFinder = KotlinJavascriptClassDataFinder(nameResolver) { path -> + packageDirectory.findChild(path.substringAfterLast("/"))?.inputStream + } private val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(moduleDescriptor, JsSerializerProtocol) override val deserializationComponents = DeserializationComponents( - storageManager, moduleDescriptor, finder, annotationAndConstantLoader, packageFragmentProvider, + storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), LoggingErrorReporter(LOG), LookupTracker.DO_NOTHING, FlexibleTypeCapabilitiesDeserializer.Dynamic, ClassDescriptorFactory.EMPTY ) override fun resolveDeclarationsInFacade(facadeFqName: FqName): List { val packageFqName = facadeFqName.parent() - return getDescriptorsFromPackageFile(packageFqName, KotlinJavascriptSerializedResourcePaths, LOG, nameResolver) + assert(packageFqName == directoryPackageFqName) { + "Was called for $packageFqName; only members of $directoryPackageFqName package are expected." + } + val packageFilePath = KotlinJavascriptSerializedResourcePaths.getPackageFilePath(directoryPackageFqName).substringAfterLast("/") + val file = packageDirectory.findChild(packageFilePath) + if (file == null) { + LOG.error("Could not read data for package $packageFqName; $packageFilePath absent in $packageDirectory") + return emptyList() + } + + val content = file.contentsToByteArray(false) + val packageProto = ProtoBuf.Package.parseFrom(content, KotlinJavascriptSerializedResourcePaths.extensionRegistry) + val membersScope = DeserializedPackageMemberScope( + createDummyPackageFragment(packageFqName), packageProto, nameResolver, packagePartSource = null, + components = deserializationComponents + ) { emptyList() } + return membersScope.getContributedDescriptors().toList() } companion object { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptStubBuilder.kt index b6045f424fa..5ea46c825b8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptStubBuilder.kt @@ -22,18 +22,16 @@ import com.intellij.psi.impl.compiled.ClassFileStubBuilder import com.intellij.psi.stubs.PsiFileStub import com.intellij.util.indexing.FileContent import org.jetbrains.kotlin.idea.decompiler.common.AnnotationLoaderForStubBuilderImpl -import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder -import org.jetbrains.kotlin.idea.decompiler.common.toClassProto -import org.jetbrains.kotlin.idea.decompiler.common.toPackageProto import org.jetbrains.kotlin.idea.decompiler.stubBuilder.ClsStubBuilderComponents import org.jetbrains.kotlin.idea.decompiler.stubBuilder.createPackageFacadeStub import org.jetbrains.kotlin.idea.decompiler.stubBuilder.createTopLevelClassStub -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl import org.jetbrains.kotlin.serialization.deserialization.TypeTable import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol +import org.jetbrains.kotlin.serialization.js.KotlinJavascriptClassDataFinder import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths import java.io.ByteArrayInputStream @@ -60,27 +58,25 @@ class KotlinJavaScriptStubBuilder : ClsStubBuilder() { assert(stringsFile != null) { "strings file not found: $stringsFileName" } val nameResolver = NameResolverImpl.read(ByteArrayInputStream(stringsFile!!.contentsToByteArray(false))) - val components = createStubBuilderComponents(file, packageFqName, nameResolver) + val components = createStubBuilderComponents(file, nameResolver) if (isPackageHeader) { - val packageProto = content.toPackageProto(KotlinJavascriptSerializedResourcePaths.extensionRegistry) - val context = components.createContext( - nameResolver, packageFqName, TypeTable(packageProto.typeTable) - ) + val packageProto = ProtoBuf.Package.parseFrom(content, KotlinJavascriptSerializedResourcePaths.extensionRegistry) + val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable)) return createPackageFacadeStub(packageProto, packageFqName, context) } else { - val classProto = content.toClassProto(KotlinJavascriptSerializedResourcePaths.extensionRegistry) + val classProto = ProtoBuf.Class.parseFrom(content, KotlinJavascriptSerializedResourcePaths.extensionRegistry) val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable)) val classId = JsMetaFileUtils.getClassId(file) return createTopLevelClassStub(classId, classProto, context) } } - private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName, nameResolver: NameResolver): ClsStubBuilderComponents { - val classDataFinder = DirectoryBasedClassDataFinder( - file.parent!!, packageFqName, nameResolver, KotlinJavascriptSerializedResourcePaths - ) + private fun createStubBuilderComponents(file: VirtualFile, nameResolver: NameResolver): ClsStubBuilderComponents { + val classDataFinder = KotlinJavascriptClassDataFinder(nameResolver) { path -> + file.parent.findChild(path.substringAfterLast("/"))?.inputStream + } val annotationLoader = AnnotationLoaderForStubBuilderImpl(JsSerializerProtocol) return ClsStubBuilderComponents(classDataFinder, annotationLoader, file) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompilerBase.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompilerBase.kt index 8dc808cec11..16eac0c093e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompilerBase.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DeserializerForDecompilerBase.kt @@ -16,22 +16,20 @@ 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.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +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.idea.decompiler.common.toPackageProto import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.TargetPlatform -import org.jetbrains.kotlin.serialization.SerializedResourcePaths import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolver -import org.jetbrains.kotlin.serialization.deserialization.NameResolver -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager @@ -62,31 +60,6 @@ abstract class DeserializerForDecompilerBase( protected fun createDummyPackageFragment(fqName: FqName): MutablePackageFragmentDescriptor = MutablePackageFragmentDescriptor(moduleDescriptor, fqName) - protected fun getDescriptorsFromPackageFile( - packageFqName: FqName, - paths: SerializedResourcePaths, - log: Logger, - nameResolver: NameResolver - ): List { - assert(packageFqName == directoryPackageFqName) { - "Was called for $packageFqName; only members of $directoryPackageFqName package are expected." - } - val packageFilePath = paths.getPackageFilePath(directoryPackageFqName).substringAfterLast("/") - val file = packageDirectory.findChild(packageFilePath) - if (file == null) { - log.error("Could not read data for package $packageFqName; $packageFilePath absent in $packageDirectory") - return emptyList() - } - - val content = file.contentsToByteArray(false) - val packageProto = content.toPackageProto(paths.extensionRegistry) - val membersScope = DeserializedPackageMemberScope( - createDummyPackageFragment(packageFqName), packageProto, nameResolver, packagePartSource = null, - components = deserializationComponents - ) { emptyList() } - return membersScope.getContributedDescriptors().toList() - } - private fun createDummyModule(name: String) = ModuleDescriptorImpl(Name.special("<$name>"), storageManager, ModuleParameters.Empty, targetPlatform.builtIns) init {