From 725ae1fc656f2550d037ca066d57b086c50af89f Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 14 Oct 2022 15:35:03 +0200 Subject: [PATCH] [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 --- .../components/KtFe10TypeCreator.kt | 4 +- .../descriptorBased/base/Kt1DescUtils.kt | 11 +- .../psiBased/base/KtFe10PsiSymbolUtils.kt | 3 - .../descriptors/types/KtFe10CapturedType.kt | 6 +- .../descriptors/types/KtFe10ClassErrorType.kt | 20 ++- .../descriptors/types/KtFe10FunctionalType.kt | 23 +++- .../types/KtFe10NewCapturedType.kt | 8 +- .../descriptors/types/KtFe10TypeErrorType.kt | 43 +++++++ .../descriptors/types/KtFe10UsualClassType.kt | 40 +++++- .../utils/KtFe10JvmTypeMapperContext.kt | 8 +- .../kotlin/analysis/api/fir/FirUtils.kt | 2 +- .../analysis/api/fir/KtSymbolByFirBuilder.kt | 16 ++- .../KtFirAnalysisSessionComponent.kt | 9 +- .../api/fir/renderer/ConeTypeIdeRenderer.kt | 2 +- .../api/fir/types/KtFirCapturedType.kt | 4 + .../api/fir/types/KtFirClassErrorType.kt | 20 ++- .../api/fir/types/KtFirFunctionalType.kt | 20 +-- .../api/fir/types/KtFirTypeErrorType.kt | 43 +++++++ .../api/fir/types/KtFirUsualClassType.kt | 13 +- .../ErrorClassTypeQualifierBuilder.kt | 64 ++++++++++ .../UsualClassTypeQualifierBuilder.kt | 115 ++++++++++++++++++ ...{KtTypeArgument.kt => KtTypeProjection.kt} | 6 +- .../components/KtExpressionTypeProvider.kt | 2 +- .../analysis/api/components/KtTypeCreator.kt | 8 +- .../api/types/KtClassTypeQualifier.kt | 39 ++++++ .../kotlin/analysis/api/types/KtType.kt | 23 +++- .../api/fir/api/FirDeclarationDesignation.kt | 5 +- .../parameters/SymbolLightTypeParameter.kt | 4 +- .../light/classes/symbol/symbolLightUtils.kt | 2 +- .../coneDiagnosticToFirDiagnostic.kt | 4 +- .../kotlin/fir/java/javaAnnotationsMapping.kt | 4 +- .../providers/impl/FirTypeResolverImpl.kt | 2 +- .../FirExpressionsResolveTransformer.kt | 2 +- .../resolve/diagnostics/ConeDiagnostics.kt | 16 +-- .../jetbrains/kotlin/types/error/ErrorType.kt | 2 +- 35 files changed, 510 insertions(+), 83 deletions(-) create mode 100644 analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10TypeErrorType.kt create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/ErrorClassTypeQualifierBuilder.kt create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt rename analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/{KtTypeArgument.kt => KtTypeProjection.kt} (83%) create mode 100644 analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtClassTypeQualifier.kt diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeCreator.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeCreator.kt index cdbc1988059..5de17e362ac 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeCreator.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10TypeCreator.kt @@ -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) } } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt index 239940d4f7b..7ede1991d91 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt @@ -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) } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/base/KtFe10PsiSymbolUtils.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/base/KtFe10PsiSymbolUtils.kt index 9df718c07e0..6804c09a2de 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/base/KtFe10PsiSymbolUtils.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/psiBased/base/KtFe10PsiSymbolUtils.kt @@ -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 diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10CapturedType.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10CapturedType.kt index 55b04d8e01f..728138ba0a4 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10CapturedType.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10CapturedType.kt @@ -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) } } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10ClassErrorType.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10ClassErrorType.kt index 7ec61402770..c0c3e1c863f 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10ClassErrorType.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10ClassErrorType.kt @@ -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 + 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 get() = withValidityAssertion { emptyList() } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10FunctionalType.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10FunctionalType.kt index 813d49cfa7b..1e0c495014f 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10FunctionalType.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10FunctionalType.kt @@ -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 + 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 - get() = withValidityAssertion { type.arguments.map { it.toKtTypeArgument(analysisContext) } } + override val ownTypeArguments: List + get() = withValidityAssertion { type.arguments.map { it.toKtTypeProjection(analysisContext) } } } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10NewCapturedType.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10NewCapturedType.kt index c1fcd8b79bc..895986a07f8 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10NewCapturedType.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10NewCapturedType.kt @@ -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) } } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10TypeErrorType.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10TypeErrorType.kt new file mode 100644 index 00000000000..dcf0484ca84 --- /dev/null +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10TypeErrorType.kt @@ -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 } +} \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10UsualClassType.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10UsualClassType.kt index aa4be307c8b..34499ed8288 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10UsualClassType.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/types/KtFe10UsualClassType.kt @@ -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 + 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 - get() = withValidityAssertion { type.arguments.map { it.toKtTypeArgument(analysisContext) } } + override val ownTypeArguments: List + get() = withValidityAssertion { type.arguments.map { it.toKtTypeProjection(analysisContext) } } override val nullability: KtTypeNullability get() = withValidityAssertion { type.ktNullability } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10JvmTypeMapperContext.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10JvmTypeMapperContext.kt index 47d69c7bf3c..57a740e1298 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10JvmTypeMapperContext.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/KtFe10JvmTypeMapperContext.kt @@ -43,7 +43,13 @@ internal class KtFe10JvmTypeMapperContext(private val resolveSession: ResolveSes } } - class NestedType(val root: PossiblyInnerType, val nested: List) + class NestedType(val root: PossiblyInnerType, val nested: List) { + val allInnerTypes: List + get() = buildList { + add(root) + addAll(nested) + } + } override val typeContext = KtFe10TypeSystemCommonBackendContextForTypeMapping(resolveSession) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt index 6c0567b1112..4fe1b49158c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt @@ -76,4 +76,4 @@ internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession) useSiteSession, ) ) -} +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt index c5e47645322..650bbe86b0c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt @@ -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(), diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt index 5ec7dad3747..7dcf1951b1f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt @@ -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 } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt index 46d4c807647..fa75b3abcca 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt @@ -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) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirCapturedType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirCapturedType.kt index 92a9c482dc1..6e47ba3ab11 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirCapturedType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirCapturedType.kt @@ -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) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirClassErrorType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirClassErrorType.kt index f7e5f4e24ac..3b0b64975f0 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirClassErrorType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirClassErrorType.kt @@ -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 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 by cached { val symbols = coneType.diagnostic.getCandidateSymbols().filterIsInstance>() symbols.map { builder.classifierBuilder.buildClassLikeSymbol(it) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirFunctionalType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirFunctionalType.kt index b9f05659502..52aaf073559 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirFunctionalType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirFunctionalType.kt @@ -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 by cached { - coneType.typeArguments.map { typeArgument -> - builder.typeBuilder.buildTypeArgument(typeArgument) - } + override val ownTypeArguments: List get() = withValidityAssertion { qualifiers.last().typeArguments } + + override val qualifiers: List 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 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) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt new file mode 100644 index 00000000000..6de3de3880f --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt @@ -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() +} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirUsualClassType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirUsualClassType.kt index 878998cebac..1e74f7094fe 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirUsualClassType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirUsualClassType.kt @@ -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 by cached { - coneType.typeArguments.map { typeArgument -> - builder.typeBuilder.buildTypeArgument(typeArgument) - } + + override val qualifiers by cached { + UsualClassTypeQualifierBuilder.buildQualifiers(coneType, builder) } + override val ownTypeArguments: List 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() } + diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/ErrorClassTypeQualifierBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/ErrorClassTypeQualifierBuilder.kt new file mode 100644 index 00000000000..62153decc45 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/ErrorClassTypeQualifierBuilder.kt @@ -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 { + 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 { + return createQualifiersByClassSymbol(coneDiagnostic.symbol, builder) + } + + private fun createQualifiersByClassSymbol( + firSymbol: FirClassLikeSymbol<*>, + builder: KtSymbolByFirBuilder + ): List { + return generateSequence(firSymbol) { firSymbol.getContainingClassSymbol(builder.rootSession) }.mapTo(mutableListOf()) { classSymbol -> + KtClassTypeQualifier.KtResolvedClassTypeQualifier( + builder.classifierBuilder.buildClassLikeSymbol(classSymbol), + emptyList(), + builder.token + ) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt new file mode 100644 index 00000000000..bd86dbf9e9f --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt @@ -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 { + + 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() + 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 { + require(isLocal) + var containingClassLookUp = containingClassForLocal() + val designation = mutableListOf(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? { + @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 + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtTypeArgument.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtTypeProjection.kt similarity index 83% rename from analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtTypeArgument.kt rename to analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtTypeProjection.kt index d0888b1d991..5e9438d8d55 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtTypeArgument.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtTypeProjection.kt @@ -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 } } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionTypeProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionTypeProvider.kt index bd974bd2e42..4539c7d52d2 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionTypeProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtExpressionTypeProvider.kt @@ -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) } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeCreator.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeCreator.kt index ed5e01a7447..a3a54d88ec6 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeCreator.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeCreator.kt @@ -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() + private val _arguments = mutableListOf() public var nullability: KtTypeNullability = KtTypeNullability.NON_NULLABLE - public val arguments: List get() = withValidityAssertion { _arguments } + public val arguments: List get() = withValidityAssertion { _arguments } - public fun argument(argument: KtTypeArgument) { + public fun argument(argument: KtTypeProjection) { assertIsValidAndAccessible() _arguments += argument } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtClassTypeQualifier.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtClassTypeQualifier.kt new file mode 100644 index 00000000000..06a62659901 --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtClassTypeQualifier.kt @@ -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 + + public class KtResolvedClassTypeQualifier( + private val _symbol: KtClassifierSymbol, + private val _typeArguments: List, + override val token: KtLifetimeToken + ) : KtClassTypeQualifier { + override val name: Name get() = withValidityAssertion { _symbol.nameOrAnonymous } + public val symbol: KtClassifierSymbol get() = withValidityAssertion { _symbol } + override val typeArguments: List get() = withValidityAssertion { _typeArguments } + } + + public class KtUnresolvedClassTypeQualifier( + private val _name: Name, + private val _typeArguments: List, + override val token: KtLifetimeToken + ) : KtClassTypeQualifier { + override val name: Name get() = withValidityAssertion { _name } + override val typeArguments: List get() = withValidityAssertion { _typeArguments } + } +} + diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtType.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtType.kt index 90471a8423c..d0ef349854c 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtType.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/types/KtType.kt @@ -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 } public sealed class KtNonErrorClassType : KtClassType() { public abstract val classId: ClassId public abstract val classSymbol: KtClassLikeSymbol - public abstract val typeArguments: List + public abstract val ownTypeArguments: List + + abstract override val qualifiers: List } 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 } @@ -61,6 +73,7 @@ public abstract class KtTypeParameterType : KtType { } public abstract class KtCapturedType : KtType { + public abstract val projection: KtTypeProjection override fun toString(): String = asStringForDebugging() } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt index cee3af172e9..2def8ad0024 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDeclarationDesignation.kt @@ -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, @@ -73,7 +74,9 @@ private fun collectDesignationPath(declaration: FirDeclaration): List { 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() diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightTypeParameter.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightTypeParameter.kt index 2fb3b9484a7..abb22b86fc5 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightTypeParameter.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/parameters/SymbolLightTypeParameter.kt @@ -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 } } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt index d8d440b1a87..0fa770da712 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt @@ -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 diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index a0155d64ac6..dc751bc6937 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -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) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt index 77a78db2f8d..2885b5335e9 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/javaAnnotationsMapping.kt @@ -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 { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index bfde838ef1b..8a9c79e900c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -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)) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 68886691873..b3200d2fc9c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -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) } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt index 1234ea1b7f1..39c8aae0b38 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt @@ -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> : ConeDiagnostic { @@ -41,9 +42,9 @@ interface ConeDiagnosticWithSingleCandidate : ConeDiagnosticWithCandidates { override val candidateSymbols: Collection> 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, 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> { +sealed interface ConeUnmatchedTypeArgumentsError : ConeDiagnosticWithSymbol> { val desiredCount: Int } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorType.kt index 8239e37a2c3..85e5f7fcda8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/error/ErrorType.kt @@ -15,7 +15,7 @@ class ErrorType @JvmOverloads internal constructor( val kind: ErrorTypeKind, override val arguments: List = emptyList(), override val isMarkedNullable: Boolean = false, - private vararg val formatParams: String + vararg val formatParams: String ) : SimpleType() { val debugMessage = String.format(kind.debugMessage, *formatParams)