[decompiler] get rid of indexers in decompiled text
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/file/KtDecompiledFile.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/file/KtDecompiledFile.kt index 76c0dc2..725b307 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/file/KtDecompiledFile.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/file/KtDecompiledFile.kt
@@ -3,11 +3,8 @@ package org.jetbrains.kotlin.analysis.decompiler.psi.file import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinDecompiledFileViewProvider import org.jetbrains.kotlin.analysis.decompiler.psi.text.DecompiledText -import org.jetbrains.kotlin.analysis.decompiler.psi.text.DecompiledTextIndexer -import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByDescriptorIndexer.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByDescriptorIndexer.kt index b7d89d6..0285a58 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByDescriptorIndexer.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByDescriptorIndexer.kt
@@ -28,11 +28,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull -object ByDescriptorIndexer : DecompiledTextIndexer<String> { - override fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<String> { - return listOf(descriptor.toStringKey()) - } - +object ByDescriptorIndexer { fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor, file: KtDecompiledFile): KtDeclaration? { val original = descriptor.original
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByJvmSignatureIndexer.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByJvmSignatureIndexer.kt deleted file mode 100644 index c4c64b7..0000000 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/ByJvmSignatureIndexer.kt +++ /dev/null
@@ -1,184 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.analysis.decompiler.psi.text - -import com.intellij.psi.PsiMember -import com.intellij.psi.impl.compiled.SignatureParsing -import com.intellij.util.cls.ClsFormatException -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.load.kotlin.MemberSignature -import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull -import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue -import org.jetbrains.kotlin.resolve.descriptorUtil.classId -import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension -import org.jetbrains.kotlin.resolve.jvm.JvmClassName -import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassConstructorDescriptor -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor -import java.text.CharacterIterator -import java.text.StringCharacterIterator - -private object ByJvmSignatureIndexer : DecompiledTextIndexer<ClassNameAndSignature> { - override fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<ClassNameAndSignature> { - val signatures = arrayListOf<ClassNameAndSignature>() - fun save(id: List<Name>, signature: MemberSignature) { - signatures.add(ClassNameAndSignature(id, signature)) - } - - fun ClassDescriptor.apply() { - when (kind) { - ClassKind.ENUM_ENTRY -> { - val enumClass = containingDeclaration as ClassDescriptor - val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), enumClass.desc()) - save(enumClass.relativeClassName(), signature) - } - ClassKind.OBJECT -> { - val instanceFieldSignature = MemberSignature.fromFieldNameAndDesc(JvmAbi.INSTANCE_FIELD, desc()) - save(relativeClassName(), instanceFieldSignature) - if (isCompanionObject) { - val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc()) - save((containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty(), signature) - } - } - else -> { - } - } - } - - fun DeserializedClassConstructorDescriptor.apply() { - JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable)?.let { - val id = (containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty() - val signature = MemberSignature.fromJvmMemberSignature(it) - save(id, signature) - } - } - - fun DeserializedSimpleFunctionDescriptor.apply() { - JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable)?.let { - val id = (containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty() - - val signature = MemberSignature.fromJvmMemberSignature(it) - save(id, signature) - - if (findJvmOverloadsAnnotation() == null) return - - val extensionShift = if (isExtension) 1 else 0 - - val omittedList = mutableListOf<Int>() - valueParameters.asReversed().forEach { parameter -> - if (parameter.hasDefaultValue()) { - omittedList.add(parameter.index + extensionShift) - val newDescriptor = excludeParametersFromDescriptor(it.desc, omittedList) - if (newDescriptor != null) { - val overloadedSignature = MemberSignature.fromMethodNameAndDesc(it.name, newDescriptor) - save(id, overloadedSignature) - } - } - } - } - } - - fun DeserializedPropertyDescriptor.apply() { - val className = (containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty() - val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) - if (signature != null) { - val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable) - if (fieldSignature != null) { - save(className, MemberSignature.fromJvmMemberSignature(fieldSignature)) - } - if (signature.hasGetter()) { - save(className, MemberSignature.fromMethod(nameResolver, signature.getter)) - } - if (signature.hasSetter()) { - save(className, MemberSignature.fromMethod(nameResolver, signature.setter)) - } - } - } - - when (descriptor) { - is ClassDescriptor -> descriptor.apply() - is DeserializedClassConstructorDescriptor -> descriptor.apply() - is DeserializedSimpleFunctionDescriptor -> descriptor.apply() - is DeserializedPropertyDescriptor -> descriptor.apply() - } - - return signatures - } -} - -private fun excludeParametersFromDescriptor(descriptor: String, omittedParameters: List<Int>): String? { - - fun tryParseParametersAndReturnType(): Pair<List<String>, String>? { - val iterator = StringCharacterIterator(descriptor) - - fun parseTypeString(): String? { - val begin = iterator.index - try { - SignatureParsing.parseTypeString(iterator) { it } - } catch (e: ClsFormatException) { - return null - } - val end = iterator.index - return descriptor.substring(begin, end) - } - - if (iterator.current() != '(') return null - iterator.next() - - if (iterator.current() == ')') { - iterator.next() - val returnType = parseTypeString() ?: return null - return emptyList<String>() to returnType - } - - val parameterTypes = mutableListOf<String>() - while (iterator.current() != ')' && iterator.current() != CharacterIterator.DONE) { - parameterTypes += parseTypeString() ?: return null - } - - if (iterator.current() != ')') return null - iterator.next() - - val returnType = parseTypeString() ?: return null - return parameterTypes to returnType - } - - val (parameterTypes, returnType) = tryParseParametersAndReturnType() ?: return null - - val parametersList = parameterTypes - .filterIndexed { index, _ -> index !in omittedParameters } - .joinToString("") - - return "($parametersList)$returnType" -} - -private fun ClassDescriptor.desc(): String = "L" + JvmClassName.byClassId(classId!!).internalName + ";" - -fun PsiMember.relativeClassName(): List<Name> { - return generateSequence(this.containingClass) { it.containingClass }.toList().dropLast(1).reversed().map { Name.identifier(it.name!!) } -} - -private fun ClassDescriptor.relativeClassName(): List<Name> { - return classId!!.relativeClassName.pathSegments().drop(1) -} - -// every member is represented by its jvm signature and relative class name (which is easy to obtain from descriptors or cls psi) - -// relative class name is a path containing inner/nested class names from top level class to the class containing this member (excluding top level class name) -// Examples: for top level function or function in a top level class relativeClassName is empty -// For: class TopLevel { class A { class B { fun f() } } } -// relativeClassName for function 'f' will be [A, B] -data class ClassNameAndSignature(val relativeClassName: List<Name>, val memberSignature: MemberSignature) - -// expose with different type -val BySignatureIndexer: DecompiledTextIndexer<*> = ByJvmSignatureIndexer
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/DecompiledText.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/DecompiledText.kt index 246eb37..aefdb8e 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/DecompiledText.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/DecompiledText.kt
@@ -5,33 +5,4 @@ package org.jetbrains.kotlin.analysis.decompiler.psi.text -import com.intellij.openapi.util.TextRange -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.utils.keysToMap - -data class DecompiledText(val text: String, val index: DecompiledTextIndex) - -interface DecompiledTextIndexer<out T : Any> { - fun indexDescriptor(descriptor: DeclarationDescriptor): Collection<T> -} - -// In-memory HashMap-based index of decompiled text -// allows navigation features -class DecompiledTextIndex(private val indexers: Collection<DecompiledTextIndexer<*>>) { - private val indexerToMap: Map<DecompiledTextIndexer<*>, MutableMap<Any, TextRange>> = indexers.keysToMap { hashMapOf<Any, TextRange>() } - - fun addToIndex(descriptor: DeclarationDescriptor, textRange: TextRange) { - indexers.forEach { mapper -> - val correspondingMap = indexerToMap.getValue(mapper) - mapper.indexDescriptor(descriptor).forEach { key -> - correspondingMap[key] = textRange - } - } - } - - fun <T : Any> getRange(mapper: DecompiledTextIndexer<T>, key: T): TextRange? = indexerToMap[mapper]?.get(key) - - companion object { - val Empty = DecompiledTextIndex(listOf()) - } -} +data class DecompiledText(val text: String) \ No newline at end of file
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledText.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledText.kt index 179c233..1d6943b 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledText.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledText.kt
@@ -61,7 +61,6 @@ packageFqName: FqName, descriptors: List<DeclarationDescriptor>, descriptorRenderer: DescriptorRenderer, - indexers: Collection<DecompiledTextIndexer<*>> = listOf(ByDescriptorIndexer), ): DecompiledText { val builder = StringBuilder() @@ -73,14 +72,7 @@ } } - val textIndex = DecompiledTextIndex(indexers) - - fun indexDescriptor(descriptor: DeclarationDescriptor, startOffset: Int, endOffset: Int) { - textIndex.addToIndex(descriptor, TextRange(startOffset, endOffset)) - } - fun appendDescriptor(descriptor: DeclarationDescriptor, indent: String, lastEnumEntry: Boolean? = null) { - val startOffset = builder.length if (isEnumEntry(descriptor)) { for (annotation in descriptor.annotations) { builder.append(descriptorRenderer.renderAnnotation(annotation)) @@ -91,7 +83,6 @@ } else { builder.append(descriptorRenderer.render(descriptor).replace("= ...", DECOMPILED_COMMENT_FOR_PARAMETER)) } - var endOffset = builder.length if (descriptor is CallableDescriptor) { //NOTE: assuming that only return types can be flexible @@ -114,7 +105,6 @@ // descriptor instanceof PropertyDescriptor builder.append(" ").append(DECOMPILED_CODE_COMMENT) } - endOffset = builder.length } if (descriptor is PropertyDescriptor) { for (accessor in descriptor.accessors) { @@ -147,7 +137,6 @@ builder.append(")") builder.append(" {").append(DECOMPILED_CODE_COMMENT).append(" }") } - endOffset = builder.length } } } else if (descriptor is ClassDescriptor && !isEnumEntry(descriptor)) { @@ -196,18 +185,9 @@ } builder.append(indent).append("}") - endOffset = builder.length } builder.append("\n") - indexDescriptor(descriptor, startOffset, endOffset) - - if (descriptor is ClassDescriptor) { - val primaryConstructor = descriptor.unsubstitutedPrimaryConstructor - if (primaryConstructor != null) { - indexDescriptor(primaryConstructor, startOffset, endOffset) - } - } } appendDecompiledTextAndPackageName() @@ -216,5 +196,5 @@ builder.append("\n") } - return DecompiledText(builder.toString(), textIndex) + return DecompiledText(builder.toString()) }
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledTextForClassFile.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledTextForClassFile.kt index 0489a81..d5e5ce0 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledTextForClassFile.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/buildDecompiledTextForClassFile.kt
@@ -33,7 +33,7 @@ fun buildText(declarations: List<DeclarationDescriptor>) = buildDecompiledText( classHeader.packageNameWithFallback, - declarations, decompilerRendererForClassFiles, listOf(ByDescriptorIndexer, BySignatureIndexer) + declarations, decompilerRendererForClassFiles ) return when (classHeader.kind) {
diff --git a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/incompatibleAbiVersion.kt b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/incompatibleAbiVersion.kt index b36bdd4..9df9cac 100644 --- a/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/incompatibleAbiVersion.kt +++ b/analysis/decompiled/decompiler-to-psi/src/org/jetbrains/kotlin/analysis/decompiler/psi/text/incompatibleAbiVersion.kt
@@ -17,6 +17,5 @@ fun <V : BinaryVersion> createIncompatibleAbiVersionDecompiledText(expectedVersion: V, actualVersion: V): DecompiledText = DecompiledText( INCOMPATIBLE_ABI_VERSION_COMMENT.replace(CURRENT_ABI_VERSION_MARKER, expectedVersion.toString()) - .replace(FILE_ABI_VERSION_MARKER, actualVersion.toString()), - DecompiledTextIndex.Empty + .replace(FILE_ABI_VERSION_MARKER, actualVersion.toString()) )
diff --git a/analysis/decompiled/light-classes-for-decompiled-fe10/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/fe10/KotlinDeclarationInCompiledFileSearcherFE10Impl.kt b/analysis/decompiled/light-classes-for-decompiled-fe10/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/fe10/KotlinDeclarationInCompiledFileSearcherFE10Impl.kt index 872f48b..50f64330 100644 --- a/analysis/decompiled/light-classes-for-decompiled-fe10/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/fe10/KotlinDeclarationInCompiledFileSearcherFE10Impl.kt +++ b/analysis/decompiled/light-classes-for-decompiled-fe10/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/fe10/KotlinDeclarationInCompiledFileSearcherFE10Impl.kt
@@ -6,19 +6,16 @@ package org.jetbrains.kotlin.analysis.decompiled.light.classes.fe10 import com.intellij.psi.PsiMember -import com.intellij.psi.PsiMethod import org.jetbrains.kotlin.analysis.decompiled.light.classes.origin.KotlinDeclarationInCompiledFileSearcher import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile -import org.jetbrains.kotlin.analysis.decompiler.psi.text.BySignatureIndexer -import org.jetbrains.kotlin.analysis.decompiler.psi.text.ClassNameAndSignature -import org.jetbrains.kotlin.analysis.decompiler.psi.text.relativeClassName import org.jetbrains.kotlin.load.kotlin.MemberSignature -import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtDeclaration class KotlinDeclarationInCompiledFileSearcherFE10Impl : KotlinDeclarationInCompiledFileSearcher() { override fun findDeclarationInCompiledFile(file: KtClsFile, member: PsiMember, signature: MemberSignature): KtDeclaration? { - val relativeClassName = member.relativeClassName() + val relativeClassName = generateSequence(member.containingClass) { it.containingClass }.toList().dropLast(1).reversed() + .map { Name.identifier(it.name!!) } val memberName = member.name ?: return null return findByStubs(file, relativeClassName, member, memberName)