diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeInfoProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeInfoProvider.kt index 06170b0ba5c..bb1b0952be5 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeInfoProvider.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeInfoProvider.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnaly import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import org.jetbrains.kotlin.builtins.getFunctionalClassKind import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils @@ -46,6 +47,19 @@ internal class KtFe10TypeInfoProvider( return kotlinType.isDenotable() } + override fun isArrayOrPrimitiveArray(type: KtType): Boolean { + require(type is KtFe10Type) + return KotlinBuiltIns.isArrayOrPrimitiveArray(type.type) + } + + override fun isNestedArray(type: KtType): Boolean { + if (!isArrayOrPrimitiveArray(type)) return false + require(type is KtFe10Type) + val unwrappedType = type.type + val elementType = unwrappedType.constructor.builtIns.getArrayElementType(unwrappedType) + return KotlinBuiltIns.isArrayOrPrimitiveArray(elementType) + } + private fun KotlinType.isDenotable(): Boolean { if (this is DefinitelyNotNullType) return false return constructor.isDenotable && diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt index cae7d47d819..81c27fe1588 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeInfoProvider.kt @@ -13,9 +13,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import org.jetbrains.kotlin.fir.resolve.FirSamResolverImpl -import org.jetbrains.kotlin.fir.types.canBeNull -import org.jetbrains.kotlin.fir.types.functionClassKind -import org.jetbrains.kotlin.fir.types.typeApproximator +import org.jetbrains.kotlin.fir.types.* internal class KtFirTypeInfoProvider( override val analysisSession: KtFirAnalysisSession, @@ -46,4 +44,15 @@ internal class KtFirTypeInfoProvider( PublicTypeApproximator.PublicApproximatorConfiguration(false) ) == null } + + override fun isArrayOrPrimitiveArray(type: KtType): Boolean { + require(type is KtFirType) + return type.coneType.isArrayOrPrimitiveArray + } + + override fun isNestedArray(type: KtType): Boolean { + if (!isArrayOrPrimitiveArray(type)) return false + require(type is KtFirType) + return type.coneType.arrayElementType()?.isArrayOrPrimitiveArray == true + } } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeInfoProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeInfoProvider.kt index 776ba6aea3a..6f7f297ec40 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeInfoProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeInfoProvider.kt @@ -21,6 +21,8 @@ public abstract class KtTypeInfoProvider : KtAnalysisSessionComponent() { public abstract fun getFunctionClassKind(type: KtType): FunctionClassKind? public abstract fun canBeNull(type: KtType): Boolean public abstract fun isDenotable(type: KtType): Boolean + public abstract fun isArrayOrPrimitiveArray(type: KtType): Boolean + public abstract fun isNestedArray(type: KtType): Boolean } public interface KtTypeInfoProviderMixIn : KtAnalysisSessionMixIn { @@ -100,6 +102,17 @@ public interface KtTypeInfoProviderMixIn : KtAnalysisSessionMixIn { } } + /** + * Returns whether the given [KtType] is an array or a primitive array type or not. + */ + public fun KtType.isArrayOrPrimitiveArray(): Boolean = + withValidityAssertion { analysisSession.typeInfoProvider.isArrayOrPrimitiveArray(this) } + + /** + * Returns whether the given [KtType] is an array or a primitive array type and its element is also an array type or not. + */ + public fun KtType.isNestedArray(): Boolean = withValidityAssertion { analysisSession.typeInfoProvider.isNestedArray(this) } + public fun KtType.isClassTypeWithClassId(classId: ClassId): Boolean = withValidityAssertion { if (this !is KtNonErrorClassType) return false return this.classId == classId