diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt index 5cfaf814ea1..3900273628a 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeProvider.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.StandardClassIds @@ -47,8 +48,12 @@ import org.jetbrains.kotlin.types.checker.intersectWrappedTypes import org.jetbrains.kotlin.types.error.ErrorType import org.jetbrains.kotlin.types.error.ErrorTypeKind import org.jetbrains.kotlin.types.error.ErrorUtils +import org.jetbrains.kotlin.types.typeUtil.builtIns +import org.jetbrains.kotlin.types.typeUtil.isGenericArrayOfTypeParameter import org.jetbrains.kotlin.types.typeUtil.isNothing +import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.util.containingNonLocalDeclaration +import org.jetbrains.kotlin.utils.addToStdlib.applyIf internal class KtFe10TypeProvider( override val analysisSession: KtFe10AnalysisSession @@ -146,6 +151,16 @@ internal class KtFe10TypeProvider( return descriptor.dispatchReceiverParameter?.type?.toKtType(analysisContext) } + override fun getArrayElementType(type: KtType): KtType? { + require(type is KtFe10Type) + val fe10Type = type.fe10Type + + if (!KotlinBuiltIns.isArrayOrPrimitiveArray(fe10Type)) return null + + val arrayElementType = fe10Type.builtIns.getArrayElementType(fe10Type) + return arrayElementType.toKtType(analysisContext) + } + private fun areTypesCompatible(a: KotlinType, b: KotlinType): Boolean { if (a.isNothing() || b.isNothing() || TypeUtils.equalTypes(a, b) || (a.isNullable() && b.isNullable())) { return true diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt index 4e5a6d02103..6dcb7a508c6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt @@ -266,5 +266,10 @@ internal class KtFirTypeProvider( } return firSymbol.dispatchReceiverType(analysisSession.firSymbolBuilder) } + + override fun getArrayElementType(type: KtType): KtType? { + require(type is KtFirType) + return type.coneType.arrayElementType()?.asKtType() + } } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt index b951372b74c..d6d77f25e48 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt @@ -42,6 +42,8 @@ public abstract class KtTypeProvider : KtAnalysisSessionComponent() { public abstract fun getAllSuperTypes(type: KtType, shouldApproximate: Boolean): List public abstract fun getDispatchReceiverType(symbol: KtCallableSymbol): KtType? + + public abstract fun getArrayElementType(type: KtType): KtType? } public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { @@ -152,6 +154,12 @@ public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { @Deprecated("Avoid using this function") public fun KtCallableSymbol.getDispatchReceiverType(): KtType? = withValidityAssertion { analysisSession.typeProvider.getDispatchReceiverType(this) } + + /** + * If provided [KtType] is a primitive type array or [Array], returns the type of the array's elements. Otherwise, returns null. + */ + public fun KtType.getArrayElementType(): KtType? = + withValidityAssertion { analysisSession.typeProvider.getArrayElementType(this) } } @Suppress("PropertyName")