Combine cls stub builders for built-ins and JS
This commit is contained in:
+4
-2
@@ -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<BuiltInsBinaryVersion>(
|
||||
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)
|
||||
|
||||
+4
-3
@@ -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<out V : BinaryVersion>(
|
||||
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?
|
||||
|
||||
+15
-11
@@ -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))
|
||||
+12
-18
@@ -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<JsMetadataVersion>(
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
-71
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user