[AA] Support enum entry initializers in member scope tests
- Now that the enum entry initializer provides a member scope, not the enum entry, we need a way to get to the enum entry initializer in tests. This can only be done via the enum entry's name, because the initializer is anonymous. ^KT-61425
This commit is contained in:
committed by
Space Team
parent
80efa34926
commit
3add7f9db5
+35
-15
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -83,28 +85,46 @@ sealed class SymbolData {
|
||||
}
|
||||
}
|
||||
|
||||
data class EnumEntryInitializerData(val enumEntryId: CallableId) : SymbolData() {
|
||||
override fun KtAnalysisSession.toSymbols(ktFile: KtFile): List<KtSymbol> {
|
||||
val classSymbol = enumEntryId.classId?.let { getClassOrObjectSymbolByClassId(it) }
|
||||
?: error("Cannot find enum class `${enumEntryId.classId}`.")
|
||||
|
||||
require(classSymbol is KtNamedClassOrObjectSymbol) { "`${enumEntryId.classId}` must be a named class." }
|
||||
require(classSymbol.classKind == KtClassKind.ENUM_CLASS) { "`${enumEntryId.classId}` must be an enum class." }
|
||||
|
||||
val enumEntrySymbol = classSymbol.getEnumEntries().find { it.name == enumEntryId.callableName }
|
||||
?: error("Cannot find enum entry symbol `$enumEntryId`.")
|
||||
|
||||
val initializerSymbol = enumEntrySymbol.enumEntryInitializer ?: error("`${enumEntryId.callableName}` must have an initializer.")
|
||||
return listOf(initializerSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val identifiers: List<String> = listOf("callable:", "class:", "typealias:", "script")
|
||||
val identifiers = arrayOf("callable:", "class:", "typealias:", "enum_entry_initializer:", "script")
|
||||
|
||||
fun create(data: String): SymbolData = when {
|
||||
data == "script" -> ScriptData
|
||||
data.startsWith("class:") -> ClassData(ClassId.fromString(data.removePrefix("class:").trim()))
|
||||
data.startsWith("typealias:") -> TypeAliasData(ClassId.fromString(data.removePrefix("typealias:").trim()))
|
||||
data.startsWith("callable:") -> {
|
||||
val fullName = data.removePrefix("callable:").trim()
|
||||
val name = if ('.' in fullName) fullName.substringAfterLast(".") else fullName.substringAfterLast('/')
|
||||
val (packageName, className) = run {
|
||||
val packageNameWithClassName = fullName.dropLast(name.length + 1)
|
||||
when {
|
||||
'.' in fullName ->
|
||||
packageNameWithClassName.substringBeforeLast('/') to packageNameWithClassName.substringAfterLast('/')
|
||||
else -> packageNameWithClassName to null
|
||||
}
|
||||
}
|
||||
CallableData(CallableId(FqName(packageName.replace('/', '.')), className?.let { FqName(it) }, Name.identifier(name)))
|
||||
}
|
||||
else -> error("Invalid symbol")
|
||||
data.startsWith("callable:") -> CallableData(extractCallableId(data, "callable:"))
|
||||
data.startsWith("enum_entry_initializer") -> EnumEntryInitializerData(extractCallableId(data, "enum_entry_initializer:"))
|
||||
else -> error("Invalid symbol kind, expected one of: $identifiers")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractCallableId(data: String, prefix: String): CallableId {
|
||||
val fullName = data.removePrefix(prefix).trim()
|
||||
val name = if ('.' in fullName) fullName.substringAfterLast(".") else fullName.substringAfterLast('/')
|
||||
val (packageName, className) = run {
|
||||
val packageNameWithClassName = fullName.dropLast(name.length + 1)
|
||||
when {
|
||||
'.' in fullName ->
|
||||
packageNameWithClassName.substringBeforeLast('/') to packageNameWithClassName.substringAfterLast('/')
|
||||
else -> packageNameWithClassName to null
|
||||
}
|
||||
}
|
||||
return CallableId(FqName(packageName.replace('/', '.')), className?.let { FqName(it) }, Name.identifier(name))
|
||||
}
|
||||
|
||||
+3
-3
@@ -18,8 +18,8 @@ abstract class AbstractMemberScopeByFqNameTest : AbstractSymbolByFqNameTest() {
|
||||
override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): SymbolsData {
|
||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath)
|
||||
val symbols = with(symbolData) { toSymbols(ktFile) }
|
||||
val classSymbol = symbols.singleOrNull() as? KtSymbolWithMembers
|
||||
?: error("Should be a single class symbol, but $symbols found")
|
||||
return SymbolsData(classSymbol.getMemberScope().getAllSymbols().toList())
|
||||
val symbolWithMembers = symbols.singleOrNull() as? KtSymbolWithMembers
|
||||
?: error("Should be a single `${KtSymbolWithMembers::class.simpleName}`, but $symbols found.")
|
||||
return SymbolsData(symbolWithMembers.getMemberScope().getAllSymbols().toList())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user