[Analysis API] separate non-class error types from class error types and add information about type qualifiers

it's needed for type printing in renderer
This commit is contained in:
Ilya Kirillov
2022-10-14 15:35:03 +02:00
parent 210212c284
commit 725ae1fc65
35 changed files with 510 additions and 83 deletions
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.components
import org.jetbrains.kotlin.analysis.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.components.KtClassTypeBuilder
import org.jetbrains.kotlin.analysis.api.components.KtTypeCreator
@@ -60,7 +60,7 @@ internal class KtFe10TypeCreator(
val type = if (typeParameters.size == builder.arguments.size) {
val projections = builder.arguments.mapIndexed { index, arg ->
when (arg) {
is KtStarProjectionTypeArgument -> StarProjectionImpl(typeParameters[index])
is KtStarTypeProjection -> StarProjectionImpl(typeParameters[index])
is KtTypeArgumentWithVariance -> TypeProjectionImpl(arg.variance, (arg.type as KtFe10Type).type)
}
}
@@ -252,7 +252,12 @@ internal fun KotlinType.toKtType(analysisContext: Fe10AnalysisContext): KtType {
is DynamicType -> KtFe10DynamicType(unwrappedType, analysisContext)
is FlexibleType -> KtFe10FlexibleType(unwrappedType, analysisContext)
is DefinitelyNotNullType -> KtFe10DefinitelyNotNullType(unwrappedType, analysisContext)
is ErrorType -> KtFe10ClassErrorType(unwrappedType, analysisContext)
is ErrorType -> {
if (unwrappedType.kind.isUnresolved)
KtFe10ClassErrorType(unwrappedType, analysisContext)
else
KtFe10TypeErrorType(unwrappedType, analysisContext)
}
is CapturedType -> KtFe10CapturedType(unwrappedType, analysisContext)
is NewCapturedType -> KtFe10NewCapturedType(unwrappedType, analysisContext)
is SimpleType -> {
@@ -291,9 +296,9 @@ internal fun KotlinType.toKtType(analysisContext: Fe10AnalysisContext): KtType {
}
}
internal fun TypeProjection.toKtTypeArgument(analysisContext: Fe10AnalysisContext): KtTypeArgument {
internal fun TypeProjection.toKtTypeProjection(analysisContext: Fe10AnalysisContext): KtTypeProjection {
return if (isStarProjection) {
KtStarProjectionTypeArgument(analysisContext.token)
KtStarTypeProjection(analysisContext.token)
} else {
KtTypeArgumentWithVariance(type.toKtType(analysisContext), this.projectionKind, analysisContext.token)
}
@@ -9,11 +9,8 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.base.KtFe10Symbol
import org.jetbrains.kotlin.analysis.api.descriptors.types.KtFe10ClassErrorType
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.cfg.getElementParentDeclaration
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.Modality
@@ -5,9 +5,10 @@
package org.jetbrains.kotlin.analysis.api.descriptors.types
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
import org.jetbrains.kotlin.analysis.api.types.KtCapturedType
@@ -23,4 +24,7 @@ internal class KtFe10CapturedType(
override val nullability: KtTypeNullability
get() = withValidityAssertion { type.ktNullability }
override val projection: KtTypeProjection
get() = withValidityAssertion { type.typeProjection.toKtTypeProjection(analysisContext) }
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.analysis.api.descriptors.types
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
@@ -14,16 +13,31 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.error.ErrorType
internal class KtFe10ClassErrorType(
override val type: ErrorType,
override val analysisContext: Fe10AnalysisContext
) : KtClassErrorType(), KtFe10Type {
init {
check(type.kind.isUnresolved) {
"Expected unresolved ErrorType but ${type.kind} found for $type"
}
}
override val qualifiers: List<KtClassTypeQualifier.KtUnresolvedClassTypeQualifier>
get() = withValidityAssertion {
type.formatParams.first().split('.').map {
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(Name.guessByFirstCharacter(it), emptyList(), token)
}
}
override fun asStringForDebugging(): String = withValidityAssertion { type.asStringForDebugging() }
override val error: String
get() = withValidityAssertion { "Type \"${type.debugMessage}\" is unresolved" }
override val errorMessage: String
get() = withValidityAssertion { type.debugMessage }
override val candidateClassSymbols: Collection<KtClassLikeSymbol>
get() = withValidityAssertion { emptyList() }
@@ -5,20 +5,22 @@
package org.jetbrains.kotlin.analysis.api.descriptors.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10DescNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtClassSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeArgument
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10JvmTypeMapperContext
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
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.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
@@ -36,6 +38,17 @@ internal class KtFe10FunctionalType(
override val nullability: KtTypeNullability
get() = withValidityAssertion { type.ktNullability }
override val qualifiers: List<KtClassTypeQualifier.KtResolvedClassTypeQualifier>
get() = withValidityAssertion {
KtFe10JvmTypeMapperContext.getNestedType(type).allInnerTypes.map { innerType ->
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
innerType.classDescriptor.toKtClassSymbol(analysisContext),
innerType.arguments.map { it.toKtTypeProjection(analysisContext) },
token
)
}
}
override val isSuspend: Boolean
get() = withValidityAssertion { descriptor.functionKind.isSuspendType }
@@ -65,6 +78,6 @@ internal class KtFe10FunctionalType(
override val classSymbol: KtClassLikeSymbol
get() = withValidityAssertion { KtFe10DescNamedClassOrObjectSymbol(descriptor, analysisContext) }
override val typeArguments: List<KtTypeArgument>
get() = withValidityAssertion { type.arguments.map { it.toKtTypeArgument(analysisContext) } }
override val ownTypeArguments: List<KtTypeProjection>
get() = withValidityAssertion { type.arguments.map { it.toKtTypeProjection(analysisContext) } }
}
@@ -5,14 +5,15 @@
package org.jetbrains.kotlin.analysis.api.descriptors.types
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtCapturedType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.types.checker.NewCapturedType
internal class KtFe10NewCapturedType(
@@ -23,4 +24,7 @@ internal class KtFe10NewCapturedType(
override val nullability: KtTypeNullability
get() = withValidityAssertion { type.ktNullability }
override val projection: KtTypeProjection
get() = withValidityAssertion { type.constructor.projection.toKtTypeProjection(analysisContext) }
}
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.descriptors.types
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtTypeErrorType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.types.error.ErrorType
import org.jetbrains.kotlin.types.error.ErrorTypeKind
internal class KtFe10TypeErrorType(
override val type: ErrorType,
override val analysisContext: Fe10AnalysisContext
) : KtTypeErrorType(), KtFe10Type {
init {
check(!type.kind.isUnresolved) {
"Expected unresolved ErrorType but ${type.kind} found for $type"
}
}
override fun tryRenderAsNonErrorType(): String? = withValidityAssertion {
when (type.kind) {
ErrorTypeKind.UNINFERRED_TYPE_VARIABLE -> type.formatParams.first()
else -> null
}
}
override fun asStringForDebugging(): String = withValidityAssertion { type.asStringForDebugging() }
override val errorMessage: String
get() = withValidityAssertion { type.debugMessage }
override val nullability: KtTypeNullability
get() = withValidityAssertion { type.ktNullability }
}
@@ -5,19 +5,21 @@
package org.jetbrains.kotlin.analysis.api.descriptors.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10DescNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.maybeLocalClassId
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeArgument
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtClassSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10JvmTypeMapperContext
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.SimpleType
@@ -29,14 +31,40 @@ internal class KtFe10UsualClassType(
) : KtUsualClassType(), KtFe10Type {
override fun asStringForDebugging(): String = withValidityAssertion { type.asStringForDebugging() }
override val qualifiers: List<KtClassTypeQualifier.KtResolvedClassTypeQualifier>
get() = withValidityAssertion {
val nestedType = KtFe10JvmTypeMapperContext.getNestedType(type)
val nonInnerQualifiers =
generateSequence(nestedType.root.classifierDescriptor.containingDeclaration as? ClassDescriptor) { it.containingDeclaration as? ClassDescriptor }
buildList {
nonInnerQualifiers.mapTo(this) {
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
it.toKtClassSymbol(analysisContext),
emptyList(),
token
)
}
nestedType.allInnerTypes.mapTo(this) { innerType ->
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
innerType.classDescriptor.toKtClassSymbol(analysisContext),
innerType.arguments.map { it.toKtTypeProjection(analysisContext) },
token
)
}
}
}
override val classId: ClassId
get() = withValidityAssertion { descriptor.maybeLocalClassId }
override val classSymbol: KtClassLikeSymbol
get() = withValidityAssertion { KtFe10DescNamedClassOrObjectSymbol(descriptor, analysisContext) }
override val typeArguments: List<KtTypeArgument>
get() = withValidityAssertion { type.arguments.map { it.toKtTypeArgument(analysisContext) } }
override val ownTypeArguments: List<KtTypeProjection>
get() = withValidityAssertion { type.arguments.map { it.toKtTypeProjection(analysisContext) } }
override val nullability: KtTypeNullability
get() = withValidityAssertion { type.ktNullability }
@@ -43,7 +43,13 @@ internal class KtFe10JvmTypeMapperContext(private val resolveSession: ResolveSes
}
}
class NestedType(val root: PossiblyInnerType, val nested: List<PossiblyInnerType>)
class NestedType(val root: PossiblyInnerType, val nested: List<PossiblyInnerType>) {
val allInnerTypes: List<PossiblyInnerType>
get() = buildList {
add(root)
addAll(nested)
}
}
override val typeContext = KtFe10TypeSystemCommonBackendContextForTypeMapping(resolveSession)
@@ -76,4 +76,4 @@ internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession)
useSiteSession,
)
)
}
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withConeTypeEntry
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolEntry
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
@@ -34,6 +35,8 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError
import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
@@ -45,15 +48,14 @@ import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@@ -446,7 +448,11 @@ internal class KtSymbolByFirBuilder constructor(
else KtFirUsualClassType(coneType, token, this@KtSymbolByFirBuilder)
}
is ConeTypeParameterType -> KtFirTypeParameterType(coneType, token, this@KtSymbolByFirBuilder)
is ConeErrorType -> KtFirClassErrorType(coneType, token, this@KtSymbolByFirBuilder)
is ConeErrorType -> when (val diagnostic = coneType.diagnostic) {
is ConeUnresolvedError, is ConeUnmatchedTypeArgumentsError ->
KtFirClassErrorType(coneType, diagnostic, token, this@KtSymbolByFirBuilder)
else -> KtFirTypeErrorType(coneType, token, this@KtSymbolByFirBuilder)
}
is ConeDynamicType -> KtFirDynamicType(coneType, token, this@KtSymbolByFirBuilder)
is ConeFlexibleType -> KtFirFlexibleType(coneType, token, this@KtSymbolByFirBuilder)
is ConeIntersectionType -> KtFirIntersectionType(coneType, token, this@KtSymbolByFirBuilder)
@@ -483,8 +489,8 @@ internal class KtSymbolByFirBuilder constructor(
return buildKtType(coneType.coneType)
}
fun buildTypeArgument(coneType: ConeTypeProjection): KtTypeArgument = when (coneType) {
is ConeStarProjection -> KtStarProjectionTypeArgument(token)
fun buildTypeProjection(coneType: ConeTypeProjection): KtTypeProjection = when (coneType) {
is ConeStarProjection -> KtStarTypeProjection(token)
is ConeKotlinTypeProjection -> KtTypeArgumentWithVariance(
buildKtType(coneType.type),
coneType.kind.toVariance(),
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.analysis.api.fir.components
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.analysis.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -66,9 +65,9 @@ internal interface KtFirAnalysisSessionComponent {
return coneType
}
val KtTypeArgument.coneTypeProjection: ConeTypeProjection
val KtTypeProjection.coneTypeProjection: ConeTypeProjection
get() = when (this) {
is KtStarProjectionTypeArgument -> ConeStarProjection
is KtStarTypeProjection -> ConeStarProjection
is KtTypeArgumentWithVariance -> {
typeContext.createTypeArgument(type.coneType, variance.convertVariance()) as ConeTypeProjection
}
@@ -100,7 +100,7 @@ internal class ConeTypeIdeRenderer(
if (options.renderUnresolvedTypeAsResolved) {
when (diagnostic) {
is ConeUnresolvedError -> {
val qualifierRendered = diagnostic.qualifier?.let { FqName(it).render() }.orEmpty()
val qualifierRendered = diagnostic.qualifier.let { FqName(it).render() }
append(qualifierRendered)
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
@@ -23,6 +24,9 @@ internal class KtFirCapturedType(
) : KtCapturedType(), KtFirType {
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val projection: KtTypeProjection
get() = withValidityAssertion { builder.typeBuilder.buildTypeProjection(coneType.constructor.projection) }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
@@ -9,29 +9,47 @@ import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
import org.jetbrains.kotlin.analysis.api.fir.types.qualifiers.ErrorClassTypeQualifierBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.renderForDebugging
internal class KtFirClassErrorType(
override val coneType: ConeErrorType,
private val coneDiagnostic: ConeDiagnostic,
override val token: KtLifetimeToken,
private val builder: KtSymbolByFirBuilder,
) : KtClassErrorType(), KtFirType {
override val error: String get() = withValidityAssertion { coneType.diagnostic.reason }
override val qualifiers: List<KtClassTypeQualifier> by cached {
when (coneDiagnostic) {
is ConeUnresolvedError ->
ErrorClassTypeQualifierBuilder.createQualifiersForUnresolvedType(coneDiagnostic, builder)
is ConeUnmatchedTypeArgumentsError ->
ErrorClassTypeQualifierBuilder.createQualifiersForUnmatchedTypeArgumentsType(coneDiagnostic, builder)
else -> error("Unsupported ${coneDiagnostic::class}")
}
}
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val errorMessage: String get() = withValidityAssertion { coneType.diagnostic.reason }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
override val candidateClassSymbols: Collection<KtClassLikeSymbol> by cached {
val symbols = coneType.diagnostic.getCandidateSymbols().filterIsInstance<FirClassLikeSymbol<*>>()
symbols.map { builder.classifierBuilder.buildClassLikeSymbol(it) }
@@ -5,15 +5,17 @@
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.types.qualifiers.UsualClassTypeQualifierBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
@@ -35,10 +37,10 @@ internal class KtFirFunctionalType(
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
?: errorWithFirSpecificEntries("Class was not found", coneType = coneType)
}
override val typeArguments: List<KtTypeArgument> by cached {
coneType.typeArguments.map { typeArgument ->
builder.typeBuilder.buildTypeArgument(typeArgument)
}
override val ownTypeArguments: List<KtTypeProjection> get() = withValidityAssertion { qualifiers.last().typeArguments }
override val qualifiers: List<KtClassTypeQualifier.KtResolvedClassTypeQualifier> by cached {
UsualClassTypeQualifierBuilder.buildQualifiers(coneType, builder)
}
override val annotationsList: KtAnnotationsList by cached {
@@ -56,7 +58,7 @@ internal class KtFirFunctionalType(
override val receiverType: KtType?
get() = withValidityAssertion {
if (coneType.isExtensionFunctionType) (typeArguments.first() as KtTypeArgumentWithVariance).type
if (coneType.isExtensionFunctionType) (ownTypeArguments.first() as KtTypeArgumentWithVariance).type
else null
}
@@ -66,13 +68,13 @@ internal class KtFirFunctionalType(
}
override val parameterTypes: List<KtType> by cached {
val parameterTypeArgs = if (coneType.isExtensionFunctionType) typeArguments.subList(1, typeArguments.lastIndex)
else typeArguments.subList(0, typeArguments.lastIndex)
val parameterTypeArgs = if (coneType.isExtensionFunctionType) ownTypeArguments.subList(1, ownTypeArguments.lastIndex)
else ownTypeArguments.subList(0, ownTypeArguments.lastIndex)
parameterTypeArgs.map { (it as KtTypeArgumentWithVariance).type }
}
override val returnType: KtType
get() = withValidityAssertion { (typeArguments.last() as KtTypeArgumentWithVariance).type }
get() = withValidityAssertion { (ownTypeArguments.last() as KtTypeArgumentWithVariance).type }
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
override fun equals(other: Any?) = typeEquals(other)
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtTypeErrorType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.renderForDebugging
internal class KtFirTypeErrorType(
override val coneType: ConeErrorType,
override val token: KtLifetimeToken,
private val builder: KtSymbolByFirBuilder,
) : KtTypeErrorType(), KtFirType {
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val errorMessage: String get() = withValidityAssertion { coneType.diagnostic.reason }
override fun tryRenderAsNonErrorType(): String? = withValidityAssertion {
when (val diagnostic = coneType.diagnostic) {
is ConeCannotInferParameterType -> diagnostic.typeParameter.name.asString()
else -> null
}
}
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
override fun equals(other: Any?) = typeEquals(other)
override fun hashCode() = typeHashcode()
}
@@ -5,10 +5,11 @@
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.types.qualifiers.UsualClassTypeQualifierBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
@@ -30,12 +31,13 @@ internal class KtFirUsualClassType(
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
?: errorWithFirSpecificEntries("Class was not found", coneType = coneType)
}
override val typeArguments: List<KtTypeArgument> by cached {
coneType.typeArguments.map { typeArgument ->
builder.typeBuilder.buildTypeArgument(typeArgument)
}
override val qualifiers by cached {
UsualClassTypeQualifierBuilder.buildQualifiers(coneType, builder)
}
override val ownTypeArguments: List<KtTypeProjection> get() = withValidityAssertion { qualifiers.last().typeArguments }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
@@ -45,3 +47,4 @@ internal class KtFirUsualClassType(
override fun equals(other: Any?) = typeEquals(other)
override fun hashCode() = typeHashcode()
}
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.fir.types.qualifiers
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.toConeTypeProjection
internal object ErrorClassTypeQualifierBuilder {
fun createQualifiersForUnresolvedType(
coneDiagnostic: ConeUnresolvedError,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier> {
return when (coneDiagnostic) {
is ConeUnresolvedTypeQualifierError ->
coneDiagnostic.qualifiers.map { part ->
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(
part.name,
part.typeArgumentList.typeArguments.map { builder.typeBuilder.buildTypeProjection(it.toConeTypeProjection()) },
builder.token
)
}
is ConeUnresolvedNameError -> listOf(
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(coneDiagnostic.name, emptyList(), builder.token)
)
is ConeUnresolvedReferenceError -> listOf(
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(coneDiagnostic.name, emptyList(), builder.token)
)
is ConeUnresolvedSymbolError ->
coneDiagnostic.classId.asSingleFqName().pathSegments()
.map { KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(it, emptyList(), builder.token) }
}
}
fun createQualifiersForUnmatchedTypeArgumentsType(
coneDiagnostic: ConeUnmatchedTypeArgumentsError,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier> {
return createQualifiersByClassSymbol(coneDiagnostic.symbol, builder)
}
private fun createQualifiersByClassSymbol(
firSymbol: FirClassLikeSymbol<*>,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier.KtResolvedClassTypeQualifier> {
return generateSequence(firSymbol) { firSymbol.getContainingClassSymbol(builder.rootSession) }.mapTo(mutableListOf()) { classSymbol ->
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
builder.classifierBuilder.buildClassLikeSymbol(classSymbol),
emptyList(),
builder.token
)
}
}
}
@@ -0,0 +1,115 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.fir.types.qualifiers
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.fir.containingClassForLocal
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
internal object UsualClassTypeQualifierBuilder {
fun buildQualifiers(
coneType: ConeClassLikeTypeImpl,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier.KtResolvedClassTypeQualifier> {
val classSymbolToRender = coneType.lookupTag.toSymbol(builder.rootSession)
?: errorWithFirSpecificEntries("ConeClassLikeTypeImpl is not resolved to symbol for on-error type", coneType = coneType) {
withEntry("useSiteSession", builder.rootSession) { it.toString() }
}
if (classSymbolToRender !is FirRegularClassSymbol) {
return listOf(
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
builder.classifierBuilder.buildClassifierSymbol(classSymbolToRender),
coneType.typeArguments.map { builder.typeBuilder.buildTypeProjection(it) },
builder.token
)
)
}
val designation = classSymbolToRender.fir.let {
val nonLocalDesignation = it.tryCollectDesignation()
nonLocalDesignation?.toSequence(includeTarget = true)?.toList()
?: collectDesignationPathForLocal(it)
?: emptyList()
}
var typeParametersLeft = coneType.typeArguments.size
fun needToRenderTypeParameters(index: Int): Boolean {
if (typeParametersLeft <= 0) return false
return index == designation.lastIndex ||
(designation[index] as? FirRegularClass)?.isInner == true ||
(designation[index + 1] as? FirRegularClass)?.isInner == true
}
val result = mutableListOf<KtClassTypeQualifier.KtResolvedClassTypeQualifier>()
designation.forEachIndexed { index, currentClass ->
check(currentClass is FirRegularClass)
val typeParameters = if (needToRenderTypeParameters(index)) {
val typeParametersCount = currentClass.typeParameters.count { it is FirTypeParameter }
val begin = typeParametersLeft - typeParametersCount
val end = typeParametersLeft
check(begin >= 0)
typeParametersLeft -= typeParametersCount
coneType.typeArguments.slice(begin until end).map { builder.typeBuilder.buildTypeProjection(it) }
} else emptyList()
result += KtClassTypeQualifier.KtResolvedClassTypeQualifier(
builder.classifierBuilder.buildClassifierSymbol(currentClass.symbol),
typeParameters,
builder.token
)
}
return result
}
private fun FirRegularClass.collectForLocal(): List<FirClassLikeDeclaration> {
require(isLocal)
var containingClassLookUp = containingClassForLocal()
val designation = mutableListOf<FirClassLikeDeclaration>(this)
@OptIn(LookupTagInternals::class)
while (containingClassLookUp != null && containingClassLookUp.classId.isLocal) {
val currentClass = containingClassLookUp.toFirRegularClass(moduleData.session) ?: break
designation.add(currentClass)
containingClassLookUp = currentClass.containingClassForLocal()
}
return designation
}
private fun collectDesignationPathForLocal(declaration: FirDeclaration): List<FirDeclaration>? {
@OptIn(LookupTagInternals::class)
val containingClass = when (declaration) {
is FirCallableDeclaration -> declaration.getContainingClass(declaration.moduleData.session)
is FirAnonymousObject -> return listOf(declaration)
is FirClassLikeDeclaration -> declaration.let {
if (!declaration.isLocal) return null
(it as? FirRegularClass)?.containingClassForLocal()?.toFirRegularClass(declaration.moduleData.session)
}
else -> error("Invalid declaration ${declaration.renderWithType()}")
} ?: return listOf(declaration)
return if (containingClass.isLocal) {
containingClass.collectForLocal().reversed()
} else {
null
}
}
}
@@ -11,11 +11,11 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.types.Variance
public sealed class KtTypeArgument : KtLifetimeOwner {
public sealed class KtTypeProjection : KtLifetimeOwner {
public abstract val type: KtType?
}
public class KtStarProjectionTypeArgument(override val token: KtLifetimeToken) : KtTypeArgument() {
public class KtStarTypeProjection(override val token: KtLifetimeToken) : KtTypeProjection() {
override val type: KtType? get() = withValidityAssertion { null }
}
@@ -23,7 +23,7 @@ public class KtTypeArgumentWithVariance(
private val _type: KtType,
public val variance: Variance,
override val token: KtLifetimeToken,
) : KtTypeArgument() {
) : KtTypeProjection() {
override val type: KtType get() = withValidityAssertion { _type }
}
@@ -59,7 +59,7 @@ public interface KtExpressionTypeProviderMixIn : KtAnalysisSessionMixIn {
/**
* Returns the expected [KtType] of this [PsiElement] if it is an expression. The returned value should not be a
* [org.jetbrains.kotlin.analysis.api.types.KtClassErrorType].
* [org.jetbrains.kotlin.analysis.api.types.KtErrorType].
*/
public fun PsiElement.getExpectedType(): KtType? =
withValidityAssertion { analysisSession.expressionTypeProvider.getExpectedType(this) }
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.analysis.api.components
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
@@ -49,13 +49,13 @@ public inline fun KtTypeCreatorMixIn.buildTypeParameterType(
public sealed class KtTypeBuilder : KtLifetimeOwner
public sealed class KtClassTypeBuilder : KtTypeBuilder() {
private val _arguments = mutableListOf<KtTypeArgument>()
private val _arguments = mutableListOf<KtTypeProjection>()
public var nullability: KtTypeNullability = KtTypeNullability.NON_NULLABLE
public val arguments: List<KtTypeArgument> get() = withValidityAssertion { _arguments }
public val arguments: List<KtTypeProjection> get() = withValidityAssertion { _arguments }
public fun argument(argument: KtTypeArgument) {
public fun argument(argument: KtTypeProjection) {
assertIsValidAndAccessible()
_arguments += argument
}
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.types
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.analysis.api.symbols.nameOrAnonymous
import org.jetbrains.kotlin.name.Name
public sealed interface KtClassTypeQualifier : KtLifetimeOwner {
public val name: Name
public val typeArguments: List<KtTypeProjection>
public class KtResolvedClassTypeQualifier(
private val _symbol: KtClassifierSymbol,
private val _typeArguments: List<KtTypeProjection>,
override val token: KtLifetimeToken
) : KtClassTypeQualifier {
override val name: Name get() = withValidityAssertion { _symbol.nameOrAnonymous }
public val symbol: KtClassifierSymbol get() = withValidityAssertion { _symbol }
override val typeArguments: List<KtTypeProjection> get() = withValidityAssertion { _typeArguments }
}
public class KtUnresolvedClassTypeQualifier(
private val _name: Name,
private val _typeArguments: List<KtTypeProjection>,
override val token: KtLifetimeToken
) : KtClassTypeQualifier {
override val name: Name get() = withValidityAssertion { _name }
override val typeArguments: List<KtTypeProjection> get() = withValidityAssertion { _typeArguments }
}
}
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.analysis.api.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
@@ -29,14 +29,27 @@ public enum class KtTypeNullability(public val isNullable: Boolean) {
}
}
public sealed interface KtErrorType : KtType {
// todo should be replaced with diagnostics
public val errorMessage: String
}
public abstract class KtTypeErrorType : KtErrorType {
public abstract fun tryRenderAsNonErrorType(): String?
}
public sealed class KtClassType : KtType {
override fun toString(): String = asStringForDebugging()
public abstract val qualifiers: List<KtClassTypeQualifier>
}
public sealed class KtNonErrorClassType : KtClassType() {
public abstract val classId: ClassId
public abstract val classSymbol: KtClassLikeSymbol
public abstract val typeArguments: List<KtTypeArgument>
public abstract val ownTypeArguments: List<KtTypeProjection>
abstract override val qualifiers: List<KtClassTypeQualifier.KtResolvedClassTypeQualifier>
}
public abstract class KtFunctionalType : KtNonErrorClassType() {
@@ -50,8 +63,7 @@ public abstract class KtFunctionalType : KtNonErrorClassType() {
public abstract class KtUsualClassType : KtNonErrorClassType()
public abstract class KtClassErrorType : KtClassType() {
public abstract val error: String
public abstract class KtClassErrorType : KtClassType(), KtErrorType {
public abstract val candidateClassSymbols: Collection<KtClassLikeSymbol>
}
@@ -61,6 +73,7 @@ public abstract class KtTypeParameterType : KtType {
}
public abstract class KtCapturedType : KtType {
public abstract val projection: KtTypeProjection
override fun toString(): String = asStringForDebugging()
}
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
import org.jetbrains.kotlin.fir.java.javaSymbolProvider
class FirDeclarationDesignationWithFile(
path: List<FirDeclaration>,
@@ -73,7 +74,9 @@ private fun collectDesignationPath(declaration: FirDeclaration): List<FirDeclara
}
is FirClassLikeDeclaration -> {
if (declaration.isLocal) return null
declaration.symbol.classId.outerClassId?.let(declaration.moduleData.session.firProvider::getFirClassifierByFqName)
val outerClassId = declaration.symbol.classId.outerClassId
outerClassId?.let(declaration.moduleData.session.firProvider::getFirClassifierByFqName)
?: outerClassId?.let(declaration.moduleData.session.javaSymbolProvider::getClassLikeSymbolByClassId)?.fir
}
else -> return null
} ?: return emptyList()
@@ -16,7 +16,7 @@ import com.intellij.psi.search.SearchScope
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
import org.jetbrains.kotlin.analysis.api.types.KtErrorType
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.asJava.classes.KotlinSuperTypeListBuilder
@@ -67,7 +67,7 @@ internal class SymbolLightTypeParameter(
.filter { type ->
when (type) {
is KtNonErrorClassType -> type.classId != StandardClassIds.Any
is KtClassErrorType -> false
is KtErrorType -> false
else -> true
}
}
@@ -181,7 +181,7 @@ internal fun KtAnalysisSession.getTypeNullability(ktType: KtType): NullabilityTy
}
if (ktType !is KtNonErrorClassType) return NullabilityType.NotNull
if (ktType.typeArguments.any { it.type is KtClassErrorType }) return NullabilityType.NotNull
if (ktType.ownTypeArguments.any { it.type is KtClassErrorType }) return NullabilityType.NotNull
if (ktType.classId.shortClassName.asString() == SpecialNames.ANONYMOUS_STRING) return NullabilityType.NotNull
val canonicalSignature = ktType.mapTypeToJvmType().descriptor
@@ -46,12 +46,12 @@ private fun ConeDiagnostic.toKtDiagnostic(
): KtDiagnostic? = when (this) {
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn(
source,
(this.name ?: SpecialNames.NO_NAME_PROVIDED).asString()
this.name.asString()
)
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.classId.asString())
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.name.asString())
is ConeUnresolvedQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier)
is ConeUnresolvedTypeQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier)
is ConeFunctionCallExpectedError -> FirErrors.FUNCTION_CALL_EXPECTED.createOn(source, this.name.asString(), this.hasValueParameters)
is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type)
is ConeResolutionToClassifierError -> FirErrors.RESOLUTION_TO_CLASSIFIER.createOn(source, this.candidateSymbol)
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.toKtPsiSourceElement
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
@@ -214,7 +215,8 @@ private fun JavaAnnotation.toFirAnnotationCall(
type = ConeClassLikeTypeImpl(lookupTag, emptyArray(), isNullable = false)
}
} else {
buildErrorTypeRef { diagnostic = ConeUnresolvedReferenceError() }
val unresolvedName = classId?.shortClassName ?: SpecialNames.NO_NAME_PROVIDED
buildErrorTypeRef { diagnostic = ConeUnresolvedReferenceError(unresolvedName) }
}
argumentMapping = buildAnnotationArgumentMapping {
@@ -247,7 +247,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
ConeAmbiguityError(typeRef.qualifier.last().name, result.typeCandidates.first().applicability, result.typeCandidates)
}
else -> {
ConeUnresolvedQualifierError(typeRef.render())
ConeUnresolvedTypeQualifierError(typeRef.qualifier, isNullable = typeRef.isMarkedNullable)
}
}
return ConeErrorType(diagnostic, attributes = typeRef.annotations.computeTypeAttributes(session))
@@ -598,7 +598,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
}
diagnostic = when {
// Use a stub diagnostic to suppress unresolved error here because it would be reported by other logic
lhsReference is FirErrorNamedReference -> ConeStubDiagnostic(ConeUnresolvedReferenceError())
lhsReference is FirErrorNamedReference -> ConeStubDiagnostic(ConeUnresolvedReferenceError(lhsReference.name))
lhsSymbol == null -> ConeVariableExpectedError
else -> ConeValReassignmentError(lhsSymbol)
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirQualifierPart
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -22,7 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
sealed interface ConeUnresolvedError : ConeDiagnostic {
val qualifier: String?
val qualifier: String
}
interface ConeDiagnosticWithSymbol<S : FirBasedSymbol<*>> : ConeDiagnostic {
@@ -41,9 +42,9 @@ interface ConeDiagnosticWithSingleCandidate : ConeDiagnosticWithCandidates {
override val candidateSymbols: Collection<FirBasedSymbol<*>> get() = listOf(candidateSymbol)
}
class ConeUnresolvedReferenceError(val name: Name? = null) : ConeUnresolvedError {
override val qualifier: String? get() = name?.asString()
override val reason: String get() = "Unresolved reference" + if (name != null) ": ${name.asString()}" else ""
class ConeUnresolvedReferenceError(val name: Name) : ConeUnresolvedError {
override val qualifier: String get() = if (!name.isSpecial) name.asString() else "NO_NAME"
override val reason: String get() = "Unresolved reference: ${name.asString()}"
}
class ConeUnresolvedSymbolError(val classId: ClassId) : ConeUnresolvedError {
@@ -51,8 +52,9 @@ class ConeUnresolvedSymbolError(val classId: ClassId) : ConeUnresolvedError {
override val reason: String get() = "Symbol not found for $classId"
}
class ConeUnresolvedQualifierError(override val qualifier: String) : ConeUnresolvedError {
override val reason: String get() = "Symbol not found for $qualifier"
class ConeUnresolvedTypeQualifierError(val qualifiers: List<FirQualifierPart>, val isNullable: Boolean) : ConeUnresolvedError {
override val qualifier: String get() = qualifiers.joinToString(separator = ".") { it.name.asString() }
override val reason: String get() = "Symbol not found for $qualifier${if (isNullable) "?" else ""}"
}
class ConeUnresolvedNameError(val name: Name) : ConeUnresolvedError {
@@ -146,7 +148,7 @@ class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic {
override val reason: String get() = "Not a legal annotation: $name"
}
interface ConeUnmatchedTypeArgumentsError : ConeDiagnosticWithSymbol<FirClassLikeSymbol<*>> {
sealed interface ConeUnmatchedTypeArgumentsError : ConeDiagnosticWithSymbol<FirClassLikeSymbol<*>> {
val desiredCount: Int
}
@@ -15,7 +15,7 @@ class ErrorType @JvmOverloads internal constructor(
val kind: ErrorTypeKind,
override val arguments: List<TypeProjection> = emptyList(),
override val isMarkedNullable: Boolean = false,
private vararg val formatParams: String
vararg val formatParams: String
) : SimpleType() {
val debugMessage = String.format(kind.debugMessage, *formatParams)