diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt index b802fa5665e..2410dcbff97 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt @@ -29,7 +29,7 @@ internal class ExpressionsSmartcastHighlightingVisitor( KotlinIdeaAnalysisBundle.message( "0.smart.cast.to.1", receiverName, - type.asDenotableTypeStringRepresentation() + type.asStringForDebugging() ) ).textAttributes = org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors.SMART_CAST_RECEIVER } @@ -39,7 +39,7 @@ internal class ExpressionsSmartcastHighlightingVisitor( getSmartCastTarget(expression), KotlinIdeaAnalysisBundle.message( "smart.cast.to.0", - type.asDenotableTypeStringRepresentation() + type.asStringForDebugging() ) ).textAttributes = org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors.SMART_CAST_VALUE } diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/FrontendAnalysisSession.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/FrontendAnalysisSession.kt index 2f42c14eca7..cf64029ea58 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/FrontendAnalysisSession.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/FrontendAnalysisSession.kt @@ -18,13 +18,13 @@ abstract class FrontendAnalysisSession(project: Project) : Invalidatable { abstract val symbolProvider: KtSymbolProvider - abstract fun getSmartCastedToTypes(expression: KtExpression): Collection? + abstract fun getSmartCastedToTypes(expression: KtExpression): Collection? abstract fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection - abstract fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): TypeInfo + abstract fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType - abstract fun getKtExpressionType(expression: KtExpression): TypeInfo + abstract fun getKtExpressionType(expression: KtExpression): KtType abstract fun isSubclassOf(klass: KtClassOrObject, superClassId: ClassId): Boolean diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt index 1a93bc286de..9c6259356ec 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.idea.frontend.api -data class ImplicitReceiverSmartCast(val types: Collection, val kind: ImplicitReceiverSmartcastKind) +data class ImplicitReceiverSmartCast(val types: Collection, val kind: ImplicitReceiverSmartcastKind) enum class ImplicitReceiverSmartcastKind { DISPATCH, EXTENSION diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtType.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtType.kt new file mode 100644 index 00000000000..3d80484a93a --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtType.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2020 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.idea.frontend.api + +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name + +interface KtType : Invalidatable { + fun isEqualTo(other: KtType): Boolean + fun isSubTypeOf(superType: KtType): Boolean + + fun asStringForDebugging(): String +} + +sealed class KtDenotableType : KtType { + abstract fun asString(): String +} + +abstract class KtClassType : KtDenotableType() { + abstract val classId: ClassId + abstract val classSymbol: KtClassLikeSymbol + abstract val typeArguments: List +} + +abstract class KtErrorType : KtType { + abstract val error: String +} + +abstract class KtTypeParameterType : KtDenotableType() { + abstract val name: Name + abstract val symbol: KtTypeParameterSymbol +} + +sealed class KtNonDenotableType : KtType + +abstract class KtFlexibleType : KtNonDenotableType() { + abstract val lowerBound: KtType + abstract val upperBound: KtType +} + +abstract class KtIntersectionType : KtNonDenotableType() { + abstract val conjuncts: List +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtTypeArgument.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtTypeArgument.kt new file mode 100644 index 00000000000..2aa92b8dc24 --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtTypeArgument.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 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.idea.frontend.api + +sealed class KtTypeArgument + +object KtStarProjectionTypeArgument : KtTypeArgument() + +abstract class KtTypeArgumentWithVariance : KtTypeArgument() { + abstract val type: KtType + abstract val variance: KtTypeArgumentVariance +} + +enum class KtTypeArgumentVariance { + COVARIANT, CONTRAVARIANT, INVARIANT +} + diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/TypeInfo.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/TypeInfo.kt deleted file mode 100644 index c0390c13f73..00000000000 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/TypeInfo.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2020 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.idea.frontend.api - -import org.jetbrains.kotlin.name.ClassId - -abstract class TypeInfo : Invalidatable { - abstract fun isClassType(): Boolean - abstract fun classIdIfClassTypeOrError(): ClassId - - abstract fun isErrorType(): Boolean - - abstract fun asDenotableTypeStringRepresentation(): String - - abstract fun isEqualTo(other: TypeInfo): Boolean - abstract fun isSubTypeOf(superType: TypeInfo): Boolean - - abstract fun isDefinitelyNullable(): Boolean - abstract fun isDefinitelyNotNull(): Boolean - - override fun toString(): String = asDenotableTypeStringRepresentation() -} - -class ErrorTypeClassIdAccessException(override val message: String? = null) : IllegalStateException() -class ClassTypeExpectedException(override val message: String? = null) : IllegalStateException() \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/DebugSymbolRenderer.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/DebugSymbolRenderer.kt index 2456bc60e71..c3bf437511e 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/DebugSymbolRenderer.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/DebugSymbolRenderer.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -36,7 +36,7 @@ object DebugSymbolRenderer { value.joinTo(this) { renderValue(it) } append("]") } - is TypeInfo -> value.asDenotableTypeStringRepresentation() + is KtType -> value.asStringForDebugging() is KtSymbol -> { val symbolTag = when (value) { is KtClassLikeSymbol -> renderValue(value.classId) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers.kt index 766a6a0bc8e..cd756305d5c 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/markers.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType import org.jetbrains.kotlin.name.Name interface KtNamedSymbol : KtSymbol { @@ -21,12 +21,12 @@ enum class KtSymbolKind { } interface KtTypedSymbol : KtSymbol { - val type: TypeInfo + val type: KtType } interface KtPossibleExtensionSymbol { val isExtension: Boolean - val receiverType: TypeInfo? + val receiverType: KtType? } interface KtSymbolWithTypeParameters { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/ConeTypeInfo.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/ConeTypeInfo.kt deleted file mode 100644 index 9cfbec2677d..00000000000 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/ConeTypeInfo.kt +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2010-2020 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.idea.frontend.api.fir - -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl -import org.jetbrains.kotlin.idea.frontend.api.* -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.types.AbstractTypeChecker -import org.jetbrains.kotlin.types.AbstractTypeCheckerContext -import java.lang.ref.WeakReference - -internal class ConeTypeInfo( - coneType: ConeKotlinType, - private val typeCheckerContext: ConeTypeCheckerContext, - private val validityToken: Invalidatable -) : TypeInfo() { - private val coneTypeWeakRef = WeakReference(coneType) - - override fun isClassType(): Boolean { - assertIsValid() - return coneType is ConeClassLikeType - } - - override fun isErrorType(): Boolean { - assertIsValid() - return coneType is ConeClassErrorType - } - - override fun classIdIfClassTypeOrError(): ClassId { - assertIsValid() - return when (val coneType = coneType) { - is ConeClassLikeTypeImpl -> coneType.lookupTag.classId - is ConeClassErrorType -> throw ErrorTypeClassIdAccessException() - else -> throw ClassTypeExpectedException() - } - } - - override fun asDenotableTypeStringRepresentation(): String { - assertIsValid() - return coneType.render()//TODO - } - - override fun isEqualTo(other: TypeInfo): Boolean { - assertIsValid() - other.assertIsValid() - check(other is ConeTypeInfo) - return AbstractTypeChecker.equalTypes( - typeCheckerContext as AbstractTypeCheckerContext, - coneType, - other.coneType - ) - } - - override fun isSubTypeOf(superType: TypeInfo): Boolean { - assertIsValid() - superType.assertIsValid() - check(superType is ConeTypeInfo) - return AbstractTypeChecker.isSubtypeOf( - typeCheckerContext as AbstractTypeCheckerContext, - coneType, - superType.coneType - ) - } - - override fun isDefinitelyNullable(): Boolean { - assertIsValid() - return coneType.nullability == ConeNullability.NULLABLE - } - - override fun isDefinitelyNotNull(): Boolean { - assertIsValid() - return coneType.nullability == ConeNullability.NOT_NULL - } - - override fun isValid(): Boolean { - if (coneTypeWeakRef.get() == null) return false - return validityToken.isValid() - } - - override fun invalidationReason(): String { - if (coneTypeWeakRef.get() == null) return "Cone type was garbage collected" - return validityToken.invalidationReason() - } - - private inline val coneType - get() = coneTypeWeakRef.get() ?: if (validityToken.isValid()) { - error("Cone type was garbage collected while analysis session is still valid") - } else { - error("Accessing the invalid coneType") - } -} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt index 9af819261fd..d2154f5f3f6 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirAnalysisSession.kt @@ -17,10 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.fir.types.coneTypeUnsafe +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.idea.fir.* import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade import org.jetbrains.kotlin.idea.frontend.api.* @@ -40,7 +37,12 @@ class FirAnalysisSession( ) : FrontendAnalysisSession(element.project) { internal val token get() = validityToken - internal val firSymbolBuilder = KtSymbolByFirBuilder(validityToken) + internal val firSymbolBuilder = KtSymbolByFirBuilder( + element.session.firSymbolProvider, + ConeTypeCheckerContext(isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, element.session), + validityToken + ) + override val symbolProvider: KtSymbolProvider = FirKtSymbolProvider( this, @@ -52,10 +54,10 @@ class FirAnalysisSession( assertIsValid() } - override fun getSmartCastedToTypes(expression: KtExpression): Collection? { + override fun getSmartCastedToTypes(expression: KtExpression): Collection? { assertIsValid() // TODO filter out not used smartcasts - return expression.getOrBuildFirSafe()?.typesFromSmartCast?.map { it.asTypeInfo(expression.session) } + return expression.getOrBuildFirSafe()?.typesFromSmartCast?.map { it.asTypeInfo() } } @OptIn(ExperimentalStdlibApi::class) @@ -70,13 +72,13 @@ class FirAnalysisSession( return buildList { (qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> ImplicitReceiverSmartCast( - smartCasted.typesFromSmartCast.map { it.asTypeInfo(session) }, + smartCasted.typesFromSmartCast.map { it.asTypeInfo() }, ImplicitReceiverSmartcastKind.DISPATCH ) }?.let(::add) (qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> ImplicitReceiverSmartCast( - smartCasted.typesFromSmartCast.map { it.asTypeInfo(session) }, + smartCasted.typesFromSmartCast.map { it.asTypeInfo() }, ImplicitReceiverSmartcastKind.EXTENSION ) }?.let(::add) @@ -84,15 +86,15 @@ class FirAnalysisSession( } - override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): TypeInfo { + override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType { assertIsValid() val firDeclaration = declaration.getOrBuildFirOfType>() - return firDeclaration.returnTypeRef.coneType.asTypeInfo(declaration.session) + return firDeclaration.returnTypeRef.coneType.asTypeInfo() } - override fun getKtExpressionType(expression: KtExpression): TypeInfo { + override fun getKtExpressionType(expression: KtExpression): KtType { assertIsValid() - return expression.getOrBuildFirOfType().typeRef.coneType.asTypeInfo(expression.session) + return expression.getOrBuildFirOfType().typeRef.coneType.asTypeInfo() } override fun isSubclassOf(klass: KtClassOrObject, superClassId: ClassId): Boolean { @@ -168,14 +170,7 @@ class FirAnalysisSession( } } - private fun ConeKotlinType.asTypeInfo(session: FirSession) = - ConeTypeInfo(this, createTypeCheckingContext(session), validityToken) - - private fun createTypeCheckingContext(session: FirSession) = ConeTypeCheckerContext( - isErrorTypeEqualsToAnything = true, // TODO? - isStubTypeEqualsToAnything = true, // TODO? - session = session - ) + private fun ConeKotlinType.asTypeInfo() = firSymbolBuilder.buildKtType(this) companion object { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirKtType.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirKtType.kt new file mode 100644 index 00000000000..9831a860258 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/FirKtType.kt @@ -0,0 +1,134 @@ +/* + * Copyright 2010-2020 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.idea.frontend.api.fir + +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.idea.frontend.api.* +import org.jetbrains.kotlin.idea.frontend.api.KtTypeParameterType +import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached +import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.AbstractTypeCheckerContext + +internal interface KtFirType : KtType, InvalidatableByValidityToken { + val coneType: ConeKotlinType + val typeCheckerContext: ConeTypeCheckerContext + + override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } + + override fun isEqualTo(other: KtType): Boolean = withValidityAssertion { + other.assertIsValid() + check(other is KtFirType) + return AbstractTypeChecker.equalTypes( + typeCheckerContext as AbstractTypeCheckerContext, + coneType, + other.coneType + ) + } + + override fun isSubTypeOf(superType: KtType): Boolean = withValidityAssertion { + superType.assertIsValid() + check(superType is KtFirType) + return AbstractTypeChecker.isSubtypeOf( + typeCheckerContext as AbstractTypeCheckerContext, + coneType, + superType.coneType + ) + } + +} + +internal class KtFirClassType( + coneType: ConeClassLikeTypeImpl, + typeCheckerContext: ConeTypeCheckerContext, + override val token: Invalidatable, + private val firBuilder: KtSymbolByFirBuilder, +) : KtClassType(), KtFirType { + override val coneType by weakRef(coneType) + override val typeCheckerContext by weakRef(typeCheckerContext) + + override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId } + override val classSymbol: KtClassLikeSymbol by cached { + firBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag) ?: error("Class ${coneType.lookupTag} was not found") + } + override val typeArguments: List by cached { + coneType.typeArguments.map { typeArgument -> + firBuilder.buildTypeArgument(typeArgument) + } + } + + override fun asString(): String = withValidityAssertion { + coneType.render() //todo + } +} + +internal class KtFirErrorType( + coneType: ConeClassErrorType, + typeCheckerContext: ConeTypeCheckerContext, + override val token: Invalidatable, +) : KtErrorType(), KtFirType { + override val coneType by weakRef(coneType) + override val typeCheckerContext by weakRef(typeCheckerContext) + + override val error: String get() = withValidityAssertion { coneType.reason } +} + +internal class KtFirTypeParameterType( + coneType: ConeTypeParameterType, + typeCheckerContext: ConeTypeCheckerContext, + override val token: Invalidatable, + private val firBuilder: KtSymbolByFirBuilder, +) : KtTypeParameterType(), KtFirType { + override val coneType by weakRef(coneType) + override val typeCheckerContext by weakRef(typeCheckerContext) + + override val name: Name get() = withValidityAssertion { coneType.lookupTag.name } + override val symbol: KtTypeParameterSymbol by cached { + firBuilder.buildTypeParameterSymbolByLookupTag(coneType.lookupTag) + ?: error("Type parameter ${coneType.lookupTag} was not found") + } + + override fun asString(): String = withValidityAssertion { + coneType.render() //todo + } +} + +internal class KtFirFlexibleType( + coneType: ConeFlexibleType, + typeCheckerContext: ConeTypeCheckerContext, + override val token: Invalidatable, + private val firBuilder: KtSymbolByFirBuilder, +) : KtFlexibleType(), KtFirType { + override val coneType by weakRef(coneType) + override val typeCheckerContext by weakRef(typeCheckerContext) + + override val lowerBound: KtType by cached { firBuilder.buildKtType(coneType.lowerBound) } + override val upperBound: KtType by cached { firBuilder.buildKtType(coneType.upperBound) } +} + +internal class KtFirIntersectionType( + coneType: ConeIntersectionType, + typeCheckerContext: ConeTypeCheckerContext, + override val token: Invalidatable, + private val firBuilder: KtSymbolByFirBuilder, +) : KtIntersectionType(), KtFirType { + override val coneType by weakRef(coneType) + override val typeCheckerContext by weakRef(typeCheckerContext) + + override val conjuncts: List by cached { + coneType.intersectedTypes.map { conjunct -> firBuilder.buildKtType(conjunct) } + } +} + +internal class KtFirTypeArgumentWithVariance( + override val type: KtType, + override val variance: KtTypeArgumentVariance +) : KtTypeArgumentWithVariance() \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt index 9cd42dbafc8..9a1c97a46c7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt @@ -8,6 +8,14 @@ package org.jetbrains.kotlin.idea.frontend.api.fir import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl +import org.jetbrains.kotlin.fir.resolve.providers.FirProvider +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.idea.frontend.api.* import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag @@ -25,45 +33,122 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirFunctionValuePara import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol -internal class KtSymbolByFirBuilder(private val validityToken: Invalidatable) { - fun buildSymbol(fir: FirDeclaration): KtSymbol = when (fir) { +internal class KtSymbolByFirBuilder( + firProvider: FirSymbolProvider, + typeCheckerContext: ConeTypeCheckerContext, + private val project: Project, + override val token: ValidityOwner +) : ValidityOwnerByValidityToken { + private val firProvider by weakRef(firProvider) + private val typeCheckerContext by weakRef(typeCheckerContext) + + private val symbolsCache = BuilderCache() + private val typesCache = BuilderCache() + + fun buildSymbol(fir: FirDeclaration): KtSymbol = symbolsCache.cache(fir) { + when (fir) { + is FirRegularClass -> buildClassSymbol(fir) + is FirSimpleFunction -> buildFunctionSymbol(fir) + is FirProperty -> buildVariableSymbol(fir) + is FirValueParameterImpl -> buildParameterSymbol(fir) + is FirConstructor -> buildConstructorSymbol(fir) + is FirTypeParameter -> buildTypeParameterSymbol(fir) + is FirTypeAlias -> buildTypeAliasSymbol(fir) + is FirEnumEntry -> buildEnumEntrySymbol(fir) + is FirField -> buildFieldSymbol(fir) + is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir) + else -> + TODO(fir::class.toString()) + } + } + + fun buildClassLikeSymbol(fir: FirClassLikeDeclaration<*>): KtClassLikeSymbol = when (fir) { is FirRegularClass -> buildClassSymbol(fir) - is FirSimpleFunction -> buildFunctionSymbol(fir) - is FirProperty -> buildVariableSymbol(fir) - is FirValueParameterImpl -> buildParameterSymbol(fir) - is FirConstructor -> buildConstructorSymbol(fir) - is FirTypeParameter -> buildTypeParameterSymbol(fir) is FirTypeAlias -> buildTypeAliasSymbol(fir) - is FirEnumEntry -> buildEnumEntrySymbol(fir) - is FirField -> buildFieldSymbol(fir) - is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir) else -> TODO(fir::class.toString()) } - fun buildClassSymbol(fir: FirRegularClass) = KtFirClassOrObjectSymbol(fir, validityToken, this) + fun buildClassSymbol(fir: FirRegularClass) = symbolsCache.cache(fir) { KtFirClassOrObjectSymbol(fir, token, this) } // TODO it can be a constructor parameter, which may be split into parameter & property // we should handle them both - fun buildParameterSymbol(fir: FirValueParameterImpl) = KtFirFunctionValueParameterSymbol(fir, validityToken) - fun buildFirConstructorParameter(fir: FirValueParameterImpl) = KtFirConstructorValueParameterSymbol(fir, validityToken) + fun buildParameterSymbol(fir: FirValueParameterImpl) = symbolsCache.cache(fir) { KtFirFunctionValueParameterSymbol(fir, token, this) } + fun buildFirConstructorParameter(fir: FirValueParameterImpl) = + symbolsCache.cache(fir) { KtFirConstructorValueParameterSymbol(fir, token, this) } - fun buildFunctionSymbol(fir: FirSimpleFunction) = KtFirFunctionSymbol(fir, validityToken, this) - fun buildConstructorSymbol(fir: FirConstructor) = KtFirConstructorSymbol(fir, validityToken, this) - fun buildTypeParameterSymbol(fir: FirTypeParameter) = KtFirTypeParameterSymbol(fir, validityToken) - fun buildTypeAliasSymbol(fir: FirTypeAlias) = KtFirTypeAliasSymbol(fir, validityToken) - fun buildEnumEntrySymbol(fir: FirEnumEntry) = KtFirEnumEntrySymbol(fir, validityToken) - fun buildFieldSymbol(fir: FirField) = KtFirFieldSymbol(fir, validityToken) - fun buildAnonymousFunctionSymbol(fir: FirAnonymousFunction) = KtFirAnonymousFunctionSymbol(fir, validityToken, this) + fun buildFunctionSymbol(fir: FirSimpleFunction) = symbolsCache.cache(fir) { KtFirFunctionSymbol(fir, token, this) } + fun buildConstructorSymbol(fir: FirConstructor) = symbolsCache.cache(fir) { KtFirConstructorSymbol(fir, token, this) } + fun buildTypeParameterSymbol(fir: FirTypeParameter) = symbolsCache.cache(fir) { KtFirTypeParameterSymbol(fir, token) } - fun buildVariableSymbol(fir: FirProperty): KtVariableSymbol { - return when { - fir.isLocal -> KtFirLocalVariableSymbol(fir, validityToken) - else -> KtFirPropertySymbol(fir, validityToken) + fun buildTypeAliasSymbol(fir: FirTypeAlias) = symbolsCache.cache(fir) { KtFirTypeAliasSymbol(fir, token) } + fun buildEnumEntrySymbol(fir: FirEnumEntry) = symbolsCache.cache(fir) { KtFirEnumEntrySymbol(fir, token, this) } + fun buildFieldSymbol(fir: FirField) = symbolsCache.cache(fir) { KtFirFieldSymbol(fir, token, this) } + fun buildAnonymousFunctionSymbol(fir: FirAnonymousFunction) = symbolsCache.cache(fir) { KtFirAnonymousFunctionSymbol(fir, token, this) } + + fun buildVariableSymbol(fir: FirProperty): KtVariableSymbol = symbolsCache.cache(fir) { + when { + fir.isLocal -> KtFirLocalVariableSymbol(fir, token, this) + else -> KtFirPropertySymbol(fir, token, this) } } + + fun buildClassLikeSymbolByLookupTag(lookupTag: ConeClassLikeLookupTag): KtClassLikeSymbol? = withValidityAssertion { + firProvider.getSymbolByLookupTag(lookupTag)?.fir?.let(::buildClassLikeSymbol) + } + + fun buildTypeParameterSymbolByLookupTag(lookupTag: ConeTypeParameterLookupTag): KtTypeParameterSymbol? = withValidityAssertion { + (firProvider.getSymbolByLookupTag(lookupTag) as? FirTypeParameterSymbol)?.fir?.let(::buildTypeParameterSymbol) + } + + + fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? { + val exists = firProvider.getPackage(packageFqName) != null + if (!exists) { + return null + } + return KtFirPackageSymbol(packageFqName, project, token) + } + + fun buildTypeArgument(coneType: ConeTypeProjection): KtTypeArgument = when (coneType) { + is ConeStarProjection -> KtStarProjectionTypeArgument + is ConeKotlinTypeProjection -> KtFirTypeArgumentWithVariance( + buildKtType(coneType.type), + coneType.kind.toVariance() + ) + } + + private fun ProjectionKind.toVariance() = when (this) { + ProjectionKind.OUT -> KtTypeArgumentVariance.COVARIANT + ProjectionKind.IN -> KtTypeArgumentVariance.CONTRAVARIANT + ProjectionKind.INVARIANT -> KtTypeArgumentVariance.INVARIANT + ProjectionKind.STAR -> error("KtStarProjectionTypeArgument be directly created") + } + + + fun buildKtType(coneType: FirTypeRef): KtType = buildKtType(coneType.coneTypeUnsafe()) + + fun buildKtType(coneType: ConeKotlinType): KtType = typesCache.cache(coneType) { + when (coneType) { + is ConeClassLikeTypeImpl -> KtFirClassType(coneType, typeCheckerContext, token, this) + is ConeTypeParameterType -> KtFirTypeParameterType(coneType, typeCheckerContext, token, this) + is ConeClassErrorType -> KtFirErrorType(coneType, typeCheckerContext, token) + is ConeFlexibleType -> KtFirFlexibleType(coneType, typeCheckerContext, token, this) + is ConeIntersectionType -> KtFirIntersectionType(coneType, typeCheckerContext, token, this) + else -> TODO() + } + } +} + +private class BuilderCache { + // the capacity & load factor values here are default ones which are used ing java.util.Map + private val cache = ContainerUtil.createWeakMap(16, .75f, ContainerUtil.identityStrategy()) + + inline fun cache(key: From, calculation: () -> S): S = + cache.getOrPut(key, calculation) as S } internal fun FirElement.buildSymbol(builder: KtSymbolByFirBuilder) = diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt index eb183bbcce6..734004c923a 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirAnonymousFunctionSymbol.kt @@ -7,19 +7,14 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction -import org.jetbrains.kotlin.fir.declarations.FirEnumEntry -import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.* -import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion -import org.jetbrains.kotlin.name.Name internal class KtFirAnonymousFunctionSymbol( fir: FirAnonymousFunction, @@ -29,7 +24,7 @@ internal class KtFirAnonymousFunctionSymbol( override val fir: FirAnonymousFunction by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val valueParameters: List by cached { fir.valueParameters.map { valueParameter -> check(valueParameter is FirValueParameterImpl) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt index f5d8c2bef1a..1c1444bbb82 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorSymbol.kt @@ -12,9 +12,8 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol @@ -31,7 +30,7 @@ internal class KtFirConstructorSymbol( override val fir: FirConstructor by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val valueParameters: List by cached { fir.valueParameters.map { valueParameter -> check(valueParameter is FirValueParameterImpl) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt index 8367b808acc..56a0dc82ed8 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt @@ -6,12 +6,11 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.idea.fir.findPsi -import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo +import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner +import org.jetbrains.kotlin.idea.frontend.api.KtType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.* @@ -20,13 +19,14 @@ import org.jetbrains.kotlin.name.Name internal class KtFirConstructorValueParameterSymbol( fir: FirValueParameterImpl, - override val token: Invalidatable + override val token: ValidityOwner, + private val builder: KtSymbolByFirBuilder ) : KtConstructorParameterSymbol(), KtFirSymbol { override val fir: FirValueParameterImpl by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } override val name: Name get() = withValidityAssertion { fir.name } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val symbolKind: KtSymbolKind get() = withValidityAssertion { when { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt index 158950238a9..6b5430e39bd 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirEnumEntrySymbol.kt @@ -7,26 +7,24 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.declarations.FirEnumEntry -import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.Name internal class KtFirEnumEntrySymbol( fir: FirEnumEntry, - override val token: Invalidatable + override val token: ValidityOwner, + private val builder: KtSymbolByFirBuilder ) : KtEnumEntrySymbol(), KtFirSymbol { override val fir: FirEnumEntry by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } override val name: Name get() = withValidityAssertion { fir.name } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFieldSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFieldSymbol.kt index 46445d21074..77d335f5bed 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFieldSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFieldSymbol.kt @@ -7,29 +7,25 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.declarations.FirField -import org.jetbrains.kotlin.fir.declarations.FirProperty -import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFieldSymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.Name internal class KtFirFieldSymbol( fir: FirField, - override val token: Invalidatable + override val token: ValidityOwner, + private val builder: KtSymbolByFirBuilder ) : KtFieldSymbol(), KtFirSymbol { override val fir: FirField by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val isVal: Boolean get() = withValidityAssertion { fir.isVal } override val name: Name get() = withValidityAssertion { fir.name } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt index 31efd25f2ef..30e7ab1eb05 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt @@ -13,9 +13,8 @@ import org.jetbrains.kotlin.fir.declarations.isOperator import org.jetbrains.kotlin.fir.declarations.isSuspend import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol @@ -32,7 +31,7 @@ internal class KtFirFunctionSymbol( override val fir: FirSimpleFunction by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } override val name: Name get() = withValidityAssertion { fir.name } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val valueParameters: List by cached { fir.valueParameters.map { valueParameter -> check(valueParameter is FirValueParameterImpl) @@ -45,7 +44,7 @@ internal class KtFirFunctionSymbol( } } override val isSuspend: Boolean get() = withValidityAssertion { fir.isSuspend } - override val receiverType: TypeInfo? by cached { fir.receiverTypeRef?.asTypeInfo(fir.session, token) } + override val receiverType: KtType? by cached { fir.receiverTypeRef?.let(builder::buildKtType) } override val isOperator: Boolean get() = withValidityAssertion { fir.isOperator } override val isExtension: Boolean get() = withValidityAssertion { fir.receiverTypeRef != null } override val fqName: FqName? get() = withValidityAssertion { fir.symbol.callableId.asFqNameForDebugInfo() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt index 77f21b16b9a..3b2c2c409f2 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt @@ -6,15 +6,13 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSimpleFunctionParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion @@ -22,13 +20,14 @@ import org.jetbrains.kotlin.name.Name internal class KtFirFunctionValueParameterSymbol( fir: FirValueParameterImpl, - override val token: Invalidatable + override val token: ValidityOwner, + private val builder: KtSymbolByFirBuilder ) : KtSimpleFunctionParameterSymbol(), KtFirSymbol { override val fir: FirValueParameterImpl by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } override val name: Name get() = withValidityAssertion { fir.name } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt index 25b087c412a..c0a319f9707 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirLocalVariableSymbol.kt @@ -9,8 +9,8 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol @@ -20,7 +20,8 @@ import org.jetbrains.kotlin.name.Name internal class KtFirLocalVariableSymbol( fir: FirProperty, - override val token: Invalidatable + override val token: ValidityOwner, + private val builder: KtSymbolByFirBuilder ) : KtLocalVariableSymbol(), KtFirSymbol { init { @@ -32,6 +33,6 @@ internal class KtFirLocalVariableSymbol( override val isVal: Boolean get() = withValidityAssertion { fir.isVal } override val name: Name get() = withValidityAssertion { fir.name } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt index af31a14a5b9..c25bd1d6fee 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt @@ -9,8 +9,8 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol @@ -21,7 +21,8 @@ import org.jetbrains.kotlin.name.Name internal class KtFirPropertySymbol( fir: FirProperty, - override val token: Invalidatable + override val token: ValidityOwner, + private val builder: KtSymbolByFirBuilder ) : KtPropertySymbol(), KtFirSymbol { init { assert(!fir.isLocal) @@ -33,8 +34,8 @@ internal class KtFirPropertySymbol( override val fqName: FqName get() = withValidityAssertion { fir.symbol.callableId.asFqNameForDebugInfo() } override val isVal: Boolean get() = withValidityAssertion { fir.isVal } override val name: Name get() = withValidityAssertion { fir.name } - override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } - override val receiverType: TypeInfo? by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) } + override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) } + override val receiverType: KtType? by cached { builder.buildKtType(fir.returnTypeRef) } override val isExtension: Boolean get() = withValidityAssertion { fir.receiverTypeRef != null } override val symbolKind: KtSymbolKind get() = withValidityAssertion { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt index 6589c88f442..566ec6753af 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirTypeParameterSymbol.kt @@ -6,16 +6,11 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.Name diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/typeBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/typeBuilder.kt index 090fe72f3ae..e69de29bb2d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/typeBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/typeBuilder.kt @@ -1,24 +0,0 @@ -/* - * Copyright 2010-2020 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.idea.frontend.api.fir.utils - -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext -import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.fir.types.coneTypeUnsafe -import org.jetbrains.kotlin.idea.frontend.api.Invalidatable -import org.jetbrains.kotlin.idea.frontend.api.InvalidatableByValidityToken -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo -import org.jetbrains.kotlin.idea.frontend.api.fir.ConeTypeInfo - -internal fun FirTypeRef.asTypeInfo(session: FirSession, invalidatable: Invalidatable): TypeInfo { - val context = ConeTypeCheckerContext( - isErrorTypeEqualsToAnything = true, - isStubTypeEqualsToAnything = true, - session = session - ) - return ConeTypeInfo(coneTypeUnsafe(), context, invalidatable) -} \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt index 79f583921f9..8f500be16eb 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt @@ -11,7 +11,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.addExternalTestFiles import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.idea.frontend.api.CallInfo -import org.jetbrains.kotlin.idea.frontend.api.TypeInfo +import org.jetbrains.kotlin.idea.frontend.api.KtType import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtParameterSymbol @@ -85,7 +85,7 @@ abstract class AbstractResolveCallTest : @Suppress("DEPRECATION") KotlinLightCod } private fun CallInfo.stringRepresentation(): String { - fun TypeInfo.render() = asDenotableTypeStringRepresentation().replace('/', '.') + fun KtType.render() = asStringForDebugging().replace('/', '.') fun Any.stringValue(): String? = when (this) { is KtFunctionLikeSymbol -> buildString { append(if (this@stringValue is KtFunctionSymbol) fqName else "")