summaryrefslogtreecommitdiff
path: root/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt')
-rw-r--r--plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt283
1 files changed, 0 insertions, 283 deletions
diff --git a/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt b/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt
deleted file mode 100644
index 10d644a05b6f..000000000000
--- a/plugins/kotlin/analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-
-package org.jetbrains.kotlin.idea.decompiler.stubBuilder
-
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.psi.PsiElement
-import com.intellij.psi.stubs.StubElement
-import org.jetbrains.kotlin.builtins.StandardNames
-import org.jetbrains.kotlin.builtins.isNumberedFunctionClassFqName
-import org.jetbrains.kotlin.descriptors.SourceElement
-import org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags.*
-import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.metadata.ProtoBuf
-import org.jetbrains.kotlin.metadata.deserialization.Flags
-import org.jetbrains.kotlin.metadata.deserialization.NameResolver
-import org.jetbrains.kotlin.metadata.deserialization.TypeTable
-import org.jetbrains.kotlin.metadata.deserialization.supertypes
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.psi.KtClassBody
-import org.jetbrains.kotlin.psi.KtSuperTypeEntry
-import org.jetbrains.kotlin.psi.KtSuperTypeList
-import org.jetbrains.kotlin.psi.stubs.elements.KtClassElementType
-import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
-import org.jetbrains.kotlin.psi.stubs.impl.KotlinClassStubImpl
-import org.jetbrains.kotlin.psi.stubs.impl.KotlinModifierListStubImpl
-import org.jetbrains.kotlin.psi.stubs.impl.KotlinObjectStubImpl
-import org.jetbrains.kotlin.psi.stubs.impl.KotlinPlaceHolderStubImpl
-import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
-import org.jetbrains.kotlin.serialization.deserialization.getClassId
-import org.jetbrains.kotlin.serialization.deserialization.getName
-
-fun createClassStub(
- parent: StubElement<out PsiElement>,
- classProto: ProtoBuf.Class,
- nameResolver: NameResolver,
- classId: ClassId,
- source: SourceElement?,
- context: ClsStubBuilderContext
-) {
- ClassClsStubBuilder(parent, classProto, nameResolver, classId, source, context).build()
-}
-
-private class ClassClsStubBuilder(
- private val parentStub: StubElement<out PsiElement>,
- private val classProto: ProtoBuf.Class,
- nameResolver: NameResolver,
- private val classId: ClassId,
- source: SourceElement?,
- outerContext: ClsStubBuilderContext
-) {
- private val thisAsProtoContainer = ProtoContainer.Class(
- classProto, nameResolver, TypeTable(classProto.typeTable), source, outerContext.protoContainer
- )
- private val classKind = thisAsProtoContainer.kind
-
- private val c = outerContext.child(
- classProto.typeParameterList, classId.shortClassName, nameResolver, thisAsProtoContainer.typeTable, thisAsProtoContainer
- )
- private val typeStubBuilder = TypeClsStubBuilder(c)
- private val supertypeIds = run {
- val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) }
- //empty supertype list if single supertype is Any
- if (supertypeIds.singleOrNull()?.let { StandardNames.FqNames.any == it.asSingleFqName().toUnsafe() } == true) {
- listOf()
- } else {
- supertypeIds
- }
- }
-
- private val companionObjectName = if (classProto.hasCompanionObjectName())
- c.nameResolver.getName(classProto.companionObjectName)
- else
- null
-
- private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
-
- fun build() {
- val typeConstraintListData = typeStubBuilder.createTypeParameterListStub(classOrObjectStub, classProto.typeParameterList)
- createConstructorStub()
- createDelegationSpecifierList()
- typeStubBuilder.createTypeConstraintListStub(classOrObjectStub, typeConstraintListData)
- createClassBodyAndMemberStubs()
- }
-
- private fun createClassOrObjectStubAndModifierListStub(): StubElement<out PsiElement> {
- val classOrObjectStub = doCreateClassOrObjectStub()
- val modifierList = createModifierListForClass(classOrObjectStub)
- if (Flags.HAS_ANNOTATIONS.get(classProto.flags)) {
- createAnnotationStubs(c.components.annotationLoader.loadClassAnnotations(thisAsProtoContainer), modifierList)
- }
- return classOrObjectStub
- }
-
- private fun createModifierListForClass(parent: StubElement<out PsiElement>): KotlinModifierListStubImpl {
- val relevantFlags = arrayListOf(VISIBILITY)
- relevantFlags.add(EXTERNAL_CLASS)
- if (isClass()) {
- relevantFlags.add(INNER)
- relevantFlags.add(DATA)
- relevantFlags.add(MODALITY)
- relevantFlags.add(VALUE_CLASS)
- }
- if (isInterface()) {
- relevantFlags.add(FUN_INTERFACE)
- }
- val additionalModifiers = when (classKind) {
- ProtoBuf.Class.Kind.ENUM_CLASS -> listOf(KtTokens.ENUM_KEYWORD)
- ProtoBuf.Class.Kind.COMPANION_OBJECT -> listOf(KtTokens.COMPANION_KEYWORD)
- ProtoBuf.Class.Kind.ANNOTATION_CLASS -> listOf(KtTokens.ANNOTATION_KEYWORD)
- else -> listOf<KtModifierKeywordToken>()
- }
- return createModifierListStubForDeclaration(parent, classProto.flags, relevantFlags, additionalModifiers)
- }
-
- private fun doCreateClassOrObjectStub(): StubElement<out PsiElement> {
- val isCompanionObject = classKind == ProtoBuf.Class.Kind.COMPANION_OBJECT
- val fqName = classId.asSingleFqName()
- val shortName = fqName.shortName().ref()
- val superTypeRefs = supertypeIds.filterNot {
- //TODO: filtering function types should go away
- isNumberedFunctionClassFqName(it.asSingleFqName().toUnsafe())
- }.map { it.shortClassName.ref() }.toTypedArray()
- val classId = classId.takeUnless { it.isLocal }
- return when (classKind) {
- ProtoBuf.Class.Kind.OBJECT, ProtoBuf.Class.Kind.COMPANION_OBJECT -> {
- KotlinObjectStubImpl(
- parentStub, shortName, fqName,
- classId = classId,
- superTypeRefs,
- isTopLevel = !this.classId.isNestedClass,
- isDefault = isCompanionObject,
- isLocal = false,
- isObjectLiteral = false,
- )
- }
- else -> {
- KotlinClassStubImpl(
- KtClassElementType.getStubType(classKind == ProtoBuf.Class.Kind.ENUM_ENTRY),
- parentStub,
- fqName.ref(),
- classId = classId,
- shortName,
- superTypeRefs,
- isInterface = classKind == ProtoBuf.Class.Kind.INTERFACE,
- isEnumEntry = classKind == ProtoBuf.Class.Kind.ENUM_ENTRY,
- isLocal = false,
- isTopLevel = !this.classId.isNestedClass,
- )
- }
- }
- }
-
- private fun createConstructorStub() {
- if (!isClass()) return
-
- val primaryConstructorProto = classProto.constructorList.find { !Flags.IS_SECONDARY.get(it.flags) } ?: return
-
- createConstructorStub(classOrObjectStub, primaryConstructorProto, c, thisAsProtoContainer)
- }
-
- private fun createDelegationSpecifierList() {
- // if single supertype is any then no delegation specifier list is needed
- if (supertypeIds.isEmpty()) return
-
- val delegationSpecifierListStub = KotlinPlaceHolderStubImpl<KtSuperTypeList>(classOrObjectStub, KtStubElementTypes.SUPER_TYPE_LIST)
-
- classProto.supertypes(c.typeTable).forEach { type ->
- val superClassStub = KotlinPlaceHolderStubImpl<KtSuperTypeEntry>(
- delegationSpecifierListStub, KtStubElementTypes.SUPER_TYPE_ENTRY
- )
- typeStubBuilder.createTypeReferenceStub(superClassStub, type)
- }
- }
-
- private fun createClassBodyAndMemberStubs() {
- val classBody = KotlinPlaceHolderStubImpl<KtClassBody>(classOrObjectStub, KtStubElementTypes.CLASS_BODY)
- createEnumEntryStubs(classBody)
- createCompanionObjectStub(classBody)
- createCallableMemberStubs(classBody)
- createInnerAndNestedClasses(classBody)
- createTypeAliasesStubs(classBody)
- }
-
- private fun createCompanionObjectStub(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
- if (companionObjectName == null) {
- return
- }
-
- val companionObjectId = classId.createNestedClassId(companionObjectName)
- createNestedClassStub(classBody, companionObjectId)
- }
-
- private fun createEnumEntryStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
- if (classKind != ProtoBuf.Class.Kind.ENUM_CLASS) return
-
- classProto.enumEntryList.forEach { entry ->
- val name = c.nameResolver.getName(entry.name)
- val annotations = c.components.annotationLoader.loadEnumEntryAnnotations(thisAsProtoContainer, entry)
- val enumEntryStub = KotlinClassStubImpl(
- KtStubElementTypes.ENUM_ENTRY,
- classBody,
- qualifiedName = c.containerFqName.child(name).ref(),
- classId = null, // enum entry do not have class id
- name = name.ref(),
- superNames = arrayOf(),
- isInterface = false,
- isEnumEntry = true,
- isLocal = false,
- isTopLevel = false
- )
- if (annotations.isNotEmpty()) {
- createAnnotationStubs(annotations, createEmptyModifierListStub(enumEntryStub))
- }
- }
- }
-
- private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
- for (secondaryConstructorProto in classProto.constructorList) {
- if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {
- createConstructorStub(classBody, secondaryConstructorProto, c, thisAsProtoContainer)
- }
- }
-
- createDeclarationsStubs(classBody, c, thisAsProtoContainer, classProto.functionList, classProto.propertyList)
- }
-
- private fun isClass(): Boolean {
- return classKind == ProtoBuf.Class.Kind.CLASS ||
- classKind == ProtoBuf.Class.Kind.ENUM_CLASS ||
- classKind == ProtoBuf.Class.Kind.ANNOTATION_CLASS
- }
-
- private fun isInterface(): Boolean {
- return classKind == ProtoBuf.Class.Kind.INTERFACE
- }
-
- private fun createInnerAndNestedClasses(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
- classProto.nestedClassNameList.forEach { id ->
- val nestedClassName = c.nameResolver.getName(id)
- if (nestedClassName != companionObjectName) {
- val nestedClassId = classId.createNestedClassId(nestedClassName)
- createNestedClassStub(classBody, nestedClassId)
- }
- }
- }
-
- private fun createTypeAliasesStubs(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
- createTypeAliasesStubs(classBody, c, thisAsProtoContainer, classProto.typeAliasList)
- }
-
- private fun createNestedClassStub(classBody: StubElement<out PsiElement>, nestedClassId: ClassId) {
- val (nameResolver, classProto, _, sourceElement) =
- c.components.classDataFinder.findClassData(nestedClassId)
- ?: c.components.virtualFileForDebug.let { rootFile ->
- val outerClassId = nestedClassId.outerClassId
- val sortedChildren = rootFile.parent.children.sortedBy { it.name }
- val msgPrefix = "Could not find data for nested class $nestedClassId of class $outerClassId\n"
- val explanation = when {
- outerClassId != null && sortedChildren.none { it.name.startsWith("${outerClassId.relativeClassName}\$a") } ->
- // KT-29427: case with obfuscation
- "Reason: obfuscation suspected (single-letter name)\n"
- else ->
- // General case
- ""
- }
- val msg = msgPrefix + explanation +
- "Root file: ${rootFile.canonicalPath}\n" +
- "Dir: ${rootFile.parent.canonicalPath}\n" +
- "Children:\n" +
- sortedChildren.joinToString(separator = "\n") {
- "${it.name} (valid: ${it.isValid})"
- }
- LOG.info(msg)
- return
- }
- createClassStub(classBody, classProto, nameResolver, nestedClassId, sourceElement, c)
- }
-
- companion object {
- private val LOG = Logger.getInstance(ClassClsStubBuilder::class.java)
- }
-}