[FIR] Replace getContainingClass usages with getContainingClassSymbol

This commit is contained in:
Dmitriy Novozhilov
2021-07-07 15:22:23 +03:00
committed by teamcityserver
parent 48a25e2fe6
commit c99a02796f
10 changed files with 84 additions and 96 deletions
@@ -242,7 +242,7 @@ internal object ConeTypeCompatibilityChecker {
private fun FirTypeParameterSymbol?.collectUpperBounds(): Set<ConeClassLikeType> {
if (this == null) return emptySet()
return fir.bounds.flatMap { it.coneTypeSafe<ConeKotlinType>().collectUpperBounds() }.toSet()
return resolvedBounds.flatMap { it.coneTypeSafe<ConeKotlinType>().collectUpperBounds() }.toSet()
}
private fun ConeKotlinType?.collectLowerBounds(): Set<ConeClassLikeType> {
@@ -17,17 +17,18 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
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.resolve.transformers.firClassLike
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
@@ -47,9 +48,9 @@ import org.jetbrains.kotlin.util.ImplementationStatus
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private val INLINE_ONLY_ANNOTATION_CLASS_ID = ClassId.topLevel(FqName("kotlin.internal.InlineOnly"))
private val INLINE_ONLY_ANNOTATION_CLASS_ID: ClassId = ClassId.topLevel(FqName("kotlin.internal.InlineOnly"))
fun FirClass.unsubstitutedScope(context: CheckerContext) =
fun FirClass.unsubstitutedScope(context: CheckerContext): FirTypeScope =
this.unsubstitutedScope(context.sessionHolder.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false)
/**
@@ -121,32 +122,21 @@ fun FirTypeRef.toRegularClass(session: FirSession): FirRegularClass? {
return coneType.toRegularClass(session)
}
/**
* Returns FirSimpleFunction based on the given FirFunctionCall
*/
inline fun <reified T : Any> FirQualifiedAccessExpression.getDeclaration(): T? {
return this.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol
?.fir as? T
}
/**
* Returns the ClassLikeDeclaration where the Fir object has been defined
* or null if no proper declaration has been found.
*/
fun FirDeclaration.getContainingClass(context: CheckerContext): FirClassLikeDeclaration? =
this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(context.session)?.fir
fun FirDeclaration.getContainingClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? =
this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(context.session)
fun FirClassLikeSymbol<*>.outerClass(context: CheckerContext): FirClassLikeSymbol<*>? {
fun FirBasedSymbol<*>.getContainingClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? = fir.getContainingClassSymbol(context)
fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? {
if (this !is FirClassSymbol<*>) return null
val outerClassId = classId.outerClassId ?: return null
return context.session.symbolProvider.getClassLikeSymbolByFqName(outerClassId)
}
fun FirClass.outerClass(context: CheckerContext): FirClass? {
return symbol.outerClass(context)?.fir as? FirClass
}
/**
* Returns the FirClassLikeDeclaration that the
* sequence of FirTypeAlias'es points to starting
@@ -290,10 +280,10 @@ fun FirClass.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef? {
return null
}
val FirFunctionCall.isIterator
val FirFunctionCall.isIterator: Boolean
get() = this.calleeReference.name.asString() == "<iterator>"
fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) =
fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession): Boolean =
session.builtinTypes.throwableType.type.isSupertypeOf(session.typeContext, this.fullyExpandedType(session))
val FirValueParameter.hasValOrVar: Boolean
@@ -302,10 +292,10 @@ val FirValueParameter.hasValOrVar: Boolean
return source.getChild(VAL_VAR_TOKEN_SET) != null
}
fun KotlinTypeMarker.isSupertypeOf(context: TypeCheckerProviderContext, type: KotlinTypeMarker?) =
fun KotlinTypeMarker.isSupertypeOf(context: TypeCheckerProviderContext, type: KotlinTypeMarker?): Boolean =
type != null && AbstractTypeChecker.isSubtypeOf(context, type, this)
fun KotlinTypeMarker.isSubtypeOf(context: TypeCheckerProviderContext, type: KotlinTypeMarker?) =
fun KotlinTypeMarker.isSubtypeOf(context: TypeCheckerProviderContext, type: KotlinTypeMarker?): Boolean =
type != null && AbstractTypeChecker.isSubtypeOf(context, this, type)
fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
@@ -380,7 +370,8 @@ private fun lowerThanBound(context: ConeInferenceContext, argument: ConeKotlinTy
return false
}
fun FirMemberDeclaration.isInlineOnly(): Boolean = isInline && (this as FirAnnotatedDeclaration).hasAnnotation(INLINE_ONLY_ANNOTATION_CLASS_ID)
fun FirMemberDeclaration.isInlineOnly(): Boolean =
isInline && (this as FirAnnotatedDeclaration).hasAnnotation(INLINE_ONLY_ANNOTATION_CLASS_ID)
fun isSubtypeForTypeMismatch(context: ConeInferenceContext, subtype: ConeKotlinType, supertype: ConeKotlinType): Boolean {
val subtypeFullyExpanded = subtype.fullyExpandedType(context.session)
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE
@@ -31,6 +31,7 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
if (!declaration.isInterface || !declaration.isFun) return
val scope = declaration.unsubstitutedScope(context)
val classSymbol = declaration.symbol
var abstractFunction: FirSimpleFunction? = null
@@ -52,7 +53,7 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
val firProperty = property.fir as? FirProperty ?: continue
if (firProperty.isAbstract) {
val source =
if (firProperty.getContainingClass(context) != declaration)
if (firProperty.getContainingClassSymbol(context) != classSymbol)
declaration.source
else
firProperty.source
@@ -67,7 +68,7 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
return
}
val inFunInterface = abstractFunction.getContainingClass(context) === declaration
val inFunInterface = abstractFunction.getContainingClassSymbol(context) === classSymbol
when {
abstractFunction.typeParameters.isNotEmpty() ->
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
import org.jetbrains.kotlin.util.ImplementationStatus
@@ -166,5 +167,5 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
}
private fun FirCallableDeclaration.isFromInterfaceOrEnum(context: CheckerContext): Boolean =
(getContainingClass(context) as? FirRegularClass)?.let { it.isInterface || it.isEnumClass } == true
(getContainingClassSymbol(context) as? FirRegularClassSymbol)?.let { it.isInterface || it.isEnumClass } == true
}
@@ -9,16 +9,17 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
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.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.getDeclaration
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.isAbstract
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirAbstractSuperCallChecker : FirQualifiedAccessExpressionChecker() {
@@ -33,16 +34,11 @@ object FirAbstractSuperCallChecker : FirQualifiedAccessExpressionChecker() {
if (closestClass.classKind == ClassKind.CLASS) {
// handles all the FirSimpleFunction/FirProperty/etc.
val item = expression.getDeclaration<FirCallableDeclaration>()
?: return
val declarationSymbol = expression.toResolvedCallableSymbol() ?: return
val declaration = item.getContainingClass(context).safeAs<FirRegularClass>()
?: return
val containingClassSymbol = declarationSymbol.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol ?: return
if (
declaration.modality == Modality.ABSTRACT &&
item.modality == Modality.ABSTRACT
) {
if (containingClassSymbol.isAbstract && declarationSymbol.isAbstract) {
reporter.reportOn(expression.calleeReference.source, FirErrors.ABSTRACT_SUPER_CALL, context)
}
}
@@ -8,14 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.descriptors.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.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -29,22 +28,12 @@ object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessExpres
val closestClass = context.findClosest<FirRegularClass>() ?: return
if (closestClass.classKind == ClassKind.INTERFACE) {
val origin = getClassLikeDeclaration(expression, context)
?.symbol.safeAs<FirRegularClassSymbol>()
?.fir
?: return
val containingClassSymbol =
expression.toResolvedCallableSymbol()?.getContainingClassSymbol(context) as? FirRegularClassSymbol ?: return
if (origin.source != null && origin.classKind == ClassKind.CLASS) {
if (containingClassSymbol.classKind == ClassKind.CLASS) {
reporter.reportOn(expression.explicitReceiver?.source, FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE, context)
}
}
}
/**
* Returns the ClassLikeDeclaration where the function has been defined
* or null if no proper declaration has been found.
*/
private fun getClassLikeDeclaration(functionCall: FirQualifiedAccessExpression, context: CheckerContext): FirClassLikeDeclaration? {
return functionCall.calleeReference.safeAs<FirResolvedNamedReference>()?.resolvedSymbol?.fir?.getContainingClass(context)
}
}
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isEnumEntryInitializer
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.outerClass
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.outerClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -18,6 +18,10 @@ import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// Initialization order: member property initializers, enum entries, companion object (including members in it).
@@ -68,17 +72,17 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
if (source.kind is FirFakeSourceElementKind) return
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
val calleeDeclaration = reference.resolvedSymbol.fir
val calleeContainingClass = calleeDeclaration.getContainingClass(context) as? FirRegularClass ?: return
val calleeSymbol = reference.resolvedSymbol
val calleeContainingClassSymbol = calleeSymbol.getContainingClassSymbol(context) as? FirRegularClassSymbol ?: return
// We're looking for members/entries/companion object in an enum class or members in companion object of an enum class.
val calleeIsInsideEnum = calleeContainingClass.isEnumClass
val calleeIsInsideEnum = calleeContainingClassSymbol.isEnumClass
val calleeIsInsideEnumCompanion =
calleeContainingClass.isCompanion && (calleeContainingClass.outerClass(context) as? FirRegularClass)?.isEnumClass == true
calleeContainingClassSymbol.isCompanion && (calleeContainingClassSymbol.outerClassSymbol(context) as? FirRegularClassSymbol)?.isEnumClass == true
if (!calleeIsInsideEnum && !calleeIsInsideEnumCompanion) return
val enumClass =
if (calleeIsInsideEnum) calleeContainingClass
else calleeContainingClass.outerClass(context) as? FirRegularClass ?: return
val enumClassSymbol =
if (calleeIsInsideEnum) calleeContainingClassSymbol
else calleeContainingClassSymbol.outerClassSymbol(context) as? FirRegularClassSymbol ?: return
// An accessed context within the enum class of interest. We should look up until either enum members or enum entries are found,
// not just last containing declaration. For example,
@@ -99,11 +103,11 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// INSTANCE(EnumCompanion2.foo())
// }
// find an accessed context within the same enum class.
it.getContainingClass(context) == enumClass
} ?: return
it.getContainingClassSymbol(context) == enumClassSymbol
}?.symbol ?: return
val enumMemberProperties = enumClass.declarations.filterIsInstance<FirProperty>()
val enumEntries = enumClass.declarations.filterIsInstance<FirEnumEntry>()
val enumMemberProperties = enumClassSymbol.declarationSymbols.filterIsInstance<FirPropertySymbol>()
val enumEntries = enumClassSymbol.declarationSymbols.filterIsInstance<FirEnumEntrySymbol>()
// When checking enum member properties, accesses to enum entries in lazy delegation is legitimate, e.g.,
// enum JvmTarget(...) {
@@ -114,7 +118,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// }
// }
if (accessedContext in enumMemberProperties) {
val lazyDelegation = (accessedContext as FirProperty).lazyDelegation
val lazyDelegation = (accessedContext as FirPropertySymbol).lazyDelegation
if (lazyDelegation != null && lazyDelegation == context.containingDeclarations.lastOrNull()) {
return
}
@@ -135,10 +139,10 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
}
// Members inside the companion object of an enum class
if (calleeContainingClass == enumClass.companionObject) {
if (calleeContainingClassSymbol == enumClassSymbol.companionObjectSymbol) {
// Uninitialized from the point of view of members or enum entries of that enum class
if (accessedContext in enumMemberProperties || accessedContext in enumEntries) {
if (calleeDeclaration is FirProperty) {
if (calleeSymbol is FirProperty) {
// From KT-11769
// enum class Fruit(...) {
// APPLE(...);
@@ -147,7 +151,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// }
// val score = ... <!>common<!>
// }
reporter.reportOn(source, FirErrors.UNINITIALIZED_VARIABLE, calleeDeclaration.symbol, context)
reporter.reportOn(source, FirErrors.UNINITIALIZED_VARIABLE, calleeSymbol.symbol, context)
} else {
// enum class EnumCompanion2(...) {
// INSTANCE(<!>foo<!>())
@@ -156,18 +160,18 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// }
// }
// <!>Companion<!>.foo() v.s. <!>foo<!>()
if ((expression.explicitReceiver as? FirResolvedQualifier)?.symbol?.fir == enumClass.companionObject) {
if ((expression.explicitReceiver as? FirResolvedQualifier)?.symbol == enumClassSymbol.companionObjectSymbol) {
reporter.reportOn(
expression.explicitReceiver!!.source,
FirErrors.UNINITIALIZED_ENUM_COMPANION,
enumClass.symbol,
enumClassSymbol,
context
)
} else {
reporter.reportOn(
expression.calleeReference.source,
FirErrors.UNINITIALIZED_ENUM_COMPANION,
enumClass.symbol,
enumClassSymbol,
context
)
}
@@ -176,8 +180,8 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
}
// The enum entries of an enum class
if (calleeDeclaration in enumEntries) {
val calleeEnumEntry = calleeDeclaration as FirEnumEntry
if (calleeSymbol in enumEntries) {
val calleeEnumEntry = calleeSymbol as FirEnumEntrySymbol
// Uninitialized from the point of view of members of that enum class
if (accessedContext in enumMemberProperties) {
// From KT-6054
@@ -188,7 +192,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// <!>B<!> -> ...
// }
// }
reporter.reportOn(source, FirErrors.UNINITIALIZED_ENUM_ENTRY, calleeEnumEntry.symbol, context)
reporter.reportOn(source, FirErrors.UNINITIALIZED_ENUM_ENTRY, calleeEnumEntry, context)
}
// enum class A(...) {
// A1(<!>A2<!>),
@@ -198,7 +202,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
if (accessedContext in enumEntries) {
// Technically, this is equal to `enumEntries.indexOf(accessedContext) <= enumEntries.indexOf(calleeDeclaration)`.
// Instead of double `indexOf`, we can iterate entries just once until either one appears.
var precedingEntry: FirEnumEntry? = null
var precedingEntry: FirEnumEntrySymbol? = null
enumEntries.forEach {
if (precedingEntry != null) return@forEach
if (it == calleeEnumEntry || it == accessedContext) {
@@ -206,16 +210,17 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
}
}
if (precedingEntry == accessedContext) {
reporter.reportOn(source, FirErrors.UNINITIALIZED_ENUM_ENTRY, calleeEnumEntry.symbol, context)
reporter.reportOn(source, FirErrors.UNINITIALIZED_ENUM_ENTRY, calleeEnumEntry, context)
}
}
}
}
private val FirProperty.lazyDelegation: FirAnonymousFunction?
private val FirPropertySymbol.lazyDelegation: FirAnonymousFunction?
get() {
if (delegate == null || delegate !is FirFunctionCall) return null
val delegateCall = delegate as FirFunctionCall
ensureResolved(FirResolvePhase.BODY_RESOLVE)
if (fir.delegate == null || fir.delegate !is FirFunctionCall) return null
val delegateCall = fir.delegate as FirFunctionCall
val callee =
(delegateCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirSimpleFunction ?: return null
if (callee.symbol.callableId.asSingleFqName().asString() != "kotlin.lazy") return null
@@ -5,22 +5,26 @@
package org.jetbrains.kotlin.fir.analysis.checkers.extended
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirFakeSourceElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.*
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.isLocalMember
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.overriddenFunctions
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDeclarationSyntaxChecker
import org.jetbrains.kotlin.fir.analysis.checkers.toVisibilityOrNull
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.declarations.utils.isSealed
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -71,10 +75,10 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
}
this is FirConstructor -> {
val clazz = this.getContainingClass(context)
val classSymbol = this.getContainingClassSymbol(context)
if (
clazz is FirClass
&& (clazz.classKind == ClassKind.ENUM_CLASS || clazz.modality() == Modality.SEALED)
classSymbol is FirRegularClassSymbol
&& (classSymbol.isEnumClass || classSymbol.isSealed)
) {
Visibilities.Private
} else {
@@ -14,11 +14,12 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.cfa.*
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClass
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.isIterator
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
@@ -31,10 +32,7 @@ import org.jetbrains.kotlin.fir.types.coneType
object UnusedChecker : FirControlFlowChecker() {
override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) {
if (graph.declaration?.getContainingClass(context)?.takeIf {
!it.symbol.classId.isLocal
} != null
) return
if (graph.declaration?.getContainingClassSymbol(context)?.takeIf { !it.isLocal } != null) return
val (properties, _) = LocalPropertyAndCapturedWriteCollector.collect(graph)
if (properties.isEmpty()) return
@@ -57,6 +57,9 @@ class FirRegularClassSymbol(classId: ClassId) : FirClassSymbol<FirRegularClass>(
ensureResolved(FirResolvePhase.STATUS)
return fir.status as FirResolvedDeclarationStatus
}
val companionObjectSymbol: FirRegularClassSymbol?
get() = fir.companionObject?.symbol
}
val ANONYMOUS_CLASS_ID = ClassId(FqName.ROOT, FqName.topLevel(Name.special("<anonymous>")), true)