[SLC] Fix nested classes missing in SLC structure tests for libraries

^KT-62038 fixed
This commit is contained in:
Marco Pennekamp
2023-09-21 00:12:41 +02:00
committed by Space Team
parent 315573d99f
commit cd8143af7b
2 changed files with 170 additions and 16 deletions
@@ -0,0 +1,145 @@
B.class:
KtClass:
line: 5
name: NestedInB
qualifier: B.NestedInB
light: KtLightClassForDecompiledDeclaration
name: NestedInB
qualifier: B.NestedInB
superTypes: [
PsiType:NestedInNestedInA
]
superClass: KtLightClassForDecompiledDeclaration: NestedInNestedInA (A.NestedInA.NestedInNestedInA)
interfaces: []
supers: [
KtLightClassForDecompiledDeclaration: NestedInNestedInA (A.NestedInA.NestedInNestedInA)
]
KtClass:
line: 8
name: InnerInB
qualifier: B.InnerInB
light: KtLightClassForDecompiledDeclaration
name: InnerInB
qualifier: B.InnerInB
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
KtClass:
line: 4
name: B
qualifier: B
light: KtLightClassForDecompiledDeclaration
name: B
qualifier: B
superTypes: [
PsiType:A
]
superClass: KtLightClassForDecompiledDeclaration: A (A)
interfaces: []
supers: [
KtLightClassForDecompiledDeclaration: A (A)
]
A.class:
KtClass:
line: 6
name: NestedInNestedInA
qualifier: A.NestedInA.NestedInNestedInA
light: KtLightClassForDecompiledDeclaration
name: NestedInNestedInA
qualifier: A.NestedInA.NestedInNestedInA
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
KtClass:
line: 9
name: InnerInNestedInA
qualifier: A.NestedInA.InnerInNestedInA
light: KtLightClassForDecompiledDeclaration
name: InnerInNestedInA
qualifier: A.NestedInA.InnerInNestedInA
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
KtClass:
line: 5
name: NestedInA
qualifier: A.NestedInA
light: KtLightClassForDecompiledDeclaration
name: NestedInA
qualifier: A.NestedInA
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
KtClass:
line: 14
name: InnerInInnerInA
qualifier: A.InnerInA.InnerInInnerInA
light: KtLightClassForDecompiledDeclaration
name: InnerInInnerInA
qualifier: A.InnerInA.InnerInInnerInA
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
KtClass:
line: 13
name: InnerInA
qualifier: A.InnerInA
light: KtLightClassForDecompiledDeclaration
name: InnerInA
qualifier: A.InnerInA
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
KtClass:
line: 4
name: A
qualifier: A
light: KtLightClassForDecompiledDeclaration
name: A
qualifier: A
superTypes: [
PsiType:Object
]
superClass: ClsClassImpl: Object (java.lang.Object)
interfaces: []
supers: [
ClsClassImpl: Object (java.lang.Object)
]
@@ -12,7 +12,6 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtFile
@@ -101,24 +100,14 @@ open class AbstractSymbolLightClassesStructureTestBase(
}.toSet()
private fun wrongInheritorStructure(line: String): Nothing = error("Can't parse '$line' line correctly")
protected fun PrettyPrinter.handleFile(ktFile: KtFile) {
val text = ktFile.text
if (ktFile.isCompiled) {
ktFile.declarations.forEach { classOrObject ->
if (classOrObject is KtClassOrObject) {
if (classOrObject is KtClass && classOrObject.isEnum()) {
classOrObject.declarations.forEach { declaration ->
if (declaration is KtEnumEntry) {
handleClassDeclaration(declaration, text)
appendLine()
}
}
}
handleClassDeclaration(classOrObject, text)
appendLine()
}
}
// A compiled file for a class should only contain a single class declaration. `*Kt.class` files on the other hand may contain
// top-level callables and need to be skipped.
val classOrObject = ktFile.declarations.singleOrNull() as? KtClassOrObject ?: return
handleCompiledClassDeclaration(classOrObject, text)
} else {
ktFile.forEachDescendantOfType<KtClassOrObject> { classOrObject ->
handleClassDeclaration(classOrObject, text)
@@ -127,6 +116,26 @@ open class AbstractSymbolLightClassesStructureTestBase(
}
}
/**
* [handleCompiledClassDeclaration] uses a custom traversal instead of [forEachDescendantOfType] because trying to access the PSI of
* compiled code in this test results in exceptions. Hence, we have to traverse nested classes and enum entries manually.
*/
private fun PrettyPrinter.handleCompiledClassDeclaration(classOrObject: KtClassOrObject, text: String) {
classOrObject.declarations.forEach { declaration ->
when (declaration) {
is KtEnumEntry -> {
// We don't call `handleCompiledClassDeclaration` to avoid printing class declarations inside enum entry initializers.
handleClassDeclaration(declaration, text)
appendLine()
}
is KtClassOrObject -> handleCompiledClassDeclaration(declaration, text)
}
}
handleClassDeclaration(classOrObject, text)
appendLine()
}
private fun PrettyPrinter.handleClassDeclaration(declaration: KtClassOrObject, fileText: String) {
appendLine("${declaration::class.simpleName}:")
withIndent {