[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 com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
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.name.CallableId
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
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 {
|
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 {
|
fun create(data: String): SymbolData = when {
|
||||||
data == "script" -> ScriptData
|
data == "script" -> ScriptData
|
||||||
data.startsWith("class:") -> ClassData(ClassId.fromString(data.removePrefix("class:").trim()))
|
data.startsWith("class:") -> ClassData(ClassId.fromString(data.removePrefix("class:").trim()))
|
||||||
data.startsWith("typealias:") -> TypeAliasData(ClassId.fromString(data.removePrefix("typealias:").trim()))
|
data.startsWith("typealias:") -> TypeAliasData(ClassId.fromString(data.removePrefix("typealias:").trim()))
|
||||||
data.startsWith("callable:") -> {
|
data.startsWith("callable:") -> CallableData(extractCallableId(data, "callable:"))
|
||||||
val fullName = data.removePrefix("callable:").trim()
|
data.startsWith("enum_entry_initializer") -> EnumEntryInitializerData(extractCallableId(data, "enum_entry_initializer:"))
|
||||||
val name = if ('.' in fullName) fullName.substringAfterLast(".") else fullName.substringAfterLast('/')
|
else -> error("Invalid symbol kind, expected one of: $identifiers")
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): SymbolsData {
|
||||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath)
|
val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath)
|
||||||
val symbols = with(symbolData) { toSymbols(ktFile) }
|
val symbols = with(symbolData) { toSymbols(ktFile) }
|
||||||
val classSymbol = symbols.singleOrNull() as? KtSymbolWithMembers
|
val symbolWithMembers = symbols.singleOrNull() as? KtSymbolWithMembers
|
||||||
?: error("Should be a single class symbol, but $symbols found")
|
?: error("Should be a single `${KtSymbolWithMembers::class.simpleName}`, but $symbols found.")
|
||||||
return SymbolsData(classSymbol.getMemberScope().getAllSymbols().toList())
|
return SymbolsData(symbolWithMembers.getMemberScope().getAllSymbols().toList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user