From f1208653504700bb4b94333a4dcb2f67065d66d2 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 1 Feb 2017 17:24:24 +0300 Subject: [PATCH] Combine cls stub builders for built-ins and JS --- .../builtIns/KotlinBuiltInDecompiler.kt | 6 +- .../common/KotlinMetadataDecompiler.kt | 7 +- .../KotlinMetadataStubBuilder.kt} | 26 ++++--- .../js/KotlinJavaScriptMetaFileDecompiler.kt | 30 ++++---- .../js/KotlinJavaScriptStubBuilder.kt | 71 ------------------- .../stubBuilder/BuiltInDecompilerTest.kt | 6 +- 6 files changed, 38 insertions(+), 108 deletions(-) rename idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/{builtIns/KotlinBuiltInStubBuilder.kt => common/KotlinMetadataStubBuilder.kt} (76%) delete mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptStubBuilder.kt 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 3240934c3c7..c6dca3275db 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 @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.builtins.BuiltInsBinaryVersion import org.jetbrains.kotlin.idea.decompiler.common.FileWithMetadata import org.jetbrains.kotlin.idea.decompiler.common.KotlinMetadataDecompiler import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.psi.stubs.KotlinStubVersions import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer @@ -31,8 +32,9 @@ import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmen import java.io.ByteArrayInputStream class KotlinBuiltInDecompiler : KotlinMetadataDecompiler( - KotlinBuiltInFileType, KotlinBuiltInStubBuilder(), TargetPlatform.Default, BuiltInSerializerProtocol, - FlexibleTypeDeserializer.ThrowException, BuiltInsBinaryVersion.INSTANCE, BuiltInsBinaryVersion.INVALID_VERSION + KotlinBuiltInFileType, TargetPlatform.Default, BuiltInSerializerProtocol, + FlexibleTypeDeserializer.ThrowException, BuiltInsBinaryVersion.INSTANCE, BuiltInsBinaryVersion.INVALID_VERSION, + KotlinStubVersions.BUILTIN_STUB_VERSION ) { override fun readFile(bytes: ByteArray, file: VirtualFile): FileWithMetadata? { return BuiltInDefinitionFile.read(bytes, file) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDecompiler.kt index 81ea5a5ba3d..64d6e0b1c2e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDecompiler.kt @@ -21,7 +21,6 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.FileViewProvider import com.intellij.psi.PsiManager import com.intellij.psi.compiled.ClassFileDecompilers -import com.intellij.psi.compiled.ClsStubBuilder import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile @@ -41,13 +40,15 @@ import java.io.IOException abstract class KotlinMetadataDecompiler( private val fileType: FileType, - private val stubBuilder: ClsStubBuilder, private val targetPlatform: TargetPlatform, private val serializerProtocol: SerializerExtensionProtocol, private val flexibleTypeDeserializer: FlexibleTypeDeserializer, private val expectedBinaryVersion: V, - private val invalidBinaryVersion: V + private val invalidBinaryVersion: V, + stubVersion: Int ) : ClassFileDecompilers.Full() { + private val stubBuilder = KotlinMetadataStubBuilder(stubVersion, fileType, serializerProtocol, this::readFile) + private val renderer = DescriptorRenderer.withOptions { defaultDecompilerRendererOptions() } abstract fun readFile(bytes: ByteArray, file: VirtualFile): FileWithMetadata? 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/common/KotlinMetadataStubBuilder.kt similarity index 76% rename from idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInStubBuilder.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataStubBuilder.kt index c455a5e98da..b933c57b84f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/builtIns/KotlinBuiltInStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataStubBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. + * Copyright 2010-2017 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. @@ -14,28 +14,32 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.decompiler.builtIns +package org.jetbrains.kotlin.idea.decompiler.common +import com.intellij.openapi.fileTypes.FileType +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.idea.decompiler.common.AnnotationLoaderForStubBuilderImpl -import org.jetbrains.kotlin.idea.decompiler.common.FileWithMetadata import org.jetbrains.kotlin.idea.decompiler.stubBuilder.* -import org.jetbrains.kotlin.psi.stubs.KotlinStubVersions +import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFinder import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer import org.jetbrains.kotlin.serialization.deserialization.TypeTable -class KotlinBuiltInStubBuilder : ClsStubBuilder() { - override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + KotlinStubVersions.BUILTIN_STUB_VERSION +open class KotlinMetadataStubBuilder( + private val version: Int, + private val fileType: FileType, + private val serializerProtocol: SerializerExtensionProtocol, + private val readFile: (ByteArray, VirtualFile) -> FileWithMetadata? +) : ClsStubBuilder() { + override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + version override fun buildFileStub(content: FileContent): PsiFileStub<*>? { val virtualFile = content.file - assert(virtualFile.fileType == KotlinBuiltInFileType) { "Unexpected file type ${virtualFile.fileType}" } - val file = BuiltInDefinitionFile.read(content.content, virtualFile) ?: return null + assert(virtualFile.fileType == fileType) { "Unexpected file type ${virtualFile.fileType}" } + val file = readFile(content.content, virtualFile) ?: return null when (file) { is FileWithMetadata.Incompatible -> { @@ -47,7 +51,7 @@ class KotlinBuiltInStubBuilder : ClsStubBuilder() { val nameResolver = file.nameResolver val components = ClsStubBuilderComponents( ProtoBasedClassDataFinder(file.proto, nameResolver), - AnnotationLoaderForStubBuilderImpl(BuiltInSerializerProtocol), + AnnotationLoaderForStubBuilderImpl(serializerProtocol), virtualFile ) val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable)) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt index 69f0a78e9bf..f848aac46b1 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptMetaFileDecompiler.kt @@ -20,6 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.decompiler.common.FileWithMetadata import org.jetbrains.kotlin.idea.decompiler.common.KotlinMetadataDecompiler import org.jetbrains.kotlin.js.resolve.JsPlatform +import org.jetbrains.kotlin.psi.stubs.KotlinStubVersions import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.js.DynamicTypeDeserializer import org.jetbrains.kotlin.serialization.js.JsProtoBuf @@ -28,27 +29,20 @@ import org.jetbrains.kotlin.utils.JsMetadataVersion import java.io.ByteArrayInputStream class KotlinJavaScriptMetaFileDecompiler : KotlinMetadataDecompiler( - KotlinJavaScriptMetaFileType, KotlinJavaScriptStubBuilder(), JsPlatform, JsSerializerProtocol, DynamicTypeDeserializer, - JsMetadataVersion.INSTANCE, JsMetadataVersion.INVALID_VERSION + KotlinJavaScriptMetaFileType, JsPlatform, JsSerializerProtocol, DynamicTypeDeserializer, + JsMetadataVersion.INSTANCE, JsMetadataVersion.INVALID_VERSION, KotlinStubVersions.JS_STUB_VERSION ) { override fun readFile(bytes: ByteArray, file: VirtualFile): FileWithMetadata? { - return KjsmFile.read(bytes) - } -} + val stream = ByteArrayInputStream(bytes) -class KjsmFile(proto: ProtoBuf.PackageFragment) : FileWithMetadata.Compatible(proto, JsSerializerProtocol) { - companion object { - fun read(bytes: ByteArray): FileWithMetadata? { - val stream = ByteArrayInputStream(bytes) - - val version = JsMetadataVersion.readFrom(stream) - if (!version.isCompatible()) { - return FileWithMetadata.Incompatible(version) - } - - JsProtoBuf.Header.parseDelimitedFrom(stream) - - return KjsmFile(ProtoBuf.PackageFragment.parseFrom(stream, JsSerializerProtocol.extensionRegistry)) + val version = JsMetadataVersion.readFrom(stream) + if (!version.isCompatible()) { + return FileWithMetadata.Incompatible(version) } + + JsProtoBuf.Header.parseDelimitedFrom(stream) + + val proto = ProtoBuf.PackageFragment.parseFrom(stream, JsSerializerProtocol.extensionRegistry) + return FileWithMetadata.Compatible(proto, JsSerializerProtocol) } } 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 deleted file mode 100644 index 4bc9930f50a..00000000000 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/js/KotlinJavaScriptStubBuilder.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2010-2016 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.js - -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.idea.decompiler.common.AnnotationLoaderForStubBuilderImpl -import org.jetbrains.kotlin.idea.decompiler.common.FileWithMetadata -import org.jetbrains.kotlin.idea.decompiler.stubBuilder.* -import org.jetbrains.kotlin.psi.stubs.KotlinStubVersions -import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFinder -import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer -import org.jetbrains.kotlin.serialization.deserialization.TypeTable -import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol - -// TODO: deduplicate code with KotlinBuiltInStubBuilder -class KotlinJavaScriptStubBuilder : ClsStubBuilder() { - override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + KotlinStubVersions.JS_STUB_VERSION - - override fun buildFileStub(content: FileContent): PsiFileStub<*>? { - val virtualFile = content.file - assert(virtualFile.fileType == KotlinJavaScriptMetaFileType) { "Unexpected file type ${virtualFile.fileType}" } - val file = KjsmFile.read(content.content) ?: return null - - when (file) { - is FileWithMetadata.Incompatible -> { - return createIncompatibleAbiVersionFileStub() - } - is FileWithMetadata.Compatible -> { - val packageProto = file.proto.`package` - val packageFqName = file.packageFqName - val nameResolver = file.nameResolver - val components = ClsStubBuilderComponents( - ProtoBasedClassDataFinder(file.proto, nameResolver), - AnnotationLoaderForStubBuilderImpl(JsSerializerProtocol), - virtualFile - ) - val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable)) - - val fileStub = createFileStub(packageFqName, isScript = false) - createDeclarationsStubs( - fileStub, context, - ProtoContainer.Package(packageFqName, context.nameResolver, context.typeTable, source = null), - packageProto - ) - for (classProto in file.classesToDecompile) { - createClassStub( - fileStub, classProto, nameResolver, nameResolver.getClassId(classProto.fqName), source = null, context = context - ) - } - return fileStub - } - } - } -} diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/BuiltInDecompilerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/BuiltInDecompilerTest.kt index bfd2c70038a..e0c7811d740 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/BuiltInDecompilerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/BuiltInDecompilerTest.kt @@ -21,7 +21,7 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import com.intellij.util.indexing.FileContentImpl import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.builtins.BuiltInsBinaryVersion -import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInStubBuilder +import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInDecompiler import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.name.FqName @@ -49,7 +49,7 @@ class BuiltInDecompilerTest : AbstractBuiltInDecompilerTest() { val dirInRuntime = findDir(packageFqName, project) val kotlinBuiltInsVirtualFile = dirInRuntime.children.single { it.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION } myFixture.configureFromExistingVirtualFile(kotlinBuiltInsVirtualFile) - return KotlinBuiltInStubBuilder().buildFileStub(FileContentImpl.createByFile(kotlinBuiltInsVirtualFile))!! + return KotlinBuiltInDecompiler().stubBuilder.buildFileStub(FileContentImpl.createByFile(kotlinBuiltInsVirtualFile))!! } fun testBuiltInStubTreeEqualToStubTreeFromDecompiledText() { @@ -63,7 +63,7 @@ class BuiltInDecompilerForWrongAbiVersionTest : AbstractBuiltInDecompilerTest() override fun configureAndBuildFileStub(packageFqName: String): PsiFileStub<*> { myFixture.configureByFile(testDataPath + BuiltInSerializerProtocol.getBuiltInsFilePath(FqName(packageFqName))) - return KotlinBuiltInStubBuilder().buildFileStub(FileContentImpl.createByFile(myFixture.file.virtualFile))!! + return KotlinBuiltInDecompiler().stubBuilder.buildFileStub(FileContentImpl.createByFile(myFixture.file.virtualFile))!! } fun testStubTreesEqualForIncompatibleAbiVersion() {