[FIR] Use toFirRegularClassSymbol instead of toFirRegular in checkers

This commit is contained in:
Ivan Kochurkin
2021-09-08 01:17:26 +03:00
committed by TeamCityServer
parent 8cdb79f969
commit 7c6326856b
18 changed files with 94 additions and 65 deletions
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.dispatchReceiverTypeOrNull
import org.jetbrains.kotlin.fir.originalOrSelf
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
@@ -77,9 +77,9 @@ object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatib
if (JavaToKotlinClassMap.mapKotlinToJava(containingClassName) != null) {
return true
}
if (!originalMember.isAbstract) {
val containingClass = originalMember.containingClass()?.toFirRegularClass(context.session)
val containingClass = originalMember.containingClass()?.toFirRegularClassSymbol(context.session)
if (containingClass?.isInterface == false) {
return false
}
@@ -22,12 +22,12 @@ import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.java.jvmDefaultModeState
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.impl.FirClassUseSiteMemberScope
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_CLASS_ID
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isExternal
import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.lexer.KtTokens
object FirJvmExternalDeclarationChecker : FirBasicDeclarationChecker() {
@@ -62,7 +62,7 @@ object FirJvmExternalDeclarationChecker : FirBasicDeclarationChecker() {
return
}
val containingClassSymbol = declaration.symbol.containingClass()?.toFirRegularClass(context.session)
val containingClassSymbol = declaration.symbol.containingClass()?.toFirRegularClassSymbol(context.session)
if (containingClassSymbol != null) {
if (containingClassSymbol.isInterface) {
reporter.reportOn(declaration.source, FirJvmErrors.EXTERNAL_DECLARATION_IN_INTERFACE, context)
@@ -14,15 +14,19 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.classKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirPropertyChecker
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingDeclarationSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
@@ -31,22 +35,18 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.JvmFieldApplicabilityProblem.*
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.JvmNames.JVM_MULTIFILE_CLASS_SHORT
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingDeclarationSymbol
import org.jetbrains.kotlin.psi.stubs.elements.KtParameterElementType
object FirJvmFieldApplicabilityChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
val annotation = declaration.getAnnotationByClassId(JVM_FIELD_ANNOTATION_CLASS_ID) ?: return
val session = context.session
val containingClass = declaration.containingClass()?.toFirRegularClass(session)
val containingClassSymbol = declaration.containingClass()?.toFirRegularClassSymbol(session)
val problem = when {
declaration.delegate != null -> DELEGATE
!declaration.hasBackingField -> return
declaration.isOverridable(containingClass) -> NOT_FINAL
declaration.isOverridable(containingClassSymbol) -> NOT_FINAL
Visibilities.isPrivate(declaration.visibility) -> PRIVATE
declaration.hasCustomAccessor() -> CUSTOM_ACCESSOR
declaration.isOverride -> OVERRIDES
@@ -63,7 +63,7 @@ object FirJvmFieldApplicabilityChecker : FirPropertyChecker() {
}
}
}
containingClass == null && isInsideJvmMultifileClassFile(context) ->
containingClassSymbol == null && isInsideJvmMultifileClassFile(context) ->
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE
declaration.returnTypeRef.isInlineClassThatRequiresMangling(session) -> RETURN_TYPE_IS_INLINE_CLASS
else -> return
@@ -89,7 +89,7 @@ object FirJvmFieldApplicabilityChecker : FirPropertyChecker() {
return this.classId.relativeClassName.asString() == StandardNames.RESULT_FQ_NAME.asString()
}
private fun FirProperty.isOverridable(containingClass: FirRegularClass?): Boolean {
private fun FirProperty.isOverridable(containingClass: FirRegularClassSymbol?): Boolean {
return visibility != Visibilities.Private && modality != Modality.FINAL &&
containingClass?.isFinal != true
}
@@ -104,7 +104,7 @@ object FirJvmFieldApplicabilityChecker : FirPropertyChecker() {
return false
}
val outerClassKind = (getContainingDeclarationSymbol(session) as? FirRegularClass)?.classKind
val outerClassKind = getContainingDeclarationSymbol(session)?.classKind
return outerClassKind == ClassKind.INTERFACE || outerClassKind == ClassKind.ANNOTATION_CLASS
}
@@ -21,11 +21,8 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
@@ -135,6 +132,21 @@ fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLik
return context.session.symbolProvider.getClassLikeSymbolByClassId(outerClassId)
}
@OptIn(SymbolInternals::class)
fun FirClassSymbol<*>.getContainingDeclarationSymbol(session: FirSession): FirClassLikeSymbol<*>? {
if (isLocal) {
return (this as FirRegularClassSymbol).fir.containingClassForLocalAttr?.toFirRegularClassSymbol(session)
} else {
val parentId = classId.relativeClassName.parent()
if (!parentId.isRoot) {
val containingDeclarationId = ClassId(classId.packageFqName, parentId, false)
return session.symbolProvider.getClassLikeSymbolByClassId(containingDeclarationId)
}
}
return null
}
/**
* Returns the FirClassLikeDeclaration that the
* sequence of FirTypeAlias'es points to starting
@@ -171,7 +183,7 @@ fun CheckerContext.findClosestClassOrObject(): FirClass? {
* Returns the list of functions that overridden by given
*/
fun FirSimpleFunction.overriddenFunctions(
containingClass: FirClass,
containingClass: FirClassSymbol<*>,
context: CheckerContext
): List<FirFunctionSymbol<*>> {
val firTypeScope = containingClass.unsubstitutedScope(
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
@@ -62,7 +62,7 @@ object FirOperatorModifierChecker : FirSimpleFunctionChecker() {
if (!declaration.isOperator) return
//we are not interested in implicit operators from override
if (!declaration.hasModifier(KtTokens.OPERATOR_KEYWORD)) return
val checks = OperatorFunctionChecks.checksByName.getOrElse(declaration.name) {
OperatorFunctionChecks.regexChecks.find { it.first.matches(declaration.name.asString()) }?.second
}
@@ -185,8 +185,8 @@ private object OperatorFunctionChecks {
EQUALS,
member,
Checks.full("must override ''equals()'' in Any") { ctx, function ->
val containingClass = function.containingClass()?.toFirRegularClass(ctx.session) ?: return@full true
function.overriddenFunctions(containingClass, ctx).any {
val containingClassSymbol = function.containingClass()?.toFirRegularClassSymbol(ctx.session) ?: return@full true
function.overriddenFunctions(containingClassSymbol, ctx).any {
it.containingClass()?.classId?.asSingleFqName() == StandardNames.FqNames.any.toSafe()
}
}
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
@@ -106,8 +106,8 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker() {
context: CheckerContext
): Boolean {
if (isEnum) return true
val firRegularClass = (this as? ConeClassLikeType)?.lookupTag?.toFirRegularClass(context.session) ?: return false
return firRegularClass.isEnumClass
val firRegularClassSymbol = (this as? ConeClassLikeType)?.lookupTag?.toFirRegularClassSymbol(context.session) ?: return false
return firRegularClassSymbol.isEnumClass
}
private fun checkSensibleness(
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.processDirectlyOverriddenFunctions
@@ -132,7 +132,7 @@ object FirOptInUsageBaseChecker {
val annotationType = annotation.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()
if (annotation.useSiteTarget != AnnotationUseSiteTarget.PROPERTY_SETTER || fromSetter) {
result.addIfNotNull(
annotationType?.lookupTag?.toFirRegularClass(
annotationType?.lookupTag?.toFirRegularClassSymbol(
session
)?.loadExperimentalityForMarkerAnnotation()
)
@@ -15,13 +15,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
@@ -145,25 +147,25 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
context: CheckerContext
): Boolean {
val session = context.session
val enclosingSuspendFunctionDispatchReceiverOwner =
(enclosingSuspendFunction.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.toFirRegularClass(session)
val enclosingSuspendFunctionExtensionReceiverOwner = enclosingSuspendFunction.takeIf { it.receiverTypeRef != null }
val enclosingSuspendFunctionDispatchReceiverOwnerSymbol =
(enclosingSuspendFunction.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.toFirRegularClassSymbol(session)
val enclosingSuspendFunctionExtensionReceiverOwnerSymbol = enclosingSuspendFunction.takeIf { it.receiverTypeRef != null }?.symbol
val dispatchReceiverExpression = expression.dispatchReceiver.takeIf { it !is FirNoReceiverExpression }
val extensionReceiverExpression = expression.extensionReceiver.takeIf { it !is FirNoReceiverExpression }
for (receiverExpression in listOfNotNull(dispatchReceiverExpression, extensionReceiverExpression)) {
if (!receiverExpression.typeRef.coneType.isRestrictSuspensionReceiver(session)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionDispatchReceiverOwner)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionExtensionReceiverOwner)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionDispatchReceiverOwnerSymbol)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionExtensionReceiverOwnerSymbol)) continue
return false
}
if (enclosingSuspendFunctionExtensionReceiverOwner?.receiverTypeRef?.coneType?.isRestrictSuspensionReceiver(session) != true) {
if (enclosingSuspendFunctionExtensionReceiverOwnerSymbol?.resolvedReceiverTypeRef?.coneType?.isRestrictSuspensionReceiver(session) != true) {
return true
}
if (sameInstanceOfReceiver(dispatchReceiverExpression, enclosingSuspendFunctionExtensionReceiverOwner)) {
if (sameInstanceOfReceiver(dispatchReceiverExpression, enclosingSuspendFunctionExtensionReceiverOwnerSymbol)) {
return true
}
if (sameInstanceOfReceiver(extensionReceiverExpression, enclosingSuspendFunctionExtensionReceiverOwner)) {
if (sameInstanceOfReceiver(extensionReceiverExpression, enclosingSuspendFunctionExtensionReceiverOwnerSymbol)) {
if (calledDeclarationSymbol.resolvedReceiverTypeRef?.coneType?.isRestrictSuspensionReceiver(session) == true) {
return true
}
@@ -174,11 +176,11 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
private fun ConeKotlinType.isRestrictSuspensionReceiver(session: FirSession): Boolean {
when (this) {
is ConeClassLikeType -> {
val regularClass = fullyExpandedType(session).lookupTag.toFirRegularClass(session) ?: return false
if (regularClass.hasAnnotation(RESTRICTS_SUSPENSION_CLASS_ID)) {
val regularClassSymbol = fullyExpandedType(session).lookupTag.toFirRegularClassSymbol(session) ?: return false
if (regularClassSymbol.getAnnotationByClassId(RESTRICTS_SUSPENSION_CLASS_ID) != null) {
return true
}
return regularClass.superTypeRefs.any { it.coneType.isRestrictSuspensionReceiver(session) }
return regularClassSymbol.superConeTypes.any { it.isRestrictSuspensionReceiver(session) }
}
is ConeTypeParameterType -> {
return lookupTag.typeParameterSymbol.resolvedBounds.any { it.coneType.isRestrictSuspensionReceiver(session) }
@@ -187,10 +189,13 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
}
}
private fun sameInstanceOfReceiver(useSiteReceiverExpression: FirExpression?, declarationSiteReceiverOwner: FirDeclaration?): Boolean {
if (declarationSiteReceiverOwner == null || useSiteReceiverExpression == null) return false
private fun sameInstanceOfReceiver(
useSiteReceiverExpression: FirExpression?,
declarationSiteReceiverOwnerSymbol: FirBasedSymbol<*>?
): Boolean {
if (declarationSiteReceiverOwnerSymbol == null || useSiteReceiverExpression == null) return false
if (useSiteReceiverExpression is FirThisReceiverExpression) {
return useSiteReceiverExpression.calleeReference.boundSymbol == declarationSiteReceiverOwner.symbol
return useSiteReceiverExpression.calleeReference.boundSymbol == declarationSiteReceiverOwnerSymbol
}
return false
}
@@ -95,8 +95,8 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
}
private fun findFunctionVisibility(function: FirSimpleFunction, context: CheckerContext): Visibility {
val currentClass = context.findClosestClassOrObject() ?: return Visibilities.Unknown
val overriddenFunctions = function.overriddenFunctions(currentClass, context)
val currentClassSymbol = context.findClosestClassOrObject()?.symbol ?: return Visibilities.Unknown
val overriddenFunctions = function.overriddenFunctions(currentClassSymbol, context)
var visibility: Visibility = Visibilities.Private
for (func in overriddenFunctions) {
val currentVisibility = func.visibility
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
import org.jetbrains.kotlin.fir.serialization.FirSerializerExtension
import org.jetbrains.kotlin.fir.types.*
@@ -260,14 +260,14 @@ class FirJvmSerializerExtension(
private fun FirProperty.isJvmFieldPropertyInInterfaceCompanion(): Boolean {
if (!hasJvmFieldAnnotation) return false
val container = (dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.toFirRegularClass(session)
val containerSymbol = (dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.toFirRegularClassSymbol(session)
// Note: companions are anyway forbidden in local classes
if (container == null || !container.isCompanion || container.isLocal) {
if (containerSymbol == null || !containerSymbol.isCompanion || containerSymbol.isLocal) {
return false
}
val grandParent =
container.classId.outerClassId?.let {
containerSymbol.classId.outerClassId?.let {
session.firProvider.getFirClassifierByFqName(it) as? FirRegularClass
}
return grandParent != null &&
@@ -13,9 +13,10 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -166,19 +167,19 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
// When converting type parameter bounds we should not attempt to load any classes, as this may trigger
// enhancement of type parameter bounds on some other class that depends on this one. Also, in case of raw
// types specifically there could be an infinite recursion on the type parameter itself.
val typeParameters = lookupTag.takeIf { mode != FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND }
?.toFirRegularClass(session)?.typeParameters
val typeParameterSymbols = lookupTag.takeIf { mode != FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND }
?.toFirRegularClassSymbol(session)?.typeParameterSymbols
val mappedTypeArguments = when {
isRaw ->
// Given `C<T : X>`, `C` -> `C<X>..C<*>?`.
typeParameters.takeIf { lowerBound == null }?.eraseToUpperBounds(session)
typeParameterSymbols.takeIf { lowerBound == null }?.eraseToUpperBounds(session)
?: Array(classifier.typeParameters.size) { ConeStarProjection }
lookupTag != lowerBound?.lookupTag ->
Array(typeArguments.size) { index ->
// TODO: check this
val newMode = if (mode == FirJavaTypeConversionMode.ANNOTATION_MEMBER) FirJavaTypeConversionMode.DEFAULT else mode
val argument = typeArguments[index]
val variance = typeParameters?.getOrNull(index)?.symbol?.fir?.variance ?: Variance.INVARIANT
val variance = typeParameterSymbols?.getOrNull(index)?.fir?.variance ?: Variance.INVARIANT
argument.toConeTypeProjection(session, javaTypeParameterStack, variance, newMode)
}
else -> lowerBound.typeArguments
@@ -211,15 +212,15 @@ private fun JavaClassifierType.argumentsMakeSenseOnlyForMutableContainer(
if (!typeArguments.lastOrNull().isSuperWildcard()) return false
val mutableLastParameterVariance =
mutableClassId.toLookupTag().toFirRegularClass(session)?.typeParameters?.lastOrNull()?.symbol?.fir?.variance
mutableClassId.toLookupTag().toFirRegularClassSymbol(session)?.typeParameterSymbols?.lastOrNull()?.variance
?: return false
return mutableLastParameterVariance != Variance.OUT_VARIANCE
}
private fun List<FirTypeParameterRef>.eraseToUpperBounds(session: FirSession): Array<ConeTypeProjection> {
private fun List<FirTypeParameterSymbol>.eraseToUpperBounds(session: FirSession): Array<ConeTypeProjection> {
val cache = mutableMapOf<FirTypeParameter, ConeKotlinType>()
return Array(size) { index -> this[index].symbol.fir.eraseToUpperBound(session, cache) }
return Array(size) { index -> this[index].fir.eraseToUpperBound(session, cache) }
}
private fun FirTypeParameter.eraseToUpperBound(session: FirSession, cache: MutableMap<FirTypeParameter, ConeKotlinType>): ConeKotlinType {
@@ -39,15 +39,19 @@ fun ConeClassLikeLookupTag.toSymbolOrError(useSiteSession: FirSession): FirClass
toSymbol(useSiteSession)
?: error("Class symbol with classId $classId was not found")
fun ConeClassLikeLookupTag.toFirRegularClass(session: FirSession): FirRegularClass? =
session.symbolProvider.getSymbolByLookupTag(this)?.fir as? FirRegularClass
@OptIn(LookupTagInternals::class)
fun ConeClassLikeLookupTag.toFirRegularClassSymbol(session: FirSession): FirRegularClassSymbol? =
session.symbolProvider.getSymbolByLookupTag(this) as? FirRegularClassSymbol
@OptIn(LookupTagInternals::class)
fun ConeClassLikeLookupTagImpl.bindSymbolToLookupTag(session: FirSession, symbol: FirClassLikeSymbol<*>?) {
boundSymbol = WeakPair(session, symbol)
}
@LookupTagInternals
fun ConeClassLikeLookupTag.toFirRegularClass(session: FirSession): FirRegularClass? =
session.symbolProvider.getSymbolByLookupTag(this)?.fir as? FirRegularClass
fun FirSymbolProvider.getSymbolByLookupTag(lookupTag: ConeClassifierLookupTag): FirClassifierSymbol<*>? {
return lookupTag.toSymbol(session)
}
@@ -505,6 +505,7 @@ fun FirRegularClass.getActualTypeParametersCount(session: FirSession): Int {
fun FirClassLikeDeclaration.getContainingDeclaration(session: FirSession): FirClassLikeDeclaration? {
if (isLocal) {
@OptIn(LookupTagInternals::class)
return (this as? FirRegularClass)?.containingClassForLocalAttr?.toFirRegularClass(session)
} else {
val classId = symbol.classId
@@ -69,6 +69,7 @@ class FirSamResolverImpl(
}
private fun getFunctionTypeForPossibleSamType(type: ConeClassLikeType): ConeLookupTagBasedType? {
@OptIn(LookupTagInternals::class)
val firRegularClass = type.lookupTag.toFirRegularClass(session) ?: return null
val unsubstitutedFunctionType = resolveFunctionTypeIfSamInterface(firRegularClass) ?: return null
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -844,7 +844,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
return when (val fir = this.fir) {
is FirConstructor -> fir.returnTypeRef.coneType.isLocal()
is FirCallableDeclaration -> {
fir.dispatchReceiverClassOrNull()?.toFirRegularClass(session)?.isLocal ?: false
fir.dispatchReceiverClassOrNull()?.toFirRegularClassSymbol(session)?.isLocal ?: false
}
else -> false
}
@@ -852,7 +852,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
private fun ConeKotlinType.isLocal(): Boolean {
if (this !is ConeClassLikeType) return false
return this.lookupTag.toFirRegularClass(session)?.isLocal == true
return this.lookupTag.toFirRegularClassSymbol(session)?.isLocal == true
}
// id == packageName + className
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getContainingFile
class FirDeclarationDesignationWithFile(
@@ -63,6 +64,7 @@ private fun collectDesignationPath(declaration: FirDeclaration): List<FirDeclara
is FirSimpleFunction, is FirProperty, is FirField, is FirConstructor -> {
val klass = declaration.containingClass() ?: return emptyList()
if (klass.classId.isLocal) return null
@OptIn(LookupTagInternals::class)
klass.toFirRegularClass(declaration.moduleData.session)
}
else -> return null
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.*
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.*
import org.jetbrains.kotlin.idea.fir.low.level.api.api.tryCollectDesignation
import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeRendererOptions
@@ -183,6 +184,7 @@ internal class ConeTypeIdeRenderer(
require(isLocal)
var containingClassLookUp = containingClassForLocal()
val designation = mutableListOf<FirClassLikeDeclaration>(this)
@OptIn(LookupTagInternals::class)
while (containingClassLookUp != null && containingClassLookUp.classId.isLocal) {
val currentClass = containingClassLookUp.toFirRegularClass(moduleData.session) ?: break
designation.add(currentClass)
@@ -192,6 +194,7 @@ internal class ConeTypeIdeRenderer(
}
private fun collectDesignationPathForLocal(declaration: FirDeclaration): List<FirDeclaration>? {
@OptIn(LookupTagInternals::class)
val containingClass = when (declaration) {
is FirCallableDeclaration -> declaration.containingClass()?.toFirRegularClass(declaration.moduleData.session)
is FirAnonymousObject -> return listOf(declaration)