[FIR] Remove unneeded symbol.fir accesses

This commit is contained in:
Nikolay Lunyak
2024-01-11 14:32:37 +02:00
committed by Space Team
parent 965d8d2fd5
commit 95989fc3e2
19 changed files with 97 additions and 85 deletions
@@ -22,8 +22,9 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.isEnumEntries
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.js.common.RESERVED_KEYWORDS
import org.jetbrains.kotlin.js.common.SPECIAL_KEYWORDS
@@ -73,7 +74,7 @@ object FirJsExportDeclarationChecker : FirBasicDeclarationChecker() {
checkTypeParameter(typeParameter)
}
if (declaration.isInlineWithReified) {
if (declaration.symbol.isInlineWithReified) {
reportWrongExportedDeclaration("inline function with reified type parameters")
return
}
@@ -153,13 +154,12 @@ object FirJsExportDeclarationChecker : FirBasicDeclarationChecker() {
return parent != null && parent.isInterface
}
private val FirCallableDeclaration.isInlineWithReified: Boolean
private val FirCallableSymbol<*>.isInlineWithReified: Boolean
get() = when (this) {
is FirPropertyAccessor -> {
@OptIn(SymbolInternals::class)
this.propertySymbol.fir.isInlineWithReified
is FirPropertyAccessorSymbol -> {
this.propertySymbol.isInlineWithReified
}
else -> typeParameters.any { it.symbol.isReified }
else -> typeParameterSymbols.any { it.isReified }
}
private fun ConeKotlinType.isExportableReturn(session: FirSession, currentlyProcessed: MutableSet<ConeKotlinType> = hashSetOf()) =
@@ -208,8 +208,7 @@ object FirJsExportDeclarationChecker : FirBasicDeclarationChecker() {
return when {
isPrimitiveExportableType -> true
@OptIn(SymbolInternals::class)
symbol?.fir !is FirMemberDeclaration -> false
symbol?.isMemberDeclaration != true -> false
isEnum -> true
else -> symbol.isEffectivelyExternal(session) || symbol.isExportedObject(session)
}
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.fir.analysis.jvm
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
/**
* With JVM compilation
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
* `kotlin.Throwable` does not require `override` keyword.
*/
object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatibilityHelper() {
override fun additionalCheck(member: FirCallableDeclaration): Boolean? {
override fun additionalCheck(member: FirCallableSymbol<*>): Boolean? {
if (!member.isJavaOrEnhancement) return false
val containingClassName = member.containingClassLookupTag()?.classId?.asSingleFqName()?.toUnsafe() ?: return false
// If the super class is mapped to a Kotlin built-in class, then we don't require `override` keyword.
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.coneType
@@ -212,10 +211,7 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() {
private fun CheckerContext.containerIsNonCompanionObject(outerLevel: Int): Boolean {
val containingClassSymbol = this.getContainerAt(outerLevel) ?: return false
@OptIn(SymbolInternals::class)
val containingClass = (containingClassSymbol.fir as? FirRegularClass) ?: return false
val containingClass = (containingClassSymbol as? FirRegularClassSymbol) ?: return false
return containingClass.classKind == ClassKind.OBJECT && !containingClass.isCompanion
}
@@ -7,18 +7,17 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAbstractOverrideChecker
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.java.enhancement.EnhancedForWarningConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.firOverrideChecker
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.typeContext
@@ -41,22 +40,21 @@ object FirOverrideJavaNullabilityWarningChecker : FirAbstractOverrideChecker() {
val enhancedOverrides = scope
.getDirectOverriddenFunctions(member.symbol)
.map {
@OptIn(SymbolInternals::class)
val substitutedBase = it.fir.substituteOrNull(substitutor, context) ?: return@map it
val substitutedBase = it.substituteOrNull(substitutor, context) ?: return@map it
anyBaseEnhanced = true
if (!anyReported && !context.session.firOverrideChecker.isOverriddenFunction(member, substitutedBase)) {
if (!anyReported && !context.session.firOverrideChecker.isOverriddenFunction(member.symbol, substitutedBase)) {
anyReported = true
reporter.reportOn(
member.source,
FirJvmErrors.WRONG_NULLABILITY_FOR_JAVA_OVERRIDE,
member.symbol,
substitutedBase.symbol,
substitutedBase,
context
)
}
substitutedBase.symbol
substitutedBase
}
if (anyBaseEnhanced && !anyReported) {
@@ -70,22 +68,21 @@ object FirOverrideJavaNullabilityWarningChecker : FirAbstractOverrideChecker() {
val enhancedOverrides = scope
.getDirectOverriddenProperties(member.symbol)
.map {
@OptIn(SymbolInternals::class)
val substitutedBase = it.fir.substituteOrNull(substitutor, context) ?: return@map it
val substitutedBase = it.substituteOrNull(substitutor, context) ?: return@map it
anyBaseEnhanced = true
if (!anyReported && !context.session.firOverrideChecker.isOverriddenProperty(member, substitutedBase)) {
if (!anyReported && !context.session.firOverrideChecker.isOverriddenProperty(member.symbol, substitutedBase)) {
anyReported = true
reporter.reportOn(
member.source,
FirJvmErrors.WRONG_NULLABILITY_FOR_JAVA_OVERRIDE,
member.symbol,
substitutedBase.symbol,
substitutedBase,
context
)
}
substitutedBase.symbol
substitutedBase
}
if (anyBaseEnhanced && !anyReported) {
@@ -133,6 +130,15 @@ private fun FirSimpleFunction.substituteOrNull(
}
}
private fun FirNamedFunctionSymbol.substituteOrNull(
substitutor: EnhancedForWarningConeSubstitutor,
context: CheckerContext,
): FirNamedFunctionSymbol? {
// Ok, because `substituteOrNull` calls lazyResolveToPhase
@OptIn(SymbolInternals::class)
return fir.substituteOrNull(substitutor, context)?.symbol
}
/**
* @see org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope.createSubstitutionOverrideProperty
* @see org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope.createSubstitutedData
@@ -163,4 +169,13 @@ private fun FirProperty.substituteOrNull(
newReceiverType = newExtensionReceiverType,
)
}
}
}
private fun FirPropertySymbol.substituteOrNull(
substitutor: EnhancedForWarningConeSubstitutor,
context: CheckerContext,
): FirPropertySymbol? {
// Ok, because `substituteOrNull` calls `lazyResolveToPhase`
@OptIn(SymbolInternals::class)
return fir.substituteOrNull(substitutor, context)?.symbol
}
@@ -7,14 +7,12 @@ package org.jetbrains.kotlin.fir.analysis.wasm.checkers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.web.common.checkers.FirAbstractWebCheckerUtils
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
object FirWasmWebCheckerUtils : FirAbstractWebCheckerUtils() {
@OptIn(SymbolInternals::class)
override fun isNativeOrExternalInterface(symbol: FirBasedSymbol<*>, session: FirSession): Boolean =
symbol.isEffectivelyExternal(session) && (symbol.fir as? FirClass)?.isInterface == true
symbol.isEffectivelyExternal(session) && (symbol as? FirClassSymbol<*>)?.isInterface == true
}
@@ -15,8 +15,9 @@ import org.jetbrains.kotlin.fir.declarations.utils.isInterface
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
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.name.ClassId
@@ -54,16 +55,14 @@ abstract class FirOverridesBackwardCompatibilityHelper : FirSessionComponent {
val originalMemberSymbol = symbol.originalOrSelf()
originalMemberSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
@OptIn(SymbolInternals::class)
val originalMember = originalMemberSymbol.fir
if (originalMember.hasAnnotation(platformDependentAnnotation, context.session)) {
if (originalMemberSymbol.hasAnnotation(platformDependentAnnotation, context.session)) {
return true
}
additionalCheck(originalMember)?.let { return it }
additionalCheck(originalMemberSymbol)?.let { return it }
if (!originalMember.isAbstract) {
val containingClass = originalMember.containingClassLookupTag()?.toFirRegularClassSymbol(context.session)
if (!originalMemberSymbol.isAbstract) {
val containingClass = originalMemberSymbol.containingClassLookupTag()?.toFirRegularClassSymbol(context.session)
if (containingClass?.isInterface == false) {
return false
}
@@ -71,16 +70,16 @@ abstract class FirOverridesBackwardCompatibilityHelper : FirSessionComponent {
val scope =
symbol.dispatchReceiverClassTypeOrNull()?.toRegularClassSymbol(context.session)?.unsubstitutedScope(context) ?: return false
val overriddenSymbols = when (originalMember) {
is FirSimpleFunction -> scope.getDirectOverriddenFunctions(originalMember.symbol)
is FirProperty -> scope.getDirectOverriddenProperties(originalMember.symbol)
val overriddenSymbols = when (originalMemberSymbol) {
is FirNamedFunctionSymbol -> scope.getDirectOverriddenFunctions(originalMemberSymbol)
is FirPropertySymbol -> scope.getDirectOverriddenProperties(originalMemberSymbol)
else -> return false
}
if (overriddenSymbols.isEmpty()) return false
return overriddenSymbols.all { isPlatformSpecificSymbolThatCanBeImplicitlyOverridden(it, visitedSymbols, context) }
}
protected open fun additionalCheck(member: FirCallableDeclaration): Boolean? = null
protected open fun additionalCheck(member: FirCallableSymbol<*>): Boolean? = null
}
val FirSession.overridesBackwardCompatibilityHelper: FirOverridesBackwardCompatibilityHelper by FirSession.sessionComponentAccessor()
@@ -85,7 +85,6 @@ fun PropertyInitializationInfoData.checkPropertyAccesses(
)
}
@OptIn(SymbolInternals::class)
private fun PropertyInitializationInfoData.checkPropertyAccesses(
graph: ControlFlowGraph,
properties: Set<FirPropertySymbol>,
@@ -116,7 +115,7 @@ private fun PropertyInitializationInfoData.checkPropertyAccesses(
node is VariableAssignmentNode -> {
val symbol = node.fir.calleeReference?.toResolvedPropertySymbol() ?: continue
if (!symbol.fir.isVal || node.fir.unwrapLValue()?.hasCorrectReceiver() != true || symbol !in properties) continue
if (!symbol.isVal || node.fir.unwrapLValue()?.hasCorrectReceiver() != true || symbol !in properties) continue
if (getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) {
reporter.reportOn(node.fir.lValue.source, FirErrors.VAL_REASSIGNMENT, symbol, context)
@@ -518,15 +518,14 @@ private fun FirDeclarationCollector<*>.areNonConflictingCallables(
return session.declarationOverloadabilityHelper.isOverloadable(declaration, conflicting)
}
@OptIn(SymbolInternals::class)
internal fun FirVariable.getDestructuredParameter(): FirValueParameter? {
internal fun FirVariable.getDestructuredParameter(): FirValueParameterSymbol? {
val initializer = initializer
if (initializer !is FirComponentCall) return null
if (initializer.source?.kind !is KtFakeSourceElementKind.DesugaredComponentFunctionCall) return null
val receiver = initializer.dispatchReceiver ?: initializer.extensionReceiver ?: return null
if (receiver !is FirPropertyAccessExpression) return null
val calleeReference = receiver.calleeReference as? FirResolvedNamedReference ?: return null
return calleeReference.resolvedSymbol.fir as? FirValueParameter
return calleeReference.resolvedSymbol as? FirValueParameterSymbol
}
/** Checks for redeclarations of value and type parameters, and local variables. */
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
import org.jetbrains.kotlin.fir.declarations.utils.isConst
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
@@ -194,19 +193,19 @@ internal fun checkConstantArguments(
val propertySymbol = expressionSymbol as? FirPropertySymbol ?: return ConstantArgumentKind.NOT_CONST
@OptIn(SymbolInternals::class)
val property = propertySymbol.fir
when {
property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty(session) -> {
propertySymbol.unwrapFakeOverrides().canBeEvaluated() || propertySymbol.isCompileTimeBuiltinProperty(session) -> {
val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != null }!!
return checkConstantArguments(receiver, session)
}
propertySymbol.isLocal -> return ConstantArgumentKind.NOT_CONST
expressionType.classId == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL
}
return when (property.initializer) {
// Ok, because we only look at the structure, not resolution-dependent properties.
@OptIn(SymbolInternals::class)
return when (propertySymbol.fir.initializer) {
is FirConstExpression<*> -> when {
property.isVal -> ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION
propertySymbol.isVal -> ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION
else -> ConstantArgumentKind.NOT_CONST
}
is FirGetClassCall -> ConstantArgumentKind.NOT_KCLASS_LITERAL
@@ -255,7 +254,7 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(session: FirSession): Boole
return false
}
private fun FirProperty.isCompileTimeBuiltinProperty(session: FirSession): Boolean {
private fun FirPropertySymbol.isCompileTimeBuiltinProperty(session: FirSession): Boolean {
val receiverType = dispatchReceiverType ?: receiverParameter?.typeRef?.coneTypeSafe<ConeKotlinType>() ?: return false
val receiverClassId = receiverType.fullyExpandedClassId(session) ?: return false
return when (name.asString()) {
@@ -345,13 +345,11 @@ fun FirCallableSymbol<*>.getImplementationStatus(
var hasImplementationVar = false
for (intersection in symbol.intersections) {
@OptIn(SymbolInternals::class)
val fir = intersection.fir
val unwrappedFir = fir.unwrapFakeOverrides()
val isVar = unwrappedFir is FirProperty && unwrappedFir.isVar
val isFromClass = unwrappedFir.getContainingClassSymbol(sessionHolder.session)?.classKind == ClassKind.CLASS
val unwrapped = intersection.unwrapFakeOverrides()
val isVar = unwrapped is FirPropertySymbol && unwrapped.isVar
val isFromClass = unwrapped.getContainingClassSymbol(sessionHolder.session)?.classKind == ClassKind.CLASS
if (fir.isAbstract) {
if (intersection.isAbstract) {
if (isFromClass) {
hasAbstractFromClass = true
}
@@ -359,7 +357,7 @@ fun FirCallableSymbol<*>.getImplementationStatus(
hasAbstractVar = true
}
} else {
if (fir.origin == FirDeclarationOrigin.Delegated) {
if (intersection.origin == FirDeclarationOrigin.Delegated) {
hasInterfaceDelegation = true
}
if (isFromClass) {
@@ -53,7 +53,9 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
private fun getDestructuredParameters(function: FirFunction): List<FirVariable> {
if (function.valueParameters.none { it.name == SpecialNames.DESTRUCT }) return function.valueParameters
val destructuredParametersBoxes = function.valueParameters.filterTo(mutableSetOf()) { it.name == SpecialNames.DESTRUCT }
val destructuredParametersBoxes = function.valueParameters
.filter { it.name == SpecialNames.DESTRUCT }
.mapTo(mutableSetOf()) { it.symbol }
return function.body?.statements.orEmpty().mapNotNullTo(function.valueParameters.toMutableList()) {
val destructuredParameter = (it as? FirVariable)?.getDestructuredParameter() ?: return@mapNotNullTo null
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.toResolvedValueParameterSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
@@ -97,8 +96,7 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
val referredParameter = qualifiedAccessExpression.calleeReference.toResolvedValueParameterSymbol() ?: return
@OptIn(SymbolInternals::class)
val referredParameterIndex = function.valueParameters.indexOf(referredParameter.fir)
val referredParameterIndex = function.valueParameters.indexOfFirst { it.symbol == referredParameter }
// Skip if the referred parameter is not declared in the same function.
if (referredParameterIndex < 0) return
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDeprecated
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
object FirDeprecatedQualifierChecker : FirResolvedQualifierChecker() {
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -27,8 +26,7 @@ object FirDeprecatedQualifierChecker : FirResolvedQualifierChecker() {
// is handled automatically when getting deprecationInfo
// for the typealias symbol (in FirDeprecationChecker).
// Below we check "the last transition".
@OptIn(SymbolInternals::class)
val companionSymbol = expression.symbol?.fullyExpandedClass(context.session)?.fir?.companionObjectSymbol ?: return
val companionSymbol = expression.symbol?.fullyExpandedClass(context.session)?.companionObjectSymbol ?: return
FirDeprecationChecker.reportApiStatusIfNeeded(expression.source, companionSymbol, context, reporter)
}
}
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.utils.sourceElement
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType
@@ -34,8 +33,7 @@ object FirIncompatibleClassExpressionChecker : FirQualifiedAccessExpressionCheck
}
}
@OptIn(SymbolInternals::class)
checkSourceElement(symbol.fir.containerSource, expression, context, reporter)
checkSourceElement(symbol.containerSource, expression, context, reporter)
}
internal fun checkType(type: ConeKotlinType?, element: FirElement, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
import org.jetbrains.kotlin.fir.declarations.utils.isInline
@@ -19,7 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.StandardClassIds.Annotations
@@ -51,7 +50,8 @@ object FirLateinitIntrinsicApplicabilityChecker : FirQualifiedAccessExpressionCh
}
// property must be declared in one of the outer lexical scopes
if (calleePropertySymbol.containingClassOrFile(context) !in context.containingDeclarations) {
val containingSymbol = calleePropertySymbol.containingClassOrFile(context)
if (context.containingDeclarations.none { it.symbol == containingSymbol }) {
reporter.reportOn(
source,
FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY,
@@ -70,11 +70,10 @@ object FirLateinitIntrinsicApplicabilityChecker : FirQualifiedAccessExpressionCh
/**
* Returns the containing class or file if the property is top-level.
*/
@OptIn(SymbolInternals::class)
private fun FirPropertySymbol.containingClassOrFile(
context: CheckerContext
): FirDeclaration? {
return getContainingClassSymbol(context.session)?.fir
?: context.session.firProvider.getFirCallableContainerFile(this)
): FirBasedSymbol<*>? {
return getContainingClassSymbol(context.session)
?: context.session.firProvider.getFirCallableContainerFile(this)?.symbol
}
}
@@ -150,9 +150,8 @@ object FirOptInUsageBaseChecker {
fromSetter = false, dispatchReceiverType = null, fromSupertype = true
)
@OptIn(SymbolInternals::class)
fun FirClassLikeSymbol<*>.isExperimentalMarker(session: FirSession) =
this is FirRegularClassSymbol && fir.getAnnotationByClassId(OptInNames.REQUIRES_OPT_IN_CLASS_ID, session) != null
this is FirRegularClassSymbol && getAnnotationByClassId(OptInNames.REQUIRES_OPT_IN_CLASS_ID, session) != null
@OptIn(SymbolInternals::class)
private fun FirBasedSymbol<*>.loadExperimentalities(
@@ -284,7 +283,7 @@ object FirOptInUsageBaseChecker {
else -> null
}
val severity = Experimentality.Severity.values().firstOrNull { it.name == levelName } ?: Experimentality.DEFAULT_SEVERITY
val severity = Experimentality.Severity.entries.firstOrNull { it.name == levelName } ?: Experimentality.DEFAULT_SEVERITY
val message = (experimental.findArgumentByName(MESSAGE) as? FirConstExpression<*>)?.value as? String
return Experimentality(symbol.classId, severity, message, annotatedOwnerClassName)
}
@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
interface FirOverrideChecker : FirSessionComponent {
fun isOverriddenFunction(
@@ -29,4 +31,9 @@ fun FirOverrideChecker.isOverriddenFunction(
baseDeclaration: FirNamedFunctionSymbol
): Boolean = isOverriddenFunction(overrideCandidate.fir, baseDeclaration.fir)
fun FirOverrideChecker.isOverriddenProperty(
overrideCandidate: FirCallableSymbol<*>,
baseDeclaration: FirPropertySymbol
): Boolean = isOverriddenProperty(overrideCandidate.fir, baseDeclaration.fir)
val FirSession.firOverrideChecker: FirOverrideChecker by FirSession.sessionComponentAccessor()
@@ -50,6 +50,10 @@ val FirDeclaration.isNonLocal
val FirCallableDeclaration.isExtension get() = receiverParameter != null
val FirBasedSymbol<*>.isMemberDeclaration: Boolean
// Accessing `fir` is ok, because we don't really use it
get() = fir is FirMemberDeclaration
val FirBasedSymbol<*>.memberDeclarationNameOrNull: Name?
// Accessing `fir` is ok, because `nameOrSpecialName` only accesses names
get() = (fir as? FirMemberDeclaration)?.nameOrSpecialName
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>(), CallableSymbolMarker {
abstract val callableId: CallableId
@@ -76,6 +77,10 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>
val name: Name
get() = callableId.callableName
val containerSource: DeserializedContainerSource?
// This is ok, because containerSource should be set during fir creation
get() = fir.containerSource
fun getDeprecation(languageVersionSettings: LanguageVersionSettings): DeprecationsPerUseSite? {
lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS)
return fir.deprecationsProvider.getDeprecationsInfo(languageVersionSettings)