diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextConsistencyTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextConsistencyTest.kt index c107ff21c63..81157086bb4 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextConsistencyTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextConsistencyTest.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.idea.test.JetWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.PluginTestCaseBase @@ -26,15 +27,18 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.descriptors.PackageFacadeProvider +import org.jetbrains.kotlin.idea.caches.resolve.IDEPackageFacadeProvider public class DecompiledTextConsistencyTest : TextConsistencyBaseTest() { - override fun getPackages(): List = listOf(FqName("kotlin")) + override fun getPackages(): List = emptyList() - override fun getTopLevelMembers(): Map = mapOf("kotlin" to "linkedListOf") + override fun getFacades(): List = listOf(FqName("kotlin.JUtilKt")) + + override fun getTopLevelMembers(): Map = mapOf("kotlin.JUtilKt" to "linkedListOf") override fun getVirtualFileFinder(): VirtualFileFinder = - JvmVirtualFileFinder.SERVICE.getInstance(getProject()) + JvmVirtualFileFinder.SERVICE.getInstance(getProject()) override fun getDecompiledText(packageFile: VirtualFile, resolver: ResolverForDecompiler?): String = (resolver?.let { buildDecompiledText(packageFile, it) } ?: buildDecompiledText(packageFile)).text @@ -42,10 +46,12 @@ public class DecompiledTextConsistencyTest : TextConsistencyBaseTest() { override fun getModuleDescriptor(): ModuleDescriptor = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext( TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(getProject(), "test"), - listOf(), BindingTraceContext(), null, null, PackageFacadeProvider.EMPTY + listOf(), BindingTraceContext(), null, null, + IDEPackageFacadeProvider(GlobalSearchScope.allScope(project)) ).moduleDescriptor - override fun getProjectDescriptor() = object : JetWithJdkAndRuntimeLightProjectDescriptor() { - override fun getSdk() = PluginTestCaseBase.fullJdk() - } + override fun getProjectDescriptor() = + object : JetWithJdkAndRuntimeLightProjectDescriptor() { + override fun getSdk() = PluginTestCaseBase.fullJdk() + } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/TextConsistencyBaseTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/TextConsistencyBaseTest.kt index bd48fa363f9..52fa029b0f7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/TextConsistencyBaseTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/TextConsistencyBaseTest.kt @@ -25,18 +25,23 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.kotlin.PackageClassUtils +import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.MemberComparator import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.junit.Assert public abstract class TextConsistencyBaseTest : JetLightCodeInsightFixtureTestCase() { protected abstract fun getPackages(): List + protected open fun getFacades(): List = emptyList() + protected abstract fun getTopLevelMembers(): Map protected abstract fun getVirtualFileFinder(): VirtualFileFinder @@ -46,16 +51,25 @@ public abstract class TextConsistencyBaseTest : JetLightCodeInsightFixtureTestCa protected abstract fun getModuleDescriptor(): ModuleDescriptor public fun testConsistency() { - getPackages().forEach { doTest(it) } + getPackages().forEach { doTestPackage(it) } + getFacades().forEach { doTestFacade(it) } } - private fun doTest(packageFqName: FqName) { - val packageFile = getVirtualFileFinder().findVirtualFileWithHeader(PackageClassUtils.getPackageClassId(packageFqName))!! - val projectBasedText = getDecompiledText(packageFile, ResolverForDecompilerImpl(getModuleDescriptor())) - val deserializedText = getDecompiledText(packageFile) + private fun doTestPackage(packageFqName: FqName) { + doTestClass(packageFqName, PackageClassUtils.getPackageClassId(packageFqName)) + } + + private fun doTestFacade(facadeFqName: FqName) { + doTestClass(facadeFqName, ClassId.topLevel(facadeFqName)) + } + + private fun doTestClass(testFqName: FqName, classId: ClassId) { + val classFile = getVirtualFileFinder().findVirtualFileWithHeader(classId)!! + val projectBasedText = getDecompiledText(classFile, ResolverForDecompilerImpl(getModuleDescriptor())) + val deserializedText = getDecompiledText(classFile) Assert.assertEquals(projectBasedText, deserializedText) // sanity checks - getTopLevelMembers()[packageFqName.asString()]?.let { + getTopLevelMembers()[testFqName.asString()]?.let { Assert.assertTrue(projectBasedText.contains(it)) } Assert.assertFalse(projectBasedText.contains("ERROR")) @@ -63,14 +77,17 @@ public abstract class TextConsistencyBaseTest : JetLightCodeInsightFixtureTestCa } private class ResolverForDecompilerImpl(val module: ModuleDescriptor) : ResolverForDecompiler { - override fun resolveTopLevelClass(classId: ClassId): ClassDescriptor? { - return module.resolveTopLevelClass(classId.asSingleFqName(), NoLookupLocation.FROM_TEST) - } + override fun resolveTopLevelClass(classId: ClassId): ClassDescriptor? = + module.resolveTopLevelClass(classId.asSingleFqName(), NoLookupLocation.FROM_TEST) - override fun resolveDeclarationsInFacade(facadeFqName: FqName): Collection { - // TODO how to handle non-package facades properly here? - return module.getPackage(facadeFqName.parent()).memberScope.getAllDescriptors() filter { - it is CallableMemberDescriptor && it.module != KotlinBuiltIns.getInstance().getBuiltInsModule() - } sortBy MemberComparator.INSTANCE - } + override fun resolveDeclarationsInFacade(facadeFqName: FqName): Collection = + module.getPackage(facadeFqName.parent()).memberScope.getAllDescriptors().filter { + it is CallableMemberDescriptor && + it.module != KotlinBuiltIns.getInstance().builtInsModule && + (it is DeserializedCallableMemberDescriptor && isFromFacade(it, facadeFqName)) + }.sortedWith(MemberComparator.INSTANCE) + + private fun isFromFacade(descriptor: DeserializedCallableMemberDescriptor, facadeFqName: FqName): Boolean = + descriptor.proto.hasExtension(JvmProtoBuf.implClassName) && + facadeFqName == PackagePartClassUtils.getPackagePartFqName(descriptor) }