[FIR] Fix all illegal usages of symbol.fir in checkers module

This commit is contained in:
Dmitriy Novozhilov
2021-07-07 15:54:50 +03:00
committed by teamcityserver
parent e94d75d433
commit 22a4da024b
96 changed files with 1301 additions and 1077 deletions
@@ -7,12 +7,14 @@ package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File import java.io.File
@OptIn(SymbolInternals::class)
abstract class AbstractFirLoadBinariesTest : AbstractFirResolveWithSessionTestCase() { abstract class AbstractFirLoadBinariesTest : AbstractFirResolveWithSessionTestCase() {
/** /**
* Since fir symbol providers can't get all names in package (only fir provider can do it), * Since fir symbol providers can't get all names in package (only fir provider can do it),
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.createSessionForTests
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -39,6 +40,7 @@ import java.io.File
import java.io.IOException import java.io.IOException
import kotlin.reflect.jvm.javaField import kotlin.reflect.jvm.javaField
@OptIn(SymbolInternals::class)
abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() { abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
private lateinit var javaFilesDir: File private lateinit var javaFilesDir: File
@@ -16,8 +16,10 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@OptIn(SymbolInternals::class)
fun renderJavaClass(renderer: FirRenderer, javaClass: FirJavaClass, session: FirSession) { fun renderJavaClass(renderer: FirRenderer, javaClass: FirJavaClass, session: FirSession) {
val memberScope = javaClass.unsubstitutedScope(session, ScopeSession(), withForcedTypeCalculator = true) val memberScope = javaClass.unsubstitutedScope(session, ScopeSession(), withForcedTypeCalculator = true)
@@ -134,7 +134,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val NOT_A_SUPERTYPE by error<PsiElement>() val NOT_A_SUPERTYPE by error<PsiElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error<PsiElement>() val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error<PsiElement>()
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error<KtTypeReference> { val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error<KtTypeReference> {
parameter<FirClass>("otherSuperType") parameter<Symbol>("otherSuperType")
} }
val SUPERTYPE_INITIALIZED_IN_INTERFACE by error<KtTypeReference>() val SUPERTYPE_INITIALIZED_IN_INTERFACE by error<KtTypeReference>()
val INTERFACE_WITH_SUPERCLASS by error<KtTypeReference>() val INTERFACE_WITH_SUPERCLASS by error<KtTypeReference>()
@@ -384,10 +384,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val NON_VARARG_SPREAD by error<LeafPsiElement>() val NON_VARARG_SPREAD by error<LeafPsiElement>()
val ARGUMENT_PASSED_TWICE by error<KtValueArgument>(PositioningStrategy.NAME_OF_NAMED_ARGUMENT) val ARGUMENT_PASSED_TWICE by error<KtValueArgument>(PositioningStrategy.NAME_OF_NAMED_ARGUMENT)
val TOO_MANY_ARGUMENTS by error<PsiElement> { val TOO_MANY_ARGUMENTS by error<PsiElement> {
parameter<FirCallableDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
} }
val NO_VALUE_FOR_PARAMETER by error<KtElement>(PositioningStrategy.VALUE_ARGUMENTS) { val NO_VALUE_FOR_PARAMETER by error<KtElement>(PositioningStrategy.VALUE_ARGUMENTS) {
parameter<FirValueParameter>("violatedParameter") parameter<FirValueParameterSymbol>("violatedParameter")
} }
val NAMED_PARAMETER_NOT_FOUND by error<KtValueArgument>(PositioningStrategy.NAME_OF_NAMED_ARGUMENT) { val NAMED_PARAMETER_NOT_FOUND by error<KtValueArgument>(PositioningStrategy.NAME_OF_NAMED_ARGUMENT) {
@@ -498,7 +498,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error<KtSimpleNameExpression> { val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error<KtSimpleNameExpression> {
parameter<Name>("typeParameterName") parameter<Name>("typeParameterName")
parameter<FirDeclaration>("typeParametersOwner") parameter<Symbol>("typeParametersOwner")
} }
val BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED by error<KtTypeReference>() val BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED by error<KtTypeReference>()
@@ -556,7 +556,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val REFLECTION by object : DiagnosticGroup("Reflection") { val REFLECTION by object : DiagnosticGroup("Reflection") {
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) { val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
parameter<FirCallableDeclaration>("referencedDeclaration") parameter<FirCallableSymbol<*>>("referencedDeclaration")
} }
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<KtExpression>() val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<KtExpression>()
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
@@ -570,123 +570,123 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val OVERRIDES by object : DiagnosticGroup("overrides") { val OVERRIDES by object : DiagnosticGroup("overrides") {
val NOTHING_TO_OVERRIDE by error<KtModifierListOwner>(PositioningStrategy.OVERRIDE_MODIFIER) { val NOTHING_TO_OVERRIDE by error<KtModifierListOwner>(PositioningStrategy.OVERRIDE_MODIFIER) {
parameter<FirMemberDeclaration>("declaration") parameter<FirCallableSymbol<*>>("declaration")
} }
val CANNOT_OVERRIDE_INVISIBLE_MEMBER by error<KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) { val CANNOT_OVERRIDE_INVISIBLE_MEMBER by error<KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) {
parameter<FirCallableDeclaration>("overridingMember") parameter<FirCallableSymbol<*>>("overridingMember")
parameter<FirCallableDeclaration>("baseMember") parameter<FirCallableSymbol<*>>("baseMember")
} }
val DATA_CLASS_OVERRIDE_CONFLICT by error<KtClassOrObject>(PositioningStrategy.DATA_MODIFIER) { val DATA_CLASS_OVERRIDE_CONFLICT by error<KtClassOrObject>(PositioningStrategy.DATA_MODIFIER) {
parameter<FirCallableDeclaration>("overridingMember") parameter<FirCallableSymbol<*>>("overridingMember")
parameter<FirCallableDeclaration>("baseMember") parameter<FirCallableSymbol<*>>("baseMember")
} }
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) { val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility") parameter<Visibility>("overridingVisibility")
parameter<FirCallableDeclaration>("overridden") parameter<FirCallableSymbol<*>>("overridden")
parameter<Name>("containingClassName") parameter<Name>("containingClassName")
} }
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) { val CANNOT_CHANGE_ACCESS_PRIVILEGE by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility") parameter<Visibility>("overridingVisibility")
parameter<FirCallableDeclaration>("overridden") parameter<FirCallableSymbol<*>>("overridden")
parameter<Name>("containingClassName") parameter<Name>("containingClassName")
} }
val OVERRIDING_FINAL_MEMBER by error<KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) { val OVERRIDING_FINAL_MEMBER by error<KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) {
parameter<FirCallableDeclaration>("overriddenDeclaration") parameter<FirCallableSymbol<*>>("overriddenDeclaration")
parameter<Name>("containingClassName") parameter<Name>("containingClassName")
} }
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("conflictingDeclaration1") parameter<FirCallableSymbol<*>>("conflictingDeclaration1")
parameter<FirCallableDeclaration>("conflictingDeclaration2") parameter<FirCallableSymbol<*>>("conflictingDeclaration2")
} }
val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("conflictingDeclaration1") parameter<FirCallableSymbol<*>>("conflictingDeclaration1")
parameter<FirCallableDeclaration>("conflictingDeclaration2") parameter<FirCallableSymbol<*>>("conflictingDeclaration2")
} }
val VAR_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val VAR_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("conflictingDeclaration1") parameter<FirCallableSymbol<*>>("conflictingDeclaration1")
parameter<FirCallableDeclaration>("conflictingDeclaration2") parameter<FirCallableSymbol<*>>("conflictingDeclaration2")
} }
val RETURN_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val RETURN_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("delegateDeclaration") parameter<FirCallableSymbol<*>>("delegateDeclaration")
parameter<FirCallableDeclaration>("baseDeclaration") parameter<FirCallableSymbol<*>>("baseDeclaration")
} }
val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("delegateDeclaration") parameter<FirCallableSymbol<*>>("delegateDeclaration")
parameter<FirCallableDeclaration>("baseDeclaration") parameter<FirCallableSymbol<*>>("baseDeclaration")
} }
val VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("delegateDeclaration") parameter<FirCallableSymbol<*>>("delegateDeclaration")
parameter<FirCallableDeclaration>("baseDeclaration") parameter<FirCallableSymbol<*>>("baseDeclaration")
} }
val CONFLICTING_INHERITED_MEMBERS by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val CONFLICTING_INHERITED_MEMBERS by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<List<FirCallableDeclaration>>("conflictingDeclarations") parameter<List<FirCallableSymbol<*>>>("conflictingDeclarations")
} }
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass>("classOrObject") parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableDeclaration>("missingDeclaration") parameter<FirCallableSymbol<*>>("missingDeclaration")
} }
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass>("classOrObject") parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableDeclaration>("missingDeclaration") parameter<FirCallableSymbol<*>>("missingDeclaration")
} }
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass>("classOrObject") parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableDeclaration>("invisibleDeclaration") parameter<FirCallableSymbol<*>>("invisibleDeclaration")
} }
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING by warning<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING by warning<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass>("classOrObject") parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableDeclaration>("invisibleDeclaration") parameter<FirCallableSymbol<*>>("invisibleDeclaration")
} }
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass>("classOrObject") parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableDeclaration>("missingDeclaration") parameter<FirCallableSymbol<*>>("missingDeclaration")
} }
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClass>("classOrObject") parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableDeclaration>("missingDeclaration") parameter<FirCallableSymbol<*>>("missingDeclaration")
} }
val OVERRIDING_FINAL_MEMBER_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val OVERRIDING_FINAL_MEMBER_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("delegatedDeclaration") parameter<FirCallableSymbol<*>>("delegatedDeclaration")
parameter<FirCallableDeclaration>("overriddenDeclaration") parameter<FirCallableSymbol<*>>("overriddenDeclaration")
} }
val DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE by warning<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) { val DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE by warning<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirCallableDeclaration>("delegatedDeclaration") parameter<FirCallableSymbol<*>>("delegatedDeclaration")
parameter<FirCallableDeclaration>("overriddenDeclaration") parameter<FirCallableSymbol<*>>("overriddenDeclaration")
} }
val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) { val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
parameter<FirMemberDeclaration>("superFunction") parameter<FirCallableSymbol<*>>("superFunction")
} }
val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) { val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("property") parameter<FirCallableSymbol<*>>("property")
parameter<FirMemberDeclaration>("superProperty") parameter<FirCallableSymbol<*>>("superProperty")
} }
val VAR_TYPE_MISMATCH_ON_OVERRIDE by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) { val VAR_TYPE_MISMATCH_ON_OVERRIDE by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("variable") parameter<FirCallableSymbol<*>>("variable")
parameter<FirMemberDeclaration>("superVariable") parameter<FirCallableSymbol<*>>("superVariable")
} }
val VAR_OVERRIDDEN_BY_VAL by error<KtNamedDeclaration>(PositioningStrategy.VAL_OR_VAR_NODE) { val VAR_OVERRIDDEN_BY_VAL by error<KtNamedDeclaration>(PositioningStrategy.VAL_OR_VAR_NODE) {
parameter<FirMemberDeclaration>("overridingDeclaration") parameter<FirCallableSymbol<*>>("overridingDeclaration")
parameter<FirMemberDeclaration>("overriddenDeclaration") parameter<FirCallableSymbol<*>>("overriddenDeclaration")
} }
val NON_FINAL_MEMBER_IN_FINAL_CLASS by warning<KtNamedDeclaration>(PositioningStrategy.OPEN_MODIFIER) val NON_FINAL_MEMBER_IN_FINAL_CLASS by warning<KtNamedDeclaration>(PositioningStrategy.OPEN_MODIFIER)
val NON_FINAL_MEMBER_IN_OBJECT by warning<KtNamedDeclaration>(PositioningStrategy.OPEN_MODIFIER) val NON_FINAL_MEMBER_IN_OBJECT by warning<KtNamedDeclaration>(PositioningStrategy.OPEN_MODIFIER)
val VIRTUAL_MEMBER_HIDDEN by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) { val VIRTUAL_MEMBER_HIDDEN by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirMemberDeclaration>("declared") parameter<FirCallableSymbol<*>>("declared")
parameter<FirRegularClass>("overriddenContainer") parameter<FirRegularClassSymbol>("overriddenContainer")
} }
} }
@@ -712,21 +712,21 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val FUNCTIONS by object : DiagnosticGroup("Functions") { val FUNCTIONS by object : DiagnosticGroup("Functions") {
val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error<KtFunction>(PositioningStrategy.MODALITY_MODIFIER) { val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error<KtFunction>(PositioningStrategy.MODALITY_MODIFIER) {
parameter<FirMemberDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
parameter<FirClass>("containingClass") parameter<FirClassSymbol<*>>("containingClass")
} }
val ABSTRACT_FUNCTION_WITH_BODY by error<KtFunction>(PositioningStrategy.MODALITY_MODIFIER) { val ABSTRACT_FUNCTION_WITH_BODY by error<KtFunction>(PositioningStrategy.MODALITY_MODIFIER) {
parameter<FirMemberDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
} }
val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error<KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) { val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error<KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) {
parameter<FirMemberDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
} }
val PRIVATE_FUNCTION_WITH_NO_BODY by error<KtFunction>(PositioningStrategy.VISIBILITY_MODIFIER) { val PRIVATE_FUNCTION_WITH_NO_BODY by error<KtFunction>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<FirMemberDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
} }
val NON_MEMBER_FUNCTION_NO_BODY by error<KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) { val NON_MEMBER_FUNCTION_NO_BODY by error<KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) {
parameter<FirMemberDeclaration>("function") parameter<FirCallableSymbol<*>>("function")
} }
val FUNCTION_DECLARATION_WITH_NO_NAME by error<KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) val FUNCTION_DECLARATION_WITH_NO_NAME by error<KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE)
@@ -756,8 +756,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") { val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error<KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) { val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error<KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) {
parameter<FirMemberDeclaration>("property") parameter<FirCallableSymbol<*>>("property")
parameter<FirClass>("containingClass") parameter<FirClassSymbol<*>>("containingClass")
} }
val PRIVATE_PROPERTY_IN_INTERFACE by error<KtProperty>(PositioningStrategy.VISIBILITY_MODIFIER) val PRIVATE_PROPERTY_IN_INTERFACE by error<KtProperty>(PositioningStrategy.VISIBILITY_MODIFIER)
@@ -844,10 +844,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirPropertySymbol>("variable") parameter<FirPropertySymbol>("variable")
} }
val UNINITIALIZED_PARAMETER by error<KtSimpleNameExpression> { val UNINITIALIZED_PARAMETER by error<KtSimpleNameExpression> {
parameter<FirVariableSymbol<FirValueParameter>>("parameter") parameter<FirValueParameterSymbol>("parameter")
} }
val UNINITIALIZED_ENUM_ENTRY by error<KtSimpleNameExpression> { val UNINITIALIZED_ENUM_ENTRY by error<KtSimpleNameExpression> {
parameter<FirVariableSymbol<FirEnumEntry>>("enumEntry") parameter<FirEnumEntrySymbol>("enumEntry")
} }
val UNINITIALIZED_ENUM_COMPANION by error<KtSimpleNameExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) { val UNINITIALIZED_ENUM_COMPANION by error<KtSimpleNameExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
parameter<FirRegularClassSymbol>("enumClass") parameter<FirRegularClassSymbol>("enumClass")
@@ -856,10 +856,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirVariableSymbol<*>>("variable") parameter<FirVariableSymbol<*>>("variable")
} }
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning<KtExpression> { val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning<KtExpression> {
parameter<FirPropertySymbol>("property") parameter<FirBackingFieldSymbol>("property")
} }
val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error<KtExpression> { val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error<KtExpression> {
parameter<FirPropertySymbol>("property") parameter<FirBackingFieldSymbol>("property")
} }
val CAPTURED_VAL_INITIALIZATION by error<KtExpression> { val CAPTURED_VAL_INITIALIZATION by error<KtExpression> {
parameter<FirPropertySymbol>("property") parameter<FirPropertySymbol>("property")
@@ -1099,7 +1099,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = { private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = {
parameter<EffectiveVisibility>("elementVisibility") parameter<EffectiveVisibility>("elementVisibility")
parameter<FirMemberDeclaration>("restrictingDeclaration") parameter<Symbol>("restrictingDeclaration")
parameter<EffectiveVisibility>("restrictingVisibility") parameter<EffectiveVisibility>("restrictingVisibility")
} }
@@ -8,11 +8,12 @@ package org.jetbrains.kotlin.fir.analysis.jvm
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.containingClass import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isAbstract import org.jetbrains.kotlin.fir.declarations.utils.isAbstract
import org.jetbrains.kotlin.fir.declarations.utils.isFinal import org.jetbrains.kotlin.fir.declarations.utils.isFinal
@@ -22,6 +23,8 @@ import org.jetbrains.kotlin.fir.originalOrSelf
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
@@ -55,13 +58,15 @@ object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatib
visitedSymbols: MutableSet<FirCallableSymbol<*>>, visitedSymbols: MutableSet<FirCallableSymbol<*>>,
context: CheckerContext context: CheckerContext
): Boolean { ): Boolean {
val fir = symbol.fir if (symbol.isFinal) return false
if (fir.isFinal) return false
if (symbol in visitedSymbols) return true if (symbol in visitedSymbols) return true
visitedSymbols += symbol visitedSymbols += symbol
val originalMember = fir.originalOrSelf() val originalMemberSymbol = symbol.originalOrSelf()
originalMemberSymbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
@OptIn(SymbolInternals::class)
val originalMember = originalMemberSymbol.fir
if (originalMember.annotations.any { it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.classId == platformDependentAnnotation }) { if (originalMember.annotations.any { it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.classId == platformDependentAnnotation }) {
return true return true
} }
@@ -81,7 +86,7 @@ object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatib
} }
val scope = val scope =
symbol.dispatchReceiverTypeOrNull()?.toRegularClass(context.session)?.unsubstitutedScope(context) ?: return false symbol.dispatchReceiverTypeOrNull()?.toRegularClassSymbol(context.session)?.unsubstitutedScope(context) ?: return false
val overriddenSymbols = when (originalMember) { val overriddenSymbols = when (originalMember) {
is FirSimpleFunction -> scope.getDirectOverriddenFunctions(originalMember.symbol) is FirSimpleFunction -> scope.getDirectOverriddenFunctions(originalMember.symbol)
is FirProperty -> scope.getDirectOverriddenProperties(originalMember.symbol) is FirProperty -> scope.getDirectOverriddenProperties(originalMember.symbol)
@@ -14,21 +14,19 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtKeywordToken
@@ -136,7 +134,7 @@ object FirErrors {
val RECURSION_IN_SUPERTYPES by error0<PsiElement>() val RECURSION_IN_SUPERTYPES by error0<PsiElement>()
val NOT_A_SUPERTYPE by error0<PsiElement>() val NOT_A_SUPERTYPE by error0<PsiElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<PsiElement>() val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<PsiElement>()
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error1<KtTypeReference, FirClass>() val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error1<KtTypeReference, FirBasedSymbol<*>>()
val SUPERTYPE_INITIALIZED_IN_INTERFACE by error0<KtTypeReference>() val SUPERTYPE_INITIALIZED_IN_INTERFACE by error0<KtTypeReference>()
val INTERFACE_WITH_SUPERCLASS by error0<KtTypeReference>() val INTERFACE_WITH_SUPERCLASS by error0<KtTypeReference>()
val FINAL_SUPERTYPE by error0<KtTypeReference>() val FINAL_SUPERTYPE by error0<KtTypeReference>()
@@ -223,15 +221,15 @@ object FirErrors {
val EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION by error0<KtAnnotationEntry>() val EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION by error0<KtAnnotationEntry>()
// Exposed visibility // Exposed visibility
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_FUNCTION_RETURN_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_FUNCTION_RETURN_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by error3<KtTypeReference, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>() val EXPOSED_RECEIVER_TYPE by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_PROPERTY_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_PROPERTY_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR by warning3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR by warning3<KtNamedDeclaration, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PARAMETER_TYPE by error3<KtParameter, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>() val EXPOSED_PARAMETER_TYPE by error3<KtParameter, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_SUPER_INTERFACE by error3<KtTypeReference, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>() val EXPOSED_SUPER_INTERFACE by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_SUPER_CLASS by error3<KtTypeReference, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>() val EXPOSED_SUPER_CLASS by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
val EXPOSED_TYPE_PARAMETER_BOUND by error3<KtTypeReference, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>() val EXPOSED_TYPE_PARAMETER_BOUND by error3<KtTypeReference, EffectiveVisibility, FirBasedSymbol<*>, EffectiveVisibility>()
// Modifiers // Modifiers
val INAPPLICABLE_INFIX_MODIFIER by error0<PsiElement>() val INAPPLICABLE_INFIX_MODIFIER by error0<PsiElement>()
@@ -274,8 +272,8 @@ object FirErrors {
val NAMED_ARGUMENTS_NOT_ALLOWED by error1<KtValueArgument, ForbiddenNamedArgumentsTarget>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT) val NAMED_ARGUMENTS_NOT_ALLOWED by error1<KtValueArgument, ForbiddenNamedArgumentsTarget>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
val NON_VARARG_SPREAD by error0<LeafPsiElement>() val NON_VARARG_SPREAD by error0<LeafPsiElement>()
val ARGUMENT_PASSED_TWICE by error0<KtValueArgument>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT) val ARGUMENT_PASSED_TWICE by error0<KtValueArgument>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
val TOO_MANY_ARGUMENTS by error1<PsiElement, FirCallableDeclaration>() val TOO_MANY_ARGUMENTS by error1<PsiElement, FirCallableSymbol<*>>()
val NO_VALUE_FOR_PARAMETER by error1<KtElement, FirValueParameter>(SourceElementPositioningStrategies.VALUE_ARGUMENTS) val NO_VALUE_FOR_PARAMETER by error1<KtElement, FirValueParameterSymbol>(SourceElementPositioningStrategies.VALUE_ARGUMENTS)
val NAMED_PARAMETER_NOT_FOUND by error1<KtValueArgument, String>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT) val NAMED_PARAMETER_NOT_FOUND by error1<KtValueArgument, String>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
val ASSIGNMENT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>() val ASSIGNMENT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
val RESULT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>() val RESULT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
@@ -319,7 +317,7 @@ object FirErrors {
val ONLY_ONE_CLASS_BOUND_ALLOWED by error0<KtTypeReference>() val ONLY_ONE_CLASS_BOUND_ALLOWED by error0<KtTypeReference>()
val REPEATED_BOUND by error0<KtTypeReference>() val REPEATED_BOUND by error0<KtTypeReference>()
val CONFLICTING_UPPER_BOUNDS by error1<KtNamedDeclaration, FirTypeParameterSymbol>() val CONFLICTING_UPPER_BOUNDS by error1<KtNamedDeclaration, FirTypeParameterSymbol>()
val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error2<KtSimpleNameExpression, Name, FirDeclaration>() val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error2<KtSimpleNameExpression, Name, FirBasedSymbol<*>>()
val BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED by error0<KtTypeReference>() val BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED by error0<KtTypeReference>()
val REIFIED_TYPE_PARAMETER_NO_INLINE by error0<KtTypeParameter>(SourceElementPositioningStrategies.REIFIED_MODIFIER) val REIFIED_TYPE_PARAMETER_NO_INLINE by error0<KtTypeParameter>(SourceElementPositioningStrategies.REIFIED_MODIFIER)
val TYPE_PARAMETERS_NOT_ALLOWED by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST) val TYPE_PARAMETERS_NOT_ALLOWED by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
@@ -336,7 +334,7 @@ object FirErrors {
val SMARTCAST_IMPOSSIBLE by error3<KtExpression, ConeKotlinType, FirExpression, String>() val SMARTCAST_IMPOSSIBLE by error3<KtExpression, ConeKotlinType, FirExpression, String>()
// Reflection // Reflection
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableDeclaration>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<KtExpression>() val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<KtExpression>()
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<KtExpression>() val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<KtExpression>()
@@ -344,34 +342,34 @@ object FirErrors {
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<PsiElement, ConeKotlinType>() val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<PsiElement, ConeKotlinType>()
// overrides // overrides
val NOTHING_TO_OVERRIDE by error1<KtModifierListOwner, FirMemberDeclaration>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) val NOTHING_TO_OVERRIDE by error1<KtModifierListOwner, FirCallableSymbol<*>>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val CANNOT_OVERRIDE_INVISIBLE_MEMBER by error2<KtNamedDeclaration, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) val CANNOT_OVERRIDE_INVISIBLE_MEMBER by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val DATA_CLASS_OVERRIDE_CONFLICT by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DATA_MODIFIER) val DATA_CLASS_OVERRIDE_CONFLICT by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DATA_MODIFIER)
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val OVERRIDING_FINAL_MEMBER by error2<KtNamedDeclaration, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) val OVERRIDING_FINAL_MEMBER by error2<KtNamedDeclaration, FirCallableSymbol<*>, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val VAR_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val VAR_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val RETURN_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val RETURN_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val CONFLICTING_INHERITED_MEMBERS by error1<KtClassOrObject, List<FirCallableDeclaration>>(SourceElementPositioningStrategies.DECLARATION_NAME) val CONFLICTING_INHERITED_MEMBERS by error1<KtClassOrObject, List<FirCallableSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING by warning2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING by warning2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val OVERRIDING_FINAL_MEMBER_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val OVERRIDING_FINAL_MEMBER_BY_DELEGATION by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE by warning2<KtClassOrObject, FirCallableDeclaration, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME) val DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE by warning2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE) val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE) val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE) val VAR_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_OVERRIDDEN_BY_VAL by error2<KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) val VAR_OVERRIDDEN_BY_VAL by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
val NON_FINAL_MEMBER_IN_FINAL_CLASS by warning0<KtNamedDeclaration>(SourceElementPositioningStrategies.OPEN_MODIFIER) val NON_FINAL_MEMBER_IN_FINAL_CLASS by warning0<KtNamedDeclaration>(SourceElementPositioningStrategies.OPEN_MODIFIER)
val NON_FINAL_MEMBER_IN_OBJECT by warning0<KtNamedDeclaration>(SourceElementPositioningStrategies.OPEN_MODIFIER) val NON_FINAL_MEMBER_IN_OBJECT by warning0<KtNamedDeclaration>(SourceElementPositioningStrategies.OPEN_MODIFIER)
val VIRTUAL_MEMBER_HIDDEN by error2<KtNamedDeclaration, FirMemberDeclaration, FirRegularClass>(SourceElementPositioningStrategies.DECLARATION_NAME) val VIRTUAL_MEMBER_HIDDEN by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirRegularClassSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
// Redeclarations // Redeclarations
val MANY_COMPANION_OBJECTS by error0<KtObjectDeclaration>(SourceElementPositioningStrategies.COMPANION_OBJECT) val MANY_COMPANION_OBJECTS by error0<KtObjectDeclaration>(SourceElementPositioningStrategies.COMPANION_OBJECT)
@@ -384,11 +382,11 @@ object FirErrors {
val LOCAL_INTERFACE_NOT_ALLOWED by error1<KtNamedDeclaration, Name>(SourceElementPositioningStrategies.DECLARATION_NAME) val LOCAL_INTERFACE_NOT_ALLOWED by error1<KtNamedDeclaration, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
// Functions // Functions
val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error2<KtFunction, FirMemberDeclaration, FirClass>(SourceElementPositioningStrategies.MODALITY_MODIFIER) val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error2<KtFunction, FirCallableSymbol<*>, FirClassSymbol<*>>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val ABSTRACT_FUNCTION_WITH_BODY by error1<KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER) val ABSTRACT_FUNCTION_WITH_BODY by error1<KtFunction, FirCallableSymbol<*>>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error1<KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error1<KtFunction, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val PRIVATE_FUNCTION_WITH_NO_BODY by error1<KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val PRIVATE_FUNCTION_WITH_NO_BODY by error1<KtFunction, FirCallableSymbol<*>>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val NON_MEMBER_FUNCTION_NO_BODY by error1<KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val NON_MEMBER_FUNCTION_NO_BODY by error1<KtFunction, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val FUNCTION_DECLARATION_WITH_NO_NAME by error0<KtFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val FUNCTION_DECLARATION_WITH_NO_NAME by error0<KtFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val ANONYMOUS_FUNCTION_WITH_NAME by error0<KtFunction>() val ANONYMOUS_FUNCTION_WITH_NAME by error0<KtFunction>()
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error0<KtParameter>(SourceElementPositioningStrategies.PARAMETER_DEFAULT_VALUE) val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error0<KtParameter>(SourceElementPositioningStrategies.PARAMETER_DEFAULT_VALUE)
@@ -407,7 +405,7 @@ object FirErrors {
val FUN_INTERFACE_WITH_SUSPEND_FUNCTION by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE) val FUN_INTERFACE_WITH_SUSPEND_FUNCTION by error0<KtDeclaration>(SourceElementPositioningStrategies.FUN_INTERFACE)
// Properties & accessors // Properties & accessors
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<KtModifierListOwner, FirMemberDeclaration, FirClass>(SourceElementPositioningStrategies.MODALITY_MODIFIER) val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<KtModifierListOwner, FirCallableSymbol<*>, FirClassSymbol<*>>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val PRIVATE_PROPERTY_IN_INTERFACE by error0<KtProperty>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val PRIVATE_PROPERTY_IN_INTERFACE by error0<KtProperty>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val ABSTRACT_PROPERTY_WITH_INITIALIZER by error0<KtExpression>() val ABSTRACT_PROPERTY_WITH_INITIALIZER by error0<KtExpression>()
val PROPERTY_INITIALIZER_IN_INTERFACE by error0<KtExpression>() val PROPERTY_INITIALIZER_IN_INTERFACE by error0<KtExpression>()
@@ -456,12 +454,12 @@ object FirErrors {
// Control flow diagnostics // Control flow diagnostics
val UNINITIALIZED_VARIABLE by error1<KtSimpleNameExpression, FirPropertySymbol>() val UNINITIALIZED_VARIABLE by error1<KtSimpleNameExpression, FirPropertySymbol>()
val UNINITIALIZED_PARAMETER by error1<KtSimpleNameExpression, FirVariableSymbol<FirValueParameter>>() val UNINITIALIZED_PARAMETER by error1<KtSimpleNameExpression, FirValueParameterSymbol>()
val UNINITIALIZED_ENUM_ENTRY by error1<KtSimpleNameExpression, FirVariableSymbol<FirEnumEntry>>() val UNINITIALIZED_ENUM_ENTRY by error1<KtSimpleNameExpression, FirEnumEntrySymbol>()
val UNINITIALIZED_ENUM_COMPANION by error1<KtSimpleNameExpression, FirRegularClassSymbol>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val UNINITIALIZED_ENUM_COMPANION by error1<KtSimpleNameExpression, FirRegularClassSymbol>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val VAL_REASSIGNMENT by error1<KtExpression, FirVariableSymbol<*>>() val VAL_REASSIGNMENT by error1<KtExpression, FirVariableSymbol<*>>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning1<KtExpression, FirPropertySymbol>() val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning1<KtExpression, FirBackingFieldSymbol>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error1<KtExpression, FirPropertySymbol>() val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error1<KtExpression, FirBackingFieldSymbol>()
val CAPTURED_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>() val CAPTURED_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
val CAPTURED_MEMBER_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>() val CAPTURED_MEMBER_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
val SETTER_PROJECTED_OUT by error1<KtBinaryExpression, FirPropertySymbol>(SourceElementPositioningStrategies.ASSIGNMENT_LHS) val SETTER_PROJECTED_OUT by error1<KtBinaryExpression, FirPropertySymbol>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
@@ -192,7 +192,7 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
override fun visitFunctionCallNode(node: FunctionCallNode, data: IllegalScopeContext) { override fun visitFunctionCallNode(node: FunctionCallNode, data: IllegalScopeContext) {
val functionSymbol = node.fir.toResolvedCallableSymbol() as? FirFunctionSymbol<*>? val functionSymbol = node.fir.toResolvedCallableSymbol() as? FirFunctionSymbol<*>?
val contractDescription = functionSymbol?.fir?.contractDescription val contractDescription = functionSymbol?.resolvedContractDescription
val callSource = node.fir.explicitReceiver?.source ?: node.fir.source val callSource = node.fir.explicitReceiver?.source ?: node.fir.source
data.checkExpressionForLeakedSymbols(node.fir.explicitReceiver, callSource) { data.checkExpressionForLeakedSymbols(node.fir.explicitReceiver, callSource) {
@@ -255,7 +255,7 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
var dataForNode = visitNode(node, data) var dataForNode = visitNode(node, data)
val functionSymbol = node.fir.toResolvedCallableSymbol() as? FirFunctionSymbol<*>? val functionSymbol = node.fir.toResolvedCallableSymbol() as? FirFunctionSymbol<*>?
val contractDescription = functionSymbol?.fir?.contractDescription val contractDescription = functionSymbol?.resolvedContractDescription
dataForNode = dataForNode.checkReference(node.fir.explicitReceiver.toQualifiedReference()) { dataForNode = dataForNode.checkReference(node.fir.explicitReceiver.toQualifiedReference()) {
when { when {
@@ -303,9 +303,6 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
return this?.coneTypeSafe<ConeKotlinType>()?.isBuiltinFunctionalType(session) == true return this?.coneTypeSafe<ConeKotlinType>()?.isBuiltinFunctionalType(session) == true
} }
private val FirFunction.contractDescription: FirContractDescription?
get() = (this as? FirContractDescriptionOwner)?.contractDescription
private fun FirContractDescription?.getParameterCallsEffectDeclaration(index: Int): ConeCallsEffectDeclaration? { private fun FirContractDescription?.getParameterCallsEffectDeclaration(index: Int): ConeCallsEffectDeclaration? {
val effects = this?.coneEffects val effects = this?.coneEffects
val callsEffect = effects?.find { it is ConeCallsEffectDeclaration && it.valueParameterReference.parameterIndex == index } val callsEffect = effects?.find { it is ConeCallsEffectDeclaration && it.valueParameterReference.parameterIndex == index }
@@ -313,13 +310,13 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
} }
private fun FirFunctionCall.getArgumentCallsEffect(arg: FirExpression): EventOccurrencesRange? { private fun FirFunctionCall.getArgumentCallsEffect(arg: FirExpression): EventOccurrencesRange? {
val function = (this.toResolvedCallableSymbol() as? FirFunctionSymbol<*>?)?.fir val functionSymbol = (this.toResolvedCallableSymbol() as? FirFunctionSymbol<*>?)
val contractDescription = function?.contractDescription val contractDescription = functionSymbol?.resolvedContractDescription
val resolvedArguments = argumentList as? FirResolvedArgumentList val resolvedArguments = argumentList as? FirResolvedArgumentList
return if (function != null && resolvedArguments != null) { return if (functionSymbol != null && resolvedArguments != null) {
val parameter = resolvedArguments.mapping[arg] val parameter = resolvedArguments.mapping[arg]
contractDescription.getParameterCallsEffect(function.valueParameters.indexOf(parameter)) contractDescription.getParameterCallsEffect(functionSymbol.valueParameterSymbols.indexOf(parameter?.symbol))
} else null } else null
} }
@@ -18,9 +18,11 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.* import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
@OptIn(SymbolInternals::class)
object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChecker() { object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChecker() {
override fun analyze( override fun analyze(
graph: ControlFlowGraph, graph: ControlFlowGraph,
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.JumpNode import org.jetbrains.kotlin.fir.resolve.dfa.cfg.JumpNode
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -157,8 +158,11 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
context: CheckerContext context: CheckerContext
): MutableTypeStatements? { ): MutableTypeStatements? {
fun buildTypeStatements(arg: ConeValueParameterReference, exactType: Boolean, type: ConeKotlinType): MutableTypeStatements? { fun buildTypeStatements(arg: ConeValueParameterReference, exactType: Boolean, type: ConeKotlinType): MutableTypeStatements? {
val fir = function.getParameterSymbol(arg.parameterIndex, context).fir val parameterSymbol = function.getParameterSymbol(arg.parameterIndex, context)
val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir)
@OptIn(SymbolInternals::class)
val parameter = parameterSymbol.fir
val realVar = variableStorage.getOrCreateRealVariable(flow, parameterSymbol, parameter)
?.takeIf { ?.takeIf {
it.stability == PropertyStability.STABLE_VALUE || it.stability == PropertyStability.STABLE_VALUE ||
// TODO: consider removing the part below // TODO: consider removing the part below
@@ -11,11 +11,10 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.isPrimitiveType import org.jetbrains.kotlin.fir.isPrimitiveType
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.calls.fullyExpandedClass
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
@@ -104,7 +103,7 @@ internal object ConeTypeCompatibilityChecker {
upperBounds: Set<ConeClassLikeType>, upperBounds: Set<ConeClassLikeType>,
lowerBounds: Set<ConeClassLikeType>, lowerBounds: Set<ConeClassLikeType>,
compatibilityUpperBound: Compatibility, compatibilityUpperBound: Compatibility,
checkedTypeParameters: MutableSet<FirTypeParameterRef> = mutableSetOf(), checkedTypeParameters: MutableSet<FirTypeParameterSymbol> = mutableSetOf(),
): Compatibility { ): Compatibility {
val upperBoundClasses: Set<FirClassWithSuperClasses> = upperBounds.mapNotNull { it.toFirClassWithSuperClasses(this) }.toSet() val upperBoundClasses: Set<FirClassWithSuperClasses> = upperBounds.mapNotNull { it.toFirClassWithSuperClasses(this) }.toSet()
@@ -134,7 +133,7 @@ internal object ConeTypeCompatibilityChecker {
// Base types are compatible. Now we check type parameters. // Base types are compatible. Now we check type parameters.
val typeArgumentMapping = mutableMapOf<FirTypeParameterRef, BoundTypeArguments>().apply { val typeArgumentMapping = mutableMapOf<FirTypeParameterSymbol, BoundTypeArguments>().apply {
for (type in upperBounds) { for (type in upperBounds) {
collectTypeArgumentMapping(type, this@areCompatible, compatibilityUpperBound) collectTypeArgumentMapping(type, this@areCompatible, compatibilityUpperBound)
} }
@@ -277,7 +276,7 @@ internal object ConeTypeCompatibilityChecker {
* - type parameter of `Collection` -> upper:[`String`, `Int`], lower:[] * - type parameter of `Collection` -> upper:[`String`, `Int`], lower:[]
* - type parameter of `Iterable` -> upper:[`String`, `Int`], lower:[] * - type parameter of `Iterable` -> upper:[`String`, `Int`], lower:[]
*/ */
private fun MutableMap<FirTypeParameterRef, BoundTypeArguments>.collectTypeArgumentMapping( private fun MutableMap<FirTypeParameterSymbol, BoundTypeArguments>.collectTypeArgumentMapping(
coneType: ConeClassLikeType, coneType: ConeClassLikeType,
ctx: ConeInferenceContext, ctx: ConeInferenceContext,
compatibilityUpperBound: Compatibility compatibilityUpperBound: Compatibility
@@ -300,12 +299,12 @@ internal object ConeTypeCompatibilityChecker {
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
private fun ConeClassLikeType.toTypeArgumentMapping( private fun ConeClassLikeType.toTypeArgumentMapping(
ctx: ConeInferenceContext, ctx: ConeInferenceContext,
envMapping: Map<FirTypeParameterRef, BoundTypeArgument> = emptyMap(), envMapping: Map<FirTypeParameterSymbol, BoundTypeArgument> = emptyMap(),
): TypeArgumentMapping? { ): TypeArgumentMapping? {
val typeParameterOwner = getClassLikeElement(ctx) ?: return null val typeParameterOwner = getClassLikeElement(ctx) ?: return null
val mapping = buildMap<FirTypeParameterRef, BoundTypeArgument> { val mapping = buildMap<FirTypeParameterSymbol, BoundTypeArgument> {
typeArguments.forEachIndexed { index, coneTypeProjection -> typeArguments.forEachIndexed { index, coneTypeProjection ->
val typeParameter: FirTypeParameterRef = typeParameterOwner.getTypeParameter(index) ?: return@forEachIndexed val typeParameter = typeParameterOwner.getTypeParameter(index) ?: return@forEachIndexed
var boundTypeArgument: BoundTypeArgument = when (coneTypeProjection) { var boundTypeArgument: BoundTypeArgument = when (coneTypeProjection) {
// Ignore star since it doesn't provide any constraints. // Ignore star since it doesn't provide any constraints.
ConeStarProjection -> return@forEachIndexed ConeStarProjection -> return@forEachIndexed
@@ -315,7 +314,7 @@ internal object ConeTypeCompatibilityChecker {
is ConeKotlinTypeProjectionOut -> BoundTypeArgument(coneTypeProjection.type, Variance.OUT_VARIANCE) is ConeKotlinTypeProjectionOut -> BoundTypeArgument(coneTypeProjection.type, Variance.OUT_VARIANCE)
is ConeKotlinTypeConflictingProjection -> BoundTypeArgument(coneTypeProjection.type, Variance.INVARIANT) is ConeKotlinTypeConflictingProjection -> BoundTypeArgument(coneTypeProjection.type, Variance.INVARIANT)
is ConeKotlinType -> is ConeKotlinType ->
when ((typeParameter as? FirTypeParameter)?.variance) { when (typeParameter.variance) {
Variance.IN_VARIANCE -> BoundTypeArgument(coneTypeProjection.type, Variance.IN_VARIANCE) Variance.IN_VARIANCE -> BoundTypeArgument(coneTypeProjection.type, Variance.IN_VARIANCE)
Variance.OUT_VARIANCE -> BoundTypeArgument(coneTypeProjection.type, Variance.OUT_VARIANCE) Variance.OUT_VARIANCE -> BoundTypeArgument(coneTypeProjection.type, Variance.OUT_VARIANCE)
else -> BoundTypeArgument(coneTypeProjection.type, Variance.INVARIANT) else -> BoundTypeArgument(coneTypeProjection.type, Variance.INVARIANT)
@@ -323,7 +322,7 @@ internal object ConeTypeCompatibilityChecker {
} }
val coneKotlinType = boundTypeArgument.type val coneKotlinType = boundTypeArgument.type
if (coneKotlinType is ConeTypeParameterType) { if (coneKotlinType is ConeTypeParameterType) {
val envTypeParameter = coneKotlinType.lookupTag.typeParameterSymbol.fir val envTypeParameter = coneKotlinType.lookupTag.typeParameterSymbol
val envTypeArgument = envMapping[envTypeParameter] val envTypeArgument = envMapping[envTypeParameter]
if (envTypeArgument != null) { if (envTypeArgument != null) {
boundTypeArgument = envTypeArgument boundTypeArgument = envTypeArgument
@@ -335,10 +334,10 @@ internal object ConeTypeCompatibilityChecker {
return TypeArgumentMapping(typeParameterOwner, mapping) return TypeArgumentMapping(typeParameterOwner, mapping)
} }
private fun MutableMap<FirTypeParameterRef, BoundTypeArguments>.collect( private fun MutableMap<FirTypeParameterSymbol, BoundTypeArguments>.collect(
ctx: ConeInferenceContext, ctx: ConeInferenceContext,
typeParameterOwner: FirClassLikeDeclaration, typeParameterOwner: FirClassLikeSymbol<*>,
parameter: FirTypeParameterRef, parameter: FirTypeParameterSymbol,
boundTypeArgument: BoundTypeArgument, boundTypeArgument: BoundTypeArgument,
compatibilityUpperBound: Compatibility, compatibilityUpperBound: Compatibility,
) { ) {
@@ -346,8 +345,8 @@ internal object ConeTypeCompatibilityChecker {
// the semantic of type parameter in Enum and KClass are fixed: values of types with incompatible type parameters are always // the semantic of type parameter in Enum and KClass are fixed: values of types with incompatible type parameters are always
// incompatible. // incompatible.
val compatibilityUpperBoundForTypeArg = val compatibilityUpperBoundForTypeArg =
if ((ctx.prohibitComparisonOfIncompatibleEnums && typeParameterOwner.symbol.classId == StandardClassIds.Enum) || if ((ctx.prohibitComparisonOfIncompatibleEnums && typeParameterOwner.classId == StandardClassIds.Enum) ||
(ctx.prohibitComparisonOfIncompatibleClasses && typeParameterOwner.symbol.classId == StandardClassIds.KClass) (ctx.prohibitComparisonOfIncompatibleClasses && typeParameterOwner.classId == StandardClassIds.KClass)
) { ) {
compatibilityUpperBound compatibilityUpperBound
} else { } else {
@@ -365,29 +364,29 @@ internal object ConeTypeCompatibilityChecker {
} }
} }
private fun FirClassLikeDeclaration.getSuperTypes(): List<ConeClassLikeType> { private fun FirClassLikeSymbol<*>.getSuperTypes(): List<ConeClassLikeType> {
return when (this) { return when (this) {
is FirTypeAlias -> listOfNotNull(expandedTypeRef.coneTypeSafe()) is FirTypeAliasSymbol -> listOfNotNull(resolvedExpandedTypeRef.coneTypeSafe())
is FirClass -> superTypeRefs.mapNotNull { it.coneTypeSafe() } is FirClassSymbol<*> -> resolvedSuperTypeRefs.mapNotNull { it.coneTypeSafe() }
else -> emptyList() else -> emptyList()
} }
} }
private fun ConeClassLikeType.getClassLikeElement(ctx: ConeInferenceContext): FirClassLikeDeclaration? = private fun ConeClassLikeType.getClassLikeElement(ctx: ConeInferenceContext): FirClassLikeSymbol<*>? =
ctx.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir ctx.symbolProvider.getSymbolByLookupTag(lookupTag)
private fun FirClassLikeDeclaration.getTypeParameter(index: Int): FirTypeParameterRef? { private fun FirClassLikeSymbol<*>.getTypeParameter(index: Int): FirTypeParameterSymbol? {
return when (this) { return when (this) {
is FirTypeAlias -> typeParameters[index] is FirTypeAliasSymbol -> typeParameterSymbols[index]
is FirClass -> typeParameters[index] is FirClassSymbol<*> -> typeParameterSymbols[index]
else -> return null else -> return null
} }
} }
/** A class declaration and the arguments bound to the declared type parameters. */ /** A class declaration and the arguments bound to the declared type parameters. */
private data class TypeArgumentMapping( private data class TypeArgumentMapping(
val typeParameterOwner: FirClassLikeDeclaration, val typeParameterOwner: FirClassLikeSymbol<*>,
val mapping: Map<FirTypeParameterRef, BoundTypeArgument> val mapping: Map<FirTypeParameterSymbol, BoundTypeArgument>
) )
/** A single bound type argument to a type parameter declared in a class. */ /** A single bound type argument to a type parameter declared in a class. */
@@ -406,13 +405,13 @@ internal object ConeTypeCompatibilityChecker {
private fun ConeClassLikeLookupTag.toFirClassWithSuperClasses( private fun ConeClassLikeLookupTag.toFirClassWithSuperClasses(
ctx: ConeInferenceContext ctx: ConeInferenceContext
): FirClassWithSuperClasses? = when (val klass = ctx.symbolProvider.getSymbolByLookupTag(this)?.fir) { ): FirClassWithSuperClasses? = when (val klass = ctx.symbolProvider.getSymbolByLookupTag(this)) {
is FirTypeAlias -> klass.fullyExpandedClass(ctx.session)?.let { FirClassWithSuperClasses(it, ctx) } is FirTypeAliasSymbol -> klass.fullyExpandedClass(ctx.session)?.let { FirClassWithSuperClasses(it, ctx) }
is FirClass -> FirClassWithSuperClasses(klass, ctx) is FirClassSymbol<*> -> FirClassWithSuperClasses(klass, ctx)
else -> null else -> null
} }
private data class FirClassWithSuperClasses(val firClass: FirClass, val ctx: ConeInferenceContext) { private data class FirClassWithSuperClasses(val firClass: FirClassSymbol<*>, val ctx: ConeInferenceContext) {
val isInterface: Boolean get() = firClass.isInterface val isInterface: Boolean get() = firClass.isInterface
val superClasses: Set<FirClassWithSuperClasses> by lazy { val superClasses: Set<FirClassWithSuperClasses> by lazy {
@@ -451,15 +450,15 @@ internal object ConeTypeCompatibilityChecker {
firClass.isPrimitiveType() || firClass.isPrimitiveType() ||
(ctx.prohibitComparisonOfIncompatibleClasses && firClass.classId == StandardClassIds.KClass) || (ctx.prohibitComparisonOfIncompatibleClasses && firClass.classId == StandardClassIds.KClass) ||
firClass.classId == StandardClassIds.String || firClass.classId == StandardClassIds.Unit || firClass.classId == StandardClassIds.String || firClass.classId == StandardClassIds.Unit ||
(firClass is FirRegularClass && (firClass.isData || firClass.isInline)) (firClass is FirRegularClassSymbol && (firClass.isData || firClass.isInline))
} }
private val FirClass.isFinal: Boolean private val FirClassSymbol<*>.isFinal: Boolean
get() { get() {
return when (this) { return when (this) {
is FirAnonymousObject -> true is FirAnonymousObjectSymbol -> true
is FirRegularClass -> status.modality == Modality.FINAL is FirRegularClassSymbol -> modality == Modality.FINAL
else -> throw java.lang.IllegalStateException("unknown type of FirClass $this") else -> error("unknown type of FirClass $this")
} }
} }
} }
@@ -12,10 +12,13 @@ import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.findArgumentByName import org.jetbrains.kotlin.fir.declarations.findArgumentByName
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
@@ -25,9 +28,14 @@ import org.jetbrains.kotlin.name.Name
private val RETENTION_PARAMETER_NAME = Name.identifier("value") private val RETENTION_PARAMETER_NAME = Name.identifier("value")
private val TARGET_PARAMETER_NAME = Name.identifier("allowedTargets") private val TARGET_PARAMETER_NAME = Name.identifier("allowedTargets")
@OptIn(SymbolInternals::class)
fun FirAnnotationCall.getRetention(session: FirSession): AnnotationRetention { fun FirAnnotationCall.getRetention(session: FirSession): AnnotationRetention {
val annotationClass = (this.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass val annotationClassSymbol =
return annotationClass?.getRetention() ?: AnnotationRetention.RUNTIME (this.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session) as? FirRegularClassSymbol
?: return AnnotationRetention.RUNTIME
annotationClassSymbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
val annotationClass = annotationClassSymbol.fir
return annotationClass.getRetention()
} }
fun FirRegularClass.getRetention(): AnnotationRetention { fun FirRegularClass.getRetention(): AnnotationRetention {
@@ -41,10 +49,13 @@ fun FirRegularClass.getRetention(): AnnotationRetention {
private val defaultAnnotationTargets = KotlinTarget.DEFAULT_TARGET_SET private val defaultAnnotationTargets = KotlinTarget.DEFAULT_TARGET_SET
@OptIn(SymbolInternals::class)
fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): Set<KotlinTarget> { fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): Set<KotlinTarget> {
if (annotationTypeRef is FirErrorTypeRef) return KotlinTarget.values().toSet() if (annotationTypeRef is FirErrorTypeRef) return KotlinTarget.values().toSet()
val annotationClass = (this.annotationTypeRef.coneType as? ConeClassLikeType) val annotationClassSymbol = (this.annotationTypeRef.coneType as? ConeClassLikeType)
?.fullyExpandedType(session)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass ?.fullyExpandedType(session)?.lookupTag?.toSymbol(session) ?: return defaultAnnotationTargets
annotationClassSymbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
val annotationClass = annotationClassSymbol.fir as? FirRegularClass
return annotationClass?.getAllowedAnnotationTargets() ?: defaultAnnotationTargets return annotationClass?.getAllowedAnnotationTargets() ?: defaultAnnotationTargets
} }
@@ -10,12 +10,15 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isConst import org.jetbrains.kotlin.fir.declarations.utils.isConst
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
@@ -28,9 +31,8 @@ internal fun checkConstantArguments(
session: FirSession, session: FirSession,
): ConstantArgumentKind? { ): ConstantArgumentKind? {
val expressionSymbol = expression.toResolvedCallableSymbol() val expressionSymbol = expression.toResolvedCallableSymbol()
?.fir
val classKindOfParent = (expressionSymbol val classKindOfParent = (expressionSymbol
?.getReferencedClass(session) as? FirRegularClass) ?.getReferencedClassSymbol(session) as? FirRegularClassSymbol)
?.classKind ?.classKind
when { when {
@@ -38,9 +40,9 @@ internal fun checkConstantArguments(
if (expression.operation == FirOperation.AS) return ConstantArgumentKind.NOT_CONST if (expression.operation == FirOperation.AS) return ConstantArgumentKind.NOT_CONST
} }
expression is FirConstExpression<*> expression is FirConstExpression<*>
|| expressionSymbol is FirEnumEntry || expressionSymbol is FirEnumEntrySymbol
|| (expressionSymbol as? FirMemberDeclaration)?.isConst == true || expressionSymbol?.isConst == true
|| expressionSymbol is FirConstructor && classKindOfParent == ClassKind.ANNOTATION_CLASS -> { || expressionSymbol is FirConstructorSymbol && classKindOfParent == ClassKind.ANNOTATION_CLASS -> {
//DO NOTHING //DO NOTHING
} }
classKindOfParent == ClassKind.ENUM_CLASS -> { classKindOfParent == ClassKind.ENUM_CLASS -> {
@@ -81,15 +83,15 @@ internal fun checkConstantArguments(
expressionSymbol == null -> { expressionSymbol == null -> {
//DO NOTHING //DO NOTHING
} }
expressionSymbol is FirField -> { expressionSymbol is FirFieldSymbol -> {
//TODO: fix checking of Java fields initializer //TODO: fix checking of Java fields initializer
if ( if (
!(expressionSymbol as FirMemberDeclaration).status.isStatic !expressionSymbol.isStatic
|| (expressionSymbol as FirMemberDeclaration).status.modality != Modality.FINAL || expressionSymbol.modality != Modality.FINAL
) )
return ConstantArgumentKind.NOT_CONST return ConstantArgumentKind.NOT_CONST
} }
expressionSymbol is FirConstructor -> { expressionSymbol is FirConstructorSymbol -> {
if (expression.typeRef.coneType.isUnsignedType) { if (expression.typeRef.coneType.isUnsignedType) {
(expression as FirFunctionCall).arguments.forEach { argumentExpression -> (expression as FirFunctionCall).arguments.forEach { argumentExpression ->
checkConstantArguments(argumentExpression, session)?.let { return it } checkConstantArguments(argumentExpression, session)?.let { return it }
@@ -158,9 +160,8 @@ internal fun checkConstantArguments(
} }
} }
expression is FirQualifiedAccessExpression -> { expression is FirQualifiedAccessExpression -> {
when { when {
(expressionSymbol as FirProperty).isLocal || expressionSymbol.symbol.callableId.className?.isRoot == false -> (expressionSymbol as FirPropertySymbol).isLocal || expressionSymbol.callableId.className?.isRoot == false ->
return ConstantArgumentKind.NOT_CONST return ConstantArgumentKind.NOT_CONST
expression.typeRef.coneType.classId == StandardClassIds.KClass -> expression.typeRef.coneType.classId == StandardClassIds.KClass ->
return ConstantArgumentKind.NOT_KCLASS_LITERAL return ConstantArgumentKind.NOT_KCLASS_LITERAL
@@ -169,10 +170,11 @@ internal fun checkConstantArguments(
expression.dispatchReceiver is FirThisReceiverExpression -> expression.dispatchReceiver is FirThisReceiverExpression ->
return null return null
} }
@OptIn(SymbolInternals::class)
return when ((expressionSymbol as? FirProperty)?.initializer) { val property = expressionSymbol.fir as? FirProperty
return when (property?.initializer) {
is FirConstExpression<*> -> { is FirConstExpression<*> -> {
if ((expressionSymbol as? FirVariable)?.isVal == true) if (property.isVal)
ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION
else else
ConstantArgumentKind.NOT_CONST ConstantArgumentKind.NOT_CONST
@@ -189,12 +191,11 @@ internal fun checkConstantArguments(
return null return null
} }
private fun FirTypedDeclaration?.getReferencedClass(session: FirSession): FirDeclaration? = private fun FirCallableSymbol<*>?.getReferencedClassSymbol(session: FirSession): FirBasedSymbol<*>? =
this?.returnTypeRef this?.resolvedReturnTypeRef
?.coneTypeSafe<ConeLookupTagBasedType>() ?.coneTypeSafe<ConeLookupTagBasedType>()
?.lookupTag ?.lookupTag
?.toSymbol(session) ?.toSymbol(session)
?.fir
private val CONVERSION_NAMES = listOf( private val CONVERSION_NAMES = listOf(
"toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean" "toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean"
@@ -22,13 +22,13 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol 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.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
@@ -53,18 +53,24 @@ private val INLINE_ONLY_ANNOTATION_CLASS_ID: ClassId = ClassId.topLevel(FqName("
fun FirClass.unsubstitutedScope(context: CheckerContext): FirTypeScope = fun FirClass.unsubstitutedScope(context: CheckerContext): FirTypeScope =
this.unsubstitutedScope(context.sessionHolder.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false) this.unsubstitutedScope(context.sessionHolder.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false)
fun FirClassSymbol<*>.unsubstitutedScope(context: CheckerContext): FirTypeScope =
this.unsubstitutedScope(context.sessionHolder.session, context.sessionHolder.scopeSession, withForcedTypeCalculator = false)
fun FirTypeRef.toClassLikeSymbol(session: FirSession): FirClassLikeSymbol<*>? {
return coneTypeSafe<ConeClassLikeType>()?.toSymbol(session) as? FirClassLikeSymbol<*>
}
/** /**
* Returns true if this is a supertype of other. * Returns true if this is a supertype of other.
*/ */
fun FirClass.isSupertypeOf(other: FirClass, session: FirSession): Boolean { fun FirClassSymbol<*>.isSupertypeOf(other: FirClassSymbol<*>, session: FirSession): Boolean {
/** /**
* Hides additional parameters. * Hides additional parameters.
*/ */
fun FirClass.isSupertypeOf(other: FirClass, exclude: MutableSet<FirClass>): Boolean { fun FirClassSymbol<*>.isSupertypeOf(other: FirClassSymbol<*>, exclude: MutableSet<FirClassSymbol<*>>): Boolean {
for (it in other.superTypeRefs) { for (it in other.resolvedSuperTypeRefs) {
val candidate = it.firClassLike(session) val candidate = it.toClassLikeSymbol(session)
?.followAllAlias(session) ?.fullyExpandedClass(session) as? FirClassSymbol<*>
?.safeAs<FirClass>()
?: continue ?: continue
if (candidate in exclude) { if (candidate in exclude) {
@@ -89,47 +95,36 @@ fun FirClass.isSupertypeOf(other: FirClass, session: FirSession): Boolean {
} }
/** /**
* Returns the FirClass associated with this * Returns the FirRegularClassSymbol associated with this
* or null of something goes wrong. * or null of something goes wrong.
*/ */
fun ConeClassLikeType.toClass(session: FirSession): FirClass? { fun ConeClassLikeType.toRegularClassSymbol(session: FirSession): FirRegularClassSymbol? {
return lookupTag.toSymbol(session).safeAs<FirClassSymbol<*>>()?.fir return fullyExpandedType(session).toSymbol(session) as? FirRegularClassSymbol
} }
fun ConeKotlinType.toRegularClassSymbol(session: FirSession): FirRegularClassSymbol? {
return (this as? ConeClassLikeType)?.toRegularClassSymbol(session)
}
fun ConeKotlinType.isInlineClass(session: FirSession): Boolean = toRegularClassSymbol(session)?.isInline == true
/** /**
* Returns the FirRegularClass associated with this * Returns the FirRegularClass associated with this
* or null of something goes wrong. * or null of something goes wrong.
*/ */
fun ConeClassLikeType.toRegularClass(session: FirSession): FirRegularClass? { fun FirTypeRef.toRegularClassSymbol(session: FirSession): FirRegularClassSymbol? {
return lookupTag.toSymbol(session).safeAs<FirRegularClassSymbol>()?.fir return coneType.toRegularClassSymbol(session)
}
/**
* Returns the FirRegularClass associated with this
* or null of something goes wrong.
*/
fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? {
return safeAs<ConeClassLikeType>()?.fullyExpandedType(session)?.toRegularClass(session)
}
fun ConeKotlinType.isInline(session: FirSession): Boolean = toRegularClass(session)?.isInline == true
/**
* Returns the FirRegularClass associated with this
* or null of something goes wrong.
*/
fun FirTypeRef.toRegularClass(session: FirSession): FirRegularClass? {
return coneType.toRegularClass(session)
} }
/** /**
* Returns the ClassLikeDeclaration where the Fir object has been defined * Returns the ClassLikeDeclaration where the Fir object has been defined
* or null if no proper declaration has been found. * or null if no proper declaration has been found.
*/ */
fun FirDeclaration.getContainingClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? = fun FirDeclaration.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? =
this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(context.session) this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(session)
fun FirBasedSymbol<*>.getContainingClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? = fir.getContainingClassSymbol(context) @OptIn(SymbolInternals::class)
fun FirBasedSymbol<*>.getContainingClassSymbol(session: FirSession): FirClassLikeSymbol<*>? = fir.getContainingClassSymbol(session)
fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? { fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLikeSymbol<*>? {
if (this !is FirClassSymbol<*>) return null if (this !is FirClassSymbol<*>) return null
@@ -142,14 +137,13 @@ fun FirClassLikeSymbol<*>.outerClassSymbol(context: CheckerContext): FirClassLik
* sequence of FirTypeAlias'es points to starting * sequence of FirTypeAlias'es points to starting
* with `this`. Or null if something goes wrong. * with `this`. Or null if something goes wrong.
*/ */
fun FirClassLikeDeclaration.followAllAlias(session: FirSession): FirClassLikeDeclaration? { fun FirClassLikeSymbol<*>.fullyExpandedClass(useSiteSession: FirSession): FirRegularClassSymbol? {
var it: FirClassLikeDeclaration? = this return when (this) {
is FirRegularClassSymbol -> this
while (it is FirTypeAlias) { is FirTypeAliasSymbol -> (resolvedExpandedTypeRef.coneTypeSafe<ConeClassLikeType>()
it = it.expandedTypeRef.firClassLike(session) ?.toSymbol(useSiteSession) as? FirClassLikeSymbol<*>)?.fullyExpandedClass(useSiteSession)
else -> null
} }
return it
} }
/** /**
@@ -184,7 +178,7 @@ fun FirSimpleFunction.overriddenFunctions(
) )
val overriddenFunctions = mutableListOf<FirFunctionSymbol<*>>() val overriddenFunctions = mutableListOf<FirFunctionSymbol<*>>()
firTypeScope.processFunctionsByName(symbol.fir.name) { } firTypeScope.processFunctionsByName(symbol.callableId.callableName) { }
firTypeScope.processOverriddenFunctions(symbol) { firTypeScope.processOverriddenFunctions(symbol) {
overriddenFunctions.add(it) overriddenFunctions.add(it)
ProcessorAction.NEXT ProcessorAction.NEXT
@@ -268,11 +262,9 @@ fun FirClass.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef? {
for (superTypeRef in superTypeRefs) { for (superTypeRef in superTypeRefs) {
val lookupTag = superTypeRef.coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: continue val lookupTag = superTypeRef.coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: continue
val fir = lookupTag.toSymbol(context.session) val symbol = lookupTag.toSymbol(context.session) as? FirClassSymbol<*> ?: continue
?.fir.safeAs<FirClass>()
?: continue
if (fir.classKind != ClassKind.INTERFACE) { if (symbol.classKind != ClassKind.INTERFACE) {
return superTypeRef return superTypeRef
} }
} }
@@ -302,13 +294,12 @@ fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
if (this.isMarkedNullable) { if (this.isMarkedNullable) {
return true return true
} }
val clazz = toRegularClass(session) ?: return true val classSymbol = toRegularClassSymbol(session) ?: return true
if (clazz.isEnumClass || clazz.isExpect || clazz.modality != Modality.FINAL) { if (classSymbol.isEnumClass || classSymbol.isExpect || classSymbol.modality != Modality.FINAL) {
return true return true
} }
clazz.typeParameters.forEachIndexed { idx, typeParameterRef -> classSymbol.typeParameterSymbols.forEachIndexed { idx, typeParameterSymbol ->
val typeParameter = typeParameterRef.symbol.fir
val typeProjection = typeArguments[idx] val typeProjection = typeArguments[idx]
if (typeProjection.isStarProjection) { if (typeProjection.isStarProjection) {
@@ -317,15 +308,15 @@ fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
val argument = typeProjection.type!! //safe because it is not a star val argument = typeProjection.type!! //safe because it is not a star
when (typeParameter.variance) { when (typeParameterSymbol.variance) {
Variance.INVARIANT -> Variance.INVARIANT ->
when (typeProjection.kind) { when (typeProjection.kind) {
ProjectionKind.INVARIANT -> ProjectionKind.INVARIANT ->
if (lowerThanBound(session.typeContext, argument, typeParameter) || argument.canHaveSubtypes(session)) { if (lowerThanBound(session.typeContext, argument, typeParameterSymbol) || argument.canHaveSubtypes(session)) {
return true return true
} }
ProjectionKind.IN -> ProjectionKind.IN ->
if (lowerThanBound(session.typeContext, argument, typeParameter)) { if (lowerThanBound(session.typeContext, argument, typeParameterSymbol)) {
return true return true
} }
ProjectionKind.OUT -> ProjectionKind.OUT ->
@@ -337,7 +328,7 @@ fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
} }
Variance.IN_VARIANCE -> Variance.IN_VARIANCE ->
if (typeProjection.kind != ProjectionKind.OUT) { if (typeProjection.kind != ProjectionKind.OUT) {
if (lowerThanBound(session.typeContext, argument, typeParameter)) { if (lowerThanBound(session.typeContext, argument, typeParameterSymbol)) {
return true return true
} }
} else { } else {
@@ -351,7 +342,7 @@ fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
return true return true
} }
} else { } else {
if (lowerThanBound(session.typeContext, argument, typeParameter)) { if (lowerThanBound(session.typeContext, argument, typeParameterSymbol)) {
return true return true
} }
} }
@@ -361,8 +352,8 @@ fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
return false return false
} }
private fun lowerThanBound(context: ConeInferenceContext, argument: ConeKotlinType, typeParameter: FirTypeParameter): Boolean { private fun lowerThanBound(context: ConeInferenceContext, argument: ConeKotlinType, typeParameterSymbol: FirTypeParameterSymbol): Boolean {
typeParameter.bounds.forEach { boundTypeRef -> typeParameterSymbol.resolvedBounds.forEach { boundTypeRef ->
if (argument != boundTypeRef.coneType && argument.isSubtypeOf(context, boundTypeRef.coneType)) { if (argument != boundTypeRef.coneType && argument.isSubtypeOf(context, boundTypeRef.coneType)) {
return true return true
} }
@@ -409,13 +400,17 @@ private fun isSubtypeOfForFunctionalTypeReturningUnit(
} }
fun FirCallableDeclaration.isVisibleInClass(parentClass: FirClass): Boolean { fun FirCallableDeclaration.isVisibleInClass(parentClass: FirClass): Boolean {
val classPackage = parentClass.symbol.classId.packageFqName return symbol.isVisibleInClass(parentClass.symbol)
}
fun FirCallableSymbol<*>.isVisibleInClass(parentClassSymbol: FirClassSymbol<*>): Boolean {
val classPackage = parentClassSymbol.classId.packageFqName
if (visibility == Visibilities.Private || if (visibility == Visibilities.Private ||
!visibility.visibleFromPackage(classPackage, symbol.callableId.packageName) !visibility.visibleFromPackage(classPackage, callableId.packageName)
) return false ) return false
if ( if (
visibility == Visibilities.Internal && visibility == Visibilities.Internal &&
(moduleData != parentClass.moduleData || parentClass.moduleData in moduleData.friendDependencies) (moduleData != parentClassSymbol.moduleData || parentClassSymbol.moduleData in moduleData.friendDependencies)
) return false ) return false
return true return true
} }
@@ -423,29 +418,34 @@ fun FirCallableDeclaration.isVisibleInClass(parentClass: FirClass): Boolean {
/** /**
* Get the [ImplementationStatus] for this member. * Get the [ImplementationStatus] for this member.
* *
* @param parentClass the contextual class for this query. * @param parentClassSymbol the contextual class for this query.
*/ */
fun FirCallableDeclaration.getImplementationStatus(sessionHolder: SessionHolder, parentClass: FirClass): ImplementationStatus { fun FirCallableSymbol<*>.getImplementationStatus(
val containingClass = getContainingClass(sessionHolder) sessionHolder: SessionHolder,
val symbol = this.symbol parentClassSymbol: FirClassSymbol<*>
): ImplementationStatus {
val containingClassSymbol = getContainingClassSymbol(sessionHolder.session)
val symbol = this
if (this.multipleDelegatesWithTheSameSignature == true && containingClass == parentClass) { if (this.multipleDelegatesWithTheSameSignature == true && containingClassSymbol == parentClassSymbol) {
return ImplementationStatus.AMBIGUOUSLY_INHERITED return ImplementationStatus.AMBIGUOUSLY_INHERITED
} }
if (symbol is FirIntersectionCallableSymbol) { if (symbol is FirIntersectionCallableSymbol) {
if (containingClass === parentClass && symbol.subjectToManyNotImplemented(sessionHolder)) { if (containingClassSymbol === parentClassSymbol && symbol.subjectToManyNotImplemented(sessionHolder)) {
return ImplementationStatus.AMBIGUOUSLY_INHERITED return ImplementationStatus.AMBIGUOUSLY_INHERITED
} }
// In Java 8, non-abstract intersection overrides having abstract symbol from base class // In Java 8, non-abstract intersection overrides having abstract symbol from base class
// still should be implemented in current class (even when they have default interface implementation) // still should be implemented in current class (even when they have default interface implementation)
if (symbol.intersections.any { if (symbol.intersections.any {
@OptIn(SymbolInternals::class)
val fir = it.fir.unwrapFakeOverrides() val fir = it.fir.unwrapFakeOverrides()
fir.isAbstract && (fir.getContainingClass(sessionHolder) as? FirRegularClass)?.classKind == ClassKind.CLASS fir.isAbstract && (fir.getContainingClassSymbol(sessionHolder.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS
} }
) { ) {
// Exception from the rule above: interface implementation via delegation // Exception from the rule above: interface implementation via delegation
if (symbol.intersections.none { if (symbol.intersections.none {
@OptIn(SymbolInternals::class)
val fir = it.fir val fir = it.fir
fir.origin == FirDeclarationOrigin.Delegated && !fir.isAbstract fir.origin == FirDeclarationOrigin.Delegated && !fir.isAbstract
} }
@@ -454,8 +454,8 @@ fun FirCallableDeclaration.getImplementationStatus(sessionHolder: SessionHolder,
} }
} }
} }
if (this is FirSimpleFunction) { if (this is FirNamedFunctionSymbol) {
if (parentClass is FirRegularClass && parentClass.isData && matchesDataClassSyntheticMemberSignatures) { if (parentClassSymbol is FirRegularClassSymbol && parentClassSymbol.isData && matchesDataClassSyntheticMemberSignatures) {
return ImplementationStatus.INHERITED_OR_SYNTHESIZED return ImplementationStatus.INHERITED_OR_SYNTHESIZED
} }
// TODO: suspend function overridden by a Java class in the middle is not properly regarded as an override // TODO: suspend function overridden by a Java class in the middle is not properly regarded as an override
@@ -465,8 +465,8 @@ fun FirCallableDeclaration.getImplementationStatus(sessionHolder: SessionHolder,
} }
return when { return when {
isFinal -> ImplementationStatus.CANNOT_BE_IMPLEMENTED isFinal -> ImplementationStatus.CANNOT_BE_IMPLEMENTED
containingClass === parentClass && origin == FirDeclarationOrigin.Source -> ImplementationStatus.ALREADY_IMPLEMENTED containingClassSymbol === parentClassSymbol && origin == FirDeclarationOrigin.Source -> ImplementationStatus.ALREADY_IMPLEMENTED
containingClass is FirRegularClass && containingClass.isExpect -> ImplementationStatus.CANNOT_BE_IMPLEMENTED containingClassSymbol is FirRegularClassSymbol && containingClassSymbol.isExpect -> ImplementationStatus.CANNOT_BE_IMPLEMENTED
isAbstract -> ImplementationStatus.NOT_IMPLEMENTED isAbstract -> ImplementationStatus.NOT_IMPLEMENTED
else -> ImplementationStatus.INHERITED_OR_SYNTHESIZED else -> ImplementationStatus.INHERITED_OR_SYNTHESIZED
} }
@@ -478,10 +478,9 @@ private fun FirIntersectionCallableSymbol.subjectToManyNotImplemented(sessionHol
var nonAbstractCountInInterface = 0 var nonAbstractCountInInterface = 0
var abstractCountInInterface = 0 var abstractCountInInterface = 0
for (intersectionSymbol in intersections) { for (intersectionSymbol in intersections) {
val intersection = intersectionSymbol.fir val containingClassSymbol = intersectionSymbol.getContainingClassSymbol(sessionHolder.session) as? FirRegularClassSymbol
val containingClass = intersection.getContainingClass(sessionHolder) as? FirRegularClass val hasInterfaceContainer = containingClassSymbol?.classKind == ClassKind.INTERFACE
val hasInterfaceContainer = containingClass?.classKind == ClassKind.INTERFACE if (intersectionSymbol.modality != Modality.ABSTRACT) {
if (intersection.modality != Modality.ABSTRACT) {
if (hasInterfaceContainer) { if (hasInterfaceContainer) {
nonAbstractCountInInterface++ nonAbstractCountInInterface++
} else { } else {
@@ -500,23 +499,26 @@ private fun FirIntersectionCallableSymbol.subjectToManyNotImplemented(sessionHol
return false return false
} }
private val FirSimpleFunction.matchesDataClassSyntheticMemberSignatures: Boolean private val FirNamedFunctionSymbol.matchesDataClassSyntheticMemberSignatures: Boolean
get() = (this.name == OperatorNameConventions.EQUALS && matchesEqualsSignature) || get() {
(this.name == HASHCODE_NAME && matchesHashCodeSignature) || val name = callableId.callableName
(this.name == OperatorNameConventions.TO_STRING && matchesToStringSignature) return (name == OperatorNameConventions.EQUALS && matchesEqualsSignature) ||
(name == HASHCODE_NAME && matchesHashCodeSignature) ||
private fun FirDeclaration.getContainingClass(sessionHolder: SessionHolder): FirClassLikeDeclaration? = (name == OperatorNameConventions.TO_STRING && matchesToStringSignature)
this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(sessionHolder.session)?.fir }
// NB: we intentionally do not check return types // NB: we intentionally do not check return types
private val FirSimpleFunction.matchesEqualsSignature: Boolean private val FirNamedFunctionSymbol.matchesEqualsSignature: Boolean
get() = valueParameters.size == 1 && valueParameters[0].returnTypeRef.coneType.isNullableAny get() {
val valueParameters = valueParameterSymbols
return valueParameters.size == 1 && valueParameters[0].resolvedReturnTypeRef.coneType.isNullableAny
}
private val FirSimpleFunction.matchesHashCodeSignature: Boolean private val FirNamedFunctionSymbol.matchesHashCodeSignature: Boolean
get() = valueParameters.isEmpty() get() = valueParameterSymbols.isEmpty()
private val FirSimpleFunction.matchesToStringSignature: Boolean private val FirNamedFunctionSymbol.matchesToStringSignature: Boolean
get() = valueParameters.isEmpty() get() = valueParameterSymbols.isEmpty()
val Name.isDelegated: Boolean get() = asString().startsWith("<\$\$delegate_") val Name.isDelegated: Boolean get() = asString().startsWith("<\$\$delegate_")
@@ -634,3 +636,42 @@ fun extractArgumentTypeRefAndSource(typeRef: FirTypeRef?, index: Int): FirTypeRe
} }
data class FirTypeRefSource(val typeRef: FirTypeRef?, val source: FirSourceElement?) data class FirTypeRefSource(val typeRef: FirTypeRef?, val source: FirSourceElement?)
fun FirRegularClassSymbol.collectEnumEntries(): Collection<FirEnumEntrySymbol> {
assert(classKind == ClassKind.ENUM_CLASS)
return declarationSymbols.filterIsInstance<FirEnumEntrySymbol>()
}
val FirClassLikeSymbol<*>.classKind: ClassKind?
get() = (this as? FirClassSymbol<*>)?.classKind
val FirBasedSymbol<*>.typeParameterSymbols: List<FirTypeParameterSymbol>?
get() = when (this) {
is FirCallableSymbol<*> -> typeParameterSymbols
is FirClassSymbol<*> -> typeParameterSymbols
is FirTypeAliasSymbol -> typeParameterSymbols
else -> null
}
/*
* This is phase-safe version of similar function from FirCallCompleter
*
* Expect type is only being added to calls in a position of cast argument: foo() as R
* And that call should be resolved to something materialize()-like: it returns its single generic parameter and doesn't have value parameters
* fun <T> materialize(): T
*/
fun FirFunctionSymbol<*>.isFunctionForExpectTypeFromCastFeature(): Boolean {
val typeParameterSymbol = typeParameterSymbols.singleOrNull() ?: return false
val returnType = resolvedReturnTypeRef.coneType
if ((returnType.lowerBoundIfFlexible() as? ConeTypeParameterType)?.lookupTag != typeParameterSymbol.toLookupTag()) return false
fun FirTypeRef.isBadType() =
coneTypeSafe<ConeKotlinType>()
?.contains { (it.lowerBoundIfFlexible() as? ConeTypeParameterType)?.lookupTag == typeParameterSymbol.toLookupTag() } != false
if (valueParameterSymbols.any { it.resolvedReturnTypeRef.isBadType() } || resolvedReceiverTypeRef?.isBadType() == true) return false
return true
}
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
fun checkInconsistentTypeParameters( fun checkInconsistentTypeParameters(
firTypeRefClasses: List<Pair<FirTypeRef?, FirRegularClass>>, firTypeRefClasses: List<Pair<FirTypeRef?, FirRegularClassSymbol>>,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
source: FirSourceElement?, source: FirSourceElement?,
@@ -55,7 +55,7 @@ fun checkInconsistentTypeParameters(
} }
private fun buildDeepSubstitutionMultimap( private fun buildDeepSubstitutionMultimap(
firTypeRefClasses: List<Pair<FirTypeRef?, FirRegularClass>>, firTypeRefClasses: List<Pair<FirTypeRef?, FirRegularClassSymbol>>,
context: CheckerContext, context: CheckerContext,
): Map<FirTypeParameterSymbol, ClassSymbolAndProjections> { ): Map<FirTypeParameterSymbol, ClassSymbolAndProjections> {
val result = mutableMapOf<FirTypeParameterSymbol, ClassSymbolAndProjections>() val result = mutableMapOf<FirTypeParameterSymbol, ClassSymbolAndProjections>()
@@ -63,10 +63,10 @@ private fun buildDeepSubstitutionMultimap(
val session = context.session val session = context.session
val typeContext = session.typeContext val typeContext = session.typeContext
fun fillInDeepSubstitutor(typeArguments: Array<out ConeTypeProjection>?, firClass: FirRegularClass) { fun fillInDeepSubstitutor(typeArguments: Array<out ConeTypeProjection>?, classSymbol: FirRegularClassSymbol) {
if (typeArguments != null) { if (typeArguments != null) {
val typeParameters = firClass.typeParameters val typeParameterSymbols = classSymbol.typeParameterSymbols
val count = minOf(typeArguments.size, typeParameters.size) val count = minOf(typeArguments.size, typeParameterSymbols.size)
for (index in 0 until count) { for (index in 0 until count) {
val typeArgument = typeArguments[index] val typeArgument = typeArguments[index]
@@ -74,14 +74,14 @@ private fun buildDeepSubstitutionMultimap(
val substitutedArgument = ConeSubstitutorByMap(substitution, session).substituteArgument(typeArgument) ?: typeArgument val substitutedArgument = ConeSubstitutorByMap(substitution, session).substituteArgument(typeArgument) ?: typeArgument
val substitutedType = substitutedArgument.type ?: continue val substitutedType = substitutedArgument.type ?: continue
val typeParameterSymbol = typeParameters[index].symbol val typeParameterSymbol = typeParameterSymbols[index]
substitution[typeParameterSymbol] = substitutedType substitution[typeParameterSymbol] = substitutedType
var classSymbolAndProjections = result[typeParameterSymbol] var classSymbolAndProjections = result[typeParameterSymbol]
val projections: MutableList<ConeKotlinType> val projections: MutableList<ConeKotlinType>
if (classSymbolAndProjections == null) { if (classSymbolAndProjections == null) {
projections = mutableListOf() projections = mutableListOf()
classSymbolAndProjections = ClassSymbolAndProjections(firClass.symbol, projections) classSymbolAndProjections = ClassSymbolAndProjections(classSymbol, projections)
result[typeParameterSymbol] = classSymbolAndProjections result[typeParameterSymbol] = classSymbolAndProjections
} else { } else {
projections = classSymbolAndProjections.projections projections = classSymbolAndProjections.projections
@@ -95,12 +95,12 @@ private fun buildDeepSubstitutionMultimap(
} }
} }
for (superTypeRef in firClass.superTypeRefs) { for (superTypeRef in classSymbol.resolvedSuperTypeRefs) {
withSuppressedDiagnostics(superTypeRef, context) { withSuppressedDiagnostics(superTypeRef, context) {
val fullyExpandedType = superTypeRef.coneType.fullyExpandedType(session) val fullyExpandedType = superTypeRef.coneType.fullyExpandedType(session)
val superTypeClass = fullyExpandedType.toRegularClass(session) val superClassSymbol = fullyExpandedType.toRegularClassSymbol(session)
if (!fullyExpandedType.isEnum && superTypeClass != null) { if (!fullyExpandedType.isEnum && superClassSymbol != null) {
fillInDeepSubstitutor(fullyExpandedType.typeArguments, superTypeClass) fillInDeepSubstitutor(fullyExpandedType.typeArguments, superClassSymbol)
} }
} }
} }
@@ -115,4 +115,4 @@ private fun buildDeepSubstitutionMultimap(
private data class ClassSymbolAndProjections( private data class ClassSymbolAndProjections(
val classSymbol: FirRegularClassSymbol, val classSymbol: FirRegularClassSymbol,
val projections: MutableList<ConeKotlinType> val projections: MutableList<ConeKotlinType>
) )
@@ -14,6 +14,9 @@ import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
@@ -72,17 +75,23 @@ private fun FirAnnotatedDeclaration.getOwnSinceKotlinVersion(session: FirSession
} }
} }
fun FirClassLikeSymbol<*>.consider() {
ensureResolved(FirResolvePhase.BODY_RESOLVE)
@OptIn(SymbolInternals::class)
this.fir.consider()
}
this.consider() this.consider()
if (this is FirConstructor) { if (this is FirConstructor) {
val classId = symbol.callableId.classId val classId = symbol.callableId.classId
if (classId != null) { if (classId != null) {
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId)
classSymbol?.fir?.consider() classSymbol?.consider()
} }
} }
if (this is FirTypeAlias) { if (this is FirTypeAlias) {
(this.expandedTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir?.consider() (this.expandedTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.consider()
} }
return result return result
@@ -10,10 +10,10 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -47,17 +47,14 @@ fun checkUpperBoundViolated(
val typeParameterSymbols = typeParameters val typeParameterSymbols = typeParameters
?: if (type is ConeClassLikeType) { ?: if (type is ConeClassLikeType) {
val fullyExpandedType = type.fullyExpandedType(context.session) val fullyExpandedType = type.fullyExpandedType(context.session)
val prototypeClass = fullyExpandedType.lookupTag.toSymbol(context.session) val prototypeClassSymbol = fullyExpandedType.lookupTag.toSymbol(context.session) as? FirRegularClassSymbol ?: return
?.fir as? FirRegularClass
?: return
if (type != fullyExpandedType) { if (type != fullyExpandedType) {
// special check for type aliases // special check for type aliases
checkUpperBoundViolated( checkUpperBoundViolated(
typeRef, typeRef,
context, context,
reporter, reporter,
prototypeClass.typeParameters.map { it.symbol }, prototypeClassSymbol.typeParameterSymbols,
fullyExpandedType.typeArguments.toList(), fullyExpandedType.typeArguments.toList(),
null, null,
isTypeAlias = true, isTypeAlias = true,
@@ -66,7 +63,7 @@ fun checkUpperBoundViolated(
return return
} }
prototypeClass.typeParameters.map { it.symbol } prototypeClassSymbol.typeParameterSymbols
} else { } else {
listOf() listOf()
} }
@@ -139,7 +136,7 @@ fun checkUpperBoundViolated(
if (typeArgument != null && typeArgumentSource != null) { if (typeArgument != null && typeArgumentSource != null) {
if (!isIgnoreTypeParameters || (typeArgument.typeArguments.isEmpty() && typeArgument !is ConeTypeParameterType)) { if (!isIgnoreTypeParameters || (typeArgument.typeArguments.isEmpty() && typeArgument !is ConeTypeParameterType)) {
val intersection = val intersection =
typeSystemContext.intersectTypes(typeParameterSymbols[index].fir.bounds.map { it.coneType }) as? ConeKotlinType typeSystemContext.intersectTypes(typeParameterSymbols[index].resolvedBounds.map { it.coneType }) as? ConeKotlinType
if (intersection != null) { if (intersection != null) {
val upperBound = substitutor.substituteOrSelf(intersection) val upperBound = substitutor.substituteOrSelf(intersection)
if (!AbstractTypeChecker.isSubtypeOf( if (!AbstractTypeChecker.isSubtypeOf(
@@ -162,4 +159,4 @@ fun checkUpperBoundViolated(
checkUpperBoundViolated(typeArgumentTypeRef, context, reporter, isIgnoreTypeParameters = isIgnoreTypeParameters) checkUpperBoundViolated(typeArgumentTypeRef, context, reporter, isIgnoreTypeParameters = isIgnoreTypeParameters)
} }
} }
} }
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
@@ -118,8 +119,7 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() {
} }
private fun isAllowedClassKind(cone: ConeLookupTagBasedType, session: FirSession): Boolean { private fun isAllowedClassKind(cone: ConeLookupTagBasedType, session: FirSession): Boolean {
val typeRefClassKind = (cone.lookupTag.toSymbol(session) val typeRefClassKind = (cone.lookupTag.toSymbol(session) as? FirRegularClassSymbol)
?.fir as? FirRegularClass)
?.classKind ?.classKind
?: return false ?: return false
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
@@ -110,10 +111,10 @@ object FirClassVarianceChecker : FirClassChecker() {
) { ) {
if (type is ConeTypeParameterType) { if (type is ConeTypeParameterType) {
val fullyExpandedType = type.fullyExpandedType(context.session) val fullyExpandedType = type.fullyExpandedType(context.session)
val typeParameter = type.lookupTag.typeParameterSymbol.fir val typeParameterSymbol = type.lookupTag.typeParameterSymbol
val resultSource = source ?: typeRef?.source val resultSource = source ?: typeRef?.source
if (resultSource != null && if (resultSource != null &&
!typeParameter.variance.allowsPosition(variance) && !typeParameterSymbol.variance.allowsPosition(variance) &&
!fullyExpandedType.attributes.contains(CompilerConeAttributes.UnsafeVariance) !fullyExpandedType.attributes.contains(CompilerConeAttributes.UnsafeVariance)
) { ) {
val factory = val factory =
@@ -121,8 +122,8 @@ object FirClassVarianceChecker : FirClassChecker() {
reporter.reportOn( reporter.reportOn(
resultSource, resultSource,
factory, factory,
typeParameter.symbol, typeParameterSymbol,
typeParameter.variance, typeParameterSymbol.variance,
variance, variance,
containingType, containingType,
context context
@@ -133,10 +134,10 @@ object FirClassVarianceChecker : FirClassChecker() {
if (type is ConeClassLikeType) { if (type is ConeClassLikeType) {
val fullyExpandedType = type.fullyExpandedType(context.session) val fullyExpandedType = type.fullyExpandedType(context.session)
val declFir = fullyExpandedType.lookupTag.toSymbol(context.session)?.fir val classSymbol = fullyExpandedType.lookupTag.toSymbol(context.session)
if (declFir is FirClass) { if (classSymbol is FirClassSymbol<*>) {
for ((index, typeArgument) in fullyExpandedType.typeArguments.withIndex()) { for ((index, typeArgument) in fullyExpandedType.typeArguments.withIndex()) {
val paramVariance = (declFir.typeParameters.getOrNull(index) as? FirTypeParameter)?.variance ?: continue val paramVariance = classSymbol.typeParameterSymbols.getOrNull(index)?.variance ?: continue
val argVariance = when (typeArgument.kind) { val argVariance = when (typeArgument.kind) {
ProjectionKind.IN -> Variance.IN_VARIANCE ProjectionKind.IN -> Variance.IN_VARIANCE
@@ -147,8 +148,7 @@ object FirClassVarianceChecker : FirClassChecker() {
val typeArgumentType = typeArgument.type ?: continue val typeArgumentType = typeArgument.type ?: continue
val projectionKind = TypeCheckingProcedure.getEffectiveProjectionKind(paramVariance, argVariance)!! val newVariance = when (TypeCheckingProcedure.getEffectiveProjectionKind(paramVariance, argVariance)!!) {
val newVariance = when (projectionKind) {
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> variance TypeCheckingProcedure.EnrichedProjectionKind.OUT -> variance
TypeCheckingProcedure.EnrichedProjectionKind.IN -> variance.opposite() TypeCheckingProcedure.EnrichedProjectionKind.IN -> variance.opposite()
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT
@@ -12,14 +12,16 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() { object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
val cyclicConstructors = mutableSetOf<FirConstructor>() val cyclicConstructors = mutableSetOf<FirConstructor>()
var hasPrimaryConstructor = false var hasPrimaryConstructor = false
@@ -91,8 +93,12 @@ object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() {
return null return null
} }
private fun FirConstructor.getDelegated(): FirConstructor? = delegatedConstructor private fun FirConstructor.getDelegated(): FirConstructor? {
?.calleeReference.safeAs<FirResolvedNamedReference>() this.symbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
?.resolvedSymbol val delegatedConstructorSymbol = delegatedConstructor
?.fir as? FirConstructor? ?.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol
@OptIn(SymbolInternals::class)
return delegatedConstructorSymbol?.fir as? FirConstructor
}
} }
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
@@ -76,6 +78,8 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
conflictingFile: FirFile?, conflictingFile: FirFile?,
session: FirSession session: FirSession
) { ) {
conflictingSymbol.ensureResolved(FirResolvePhase.STATUS)
@OptIn(SymbolInternals::class)
val conflicting = conflictingSymbol.fir as? FirDeclaration ?: return val conflicting = conflictingSymbol.fir as? FirDeclaration ?: return
if (declaration.moduleData != conflicting.moduleData) return if (declaration.moduleData != conflicting.moduleData) return
val actualConflictingPresentation = conflictingPresentation ?: presenter.represent(conflicting) val actualConflictingPresentation = conflictingPresentation ?: presenter.represent(conflicting)
@@ -116,6 +120,8 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
) )
} }
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ -> packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
symbol.ensureResolved(FirResolvePhase.STATUS)
@OptIn(SymbolInternals::class)
val classWithSameName = symbol.fir as? FirRegularClass val classWithSameName = symbol.fir as? FirRegularClass
classWithSameName?.onConstructors { constructor -> classWithSameName?.onConstructors { constructor ->
collectExternalConflict( collectExternalConflict(
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeCyclicTypeBound import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeCyclicTypeBound
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -24,7 +25,7 @@ object FirCyclicTypeBoundsChecker : FirBasicDeclarationChecker() {
val processed = mutableSetOf<Name>() val processed = mutableSetOf<Name>()
val cycles = mutableSetOf<Name>() val cycles = mutableSetOf<Name>()
val graph = declaration.typeParameters.associate { param -> val graph = declaration.typeParameters.associate { param ->
param.symbol.name to param.symbol.fir.bounds.flatMap { extractTypeParamNames(it) }.toSet() param.symbol.name to param.symbol.resolvedBounds.flatMap { extractTypeParamNames(it) }.toSet()
} }
val graphFunc = { name: Name -> graph.getOrDefault(name, emptySet()) } val graphFunc = { name: Name -> graph.getOrDefault(name, emptySet()) }
val path = mutableListOf<Name>() val path = mutableListOf<Name>()
@@ -51,7 +52,7 @@ object FirCyclicTypeBoundsChecker : FirBasicDeclarationChecker() {
.forEach { param -> .forEach { param ->
//for some reason FE 1.0 report differently for class declarations //for some reason FE 1.0 report differently for class declarations
val targets = if (declaration is FirRegularClass) { val targets = if (declaration is FirRegularClass) {
param.symbol.fir.originalBounds().filter { cycles.contains(extractTypeParamName(it.coneType)) } param.symbol.originalBounds().filter { cycles.contains(extractTypeParamName(it.coneType)) }
.mapNotNull { it.source } .mapNotNull { it.source }
} else { } else {
listOf(param.source) listOf(param.source)
@@ -63,7 +64,7 @@ object FirCyclicTypeBoundsChecker : FirBasicDeclarationChecker() {
} }
} }
private fun FirTypeParameter.originalBounds() = bounds.flatMap { it.unwrapBound() } private fun FirTypeParameterSymbol.originalBounds() = resolvedBounds.flatMap { it.unwrapBound() }
private fun FirTypeRef.unwrapBound(): List<FirTypeRef> = private fun FirTypeRef.unwrapBound(): List<FirTypeRef> =
if (this is FirErrorTypeRef && diagnostic is ConeCyclicTypeBound) { if (this is FirErrorTypeRef && diagnostic is ConeCyclicTypeBound) {
@@ -21,7 +21,8 @@ import org.jetbrains.kotlin.fir.containingClassAttr
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
@@ -192,10 +193,16 @@ internal fun FirRegularClass.isInlineOrValueClass(): Boolean {
return isInline || hasModifier(KtTokens.VALUE_KEYWORD) return isInline || hasModifier(KtTokens.VALUE_KEYWORD)
} }
internal fun FirRegularClassSymbol.isInlineOrValueClass(): Boolean {
if (this.classKind != ClassKind.CLASS) return false
return isInline
}
internal val FirDeclaration.isEnumEntryInitializer: Boolean internal val FirDeclaration.isEnumEntryInitializer: Boolean
get() { get() {
if (this !is FirConstructor || !this.isPrimary) return false if (this !is FirConstructor || !this.isPrimary) return false
return (containingClassAttr as? ConeClassLookupTagWithFixedSymbol)?.symbol?.fir?.classKind == ClassKind.ENUM_ENTRY return (containingClassAttr as? ConeClassLookupTagWithFixedSymbol)?.symbol?.classKind == ClassKind.ENUM_ENTRY
} }
// contract: returns(true) implies (this is FirMemberDeclaration<*>) // contract: returns(true) implies (this is FirMemberDeclaration<*>)
@@ -207,7 +214,20 @@ internal val FirDeclaration.isLocalMember: Boolean
else -> false else -> false
} }
internal val FirBasedSymbol<*>.isLocalMember: Boolean
get() = when (this) {
is FirPropertySymbol -> this.isLocal
is FirRegularClassSymbol -> this.isLocal
is FirNamedFunctionSymbol -> this.isLocal
else -> false
}
internal val FirCallableDeclaration.isExtensionMember: Boolean internal val FirCallableDeclaration.isExtensionMember: Boolean
get() { get() {
return receiverTypeRef != null && dispatchReceiverType != null return receiverTypeRef != null && dispatchReceiverType != null
} }
internal val FirCallableSymbol<*>.isExtensionMember: Boolean
get() {
return resolvedReceiverTypeRef != null && dispatchReceiverType != null
}
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
@@ -24,6 +21,9 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeConstraintSystemHasContradiction import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeConstraintSystemHasContradiction
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -66,8 +66,8 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
val originalDestructuringDeclarationOrInitializerSource = originalDestructuringDeclarationOrInitializer.source ?: return val originalDestructuringDeclarationOrInitializerSource = originalDestructuringDeclarationOrInitializer.source ?: return
val originalDestructuringDeclarationType = val originalDestructuringDeclarationType =
when (originalDestructuringDeclarationOrInitializer) { when (originalDestructuringDeclarationOrInitializer) {
is FirVariable -> originalDestructuringDeclarationOrInitializer.returnTypeRef.coneTypeSafe<ConeKotlinType>() is FirVariable -> originalDestructuringDeclarationOrInitializer.returnTypeRef.coneType
is FirExpression -> originalDestructuringDeclarationOrInitializer.typeRef.coneTypeSafe<ConeKotlinType>() is FirExpression -> originalDestructuringDeclarationOrInitializer.typeRef.coneType
else -> null else -> null
} ?: return } ?: return
@@ -137,7 +137,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
reporter.reportOn( reporter.reportOn(
source, source,
FirErrors.COMPONENT_FUNCTION_ON_NULLABLE, FirErrors.COMPONENT_FUNCTION_ON_NULLABLE,
(diagnostic.candidate.symbol.fir as FirSimpleFunction).name, (diagnostic.candidate.symbol as FirNamedFunctionSymbol).callableId.callableName,
context context
) )
} }
@@ -182,5 +182,10 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
} }
private val FirQualifiedAccessExpression.resolvedVariable: FirVariable? private val FirQualifiedAccessExpression.resolvedVariable: FirVariable?
get() = ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirVariableSymbol)?.fir as? FirVariable get() {
val symbol = (calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirVariableSymbol<*> ?: return null
symbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
@OptIn(SymbolInternals::class)
return symbol.fir
}
} }
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -18,7 +18,9 @@ import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -32,6 +34,7 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
is FirProperty -> checkProperty(declaration, reporter, context) is FirProperty -> checkProperty(declaration, reporter, context)
is FirFunction -> checkFunction(declaration, reporter, context) is FirFunction -> checkFunction(declaration, reporter, context)
is FirRegularClass -> checkClass(declaration, reporter, context) is FirRegularClass -> checkClass(declaration, reporter, context)
else -> {}
} }
} }
@@ -48,22 +51,20 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
val isInterface = declaration.classKind == ClassKind.INTERFACE val isInterface = declaration.classKind == ClassKind.INTERFACE
for (supertypeRef in supertypes) { for (supertypeRef in supertypes) {
val supertype = supertypeRef.coneTypeSafe<ConeClassLikeType>() ?: continue val supertype = supertypeRef.coneTypeSafe<ConeClassLikeType>() ?: continue
val clazz = supertype.toRegularClass(context.session) ?: continue val classSymbol = supertype.toRegularClassSymbol(context.session) ?: continue
val superIsInterface = clazz.classKind == ClassKind.INTERFACE val superIsInterface = classSymbol.classKind == ClassKind.INTERFACE
if (superIsInterface != isInterface) { if (superIsInterface != isInterface) {
continue continue
} }
val restricting = supertype.findVisibilityExposure(context, classVisibility) val (restricting, restrictingVisibility) = supertype.findVisibilityExposure(context, classVisibility) ?: continue
if (restricting != null) { reporter.reportOn(
reporter.reportOn( supertypeRef.source ?: declaration.source,
supertypeRef.source ?: declaration.source, if (isInterface) FirErrors.EXPOSED_SUPER_INTERFACE else FirErrors.EXPOSED_SUPER_CLASS,
if (isInterface) FirErrors.EXPOSED_SUPER_INTERFACE else FirErrors.EXPOSED_SUPER_CLASS, classVisibility,
classVisibility, restricting,
restricting, restrictingVisibility,
restricting.effectiveVisibility, context
context )
)
}
} }
} }
@@ -72,18 +73,16 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
if (classVisibility == EffectiveVisibility.Local) return if (classVisibility == EffectiveVisibility.Local) return
for (parameter in declaration.typeParameters) { for (parameter in declaration.typeParameters) {
for (bound in parameter.symbol.fir.bounds) { for (bound in parameter.symbol.resolvedBounds) {
val restricting = bound.coneType.findVisibilityExposure(context, classVisibility) val (restricting, restrictingVisibility) = bound.coneType.findVisibilityExposure(context, classVisibility) ?: continue
if (restricting != null) { reporter.reportOn(
reporter.reportOn( bound.source,
bound.source, FirErrors.EXPOSED_TYPE_PARAMETER_BOUND,
FirErrors.EXPOSED_TYPE_PARAMETER_BOUND, classVisibility,
classVisibility, restricting,
restricting, restrictingVisibility,
restricting.effectiveVisibility, context
context )
)
}
} }
} }
} }
@@ -93,17 +92,15 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
val typeAliasVisibility = declaration.effectiveVisibility val typeAliasVisibility = declaration.effectiveVisibility
if (typeAliasVisibility == EffectiveVisibility.Local) return if (typeAliasVisibility == EffectiveVisibility.Local) return
val restricting = expandedType?.findVisibilityExposure(context, typeAliasVisibility) val (restricting, restrictingVisibility) = expandedType?.findVisibilityExposure(context, typeAliasVisibility) ?: return
if (restricting != null) { reporter.reportOn(
reporter.reportOn( declaration.source,
declaration.source, FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE,
FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE, typeAliasVisibility,
typeAliasVisibility, restricting,
restricting, restrictingVisibility,
restricting.effectiveVisibility, context
context )
)
}
} }
private fun checkFunction(declaration: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) { private fun checkFunction(declaration: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) {
@@ -111,34 +108,30 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
if (functionVisibility == EffectiveVisibility.Local) return if (functionVisibility == EffectiveVisibility.Local) return
if (declaration !is FirConstructor && declaration !is FirPropertyAccessor) { if (declaration !is FirConstructor && declaration !is FirPropertyAccessor) {
val restricting = declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>() declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.findVisibilityExposure(context, functionVisibility) ?.findVisibilityExposure(context, functionVisibility)?.let { (restricting, restrictingVisibility) ->
if (restricting != null) {
reporter.reportOn(
declaration.source,
FirErrors.EXPOSED_FUNCTION_RETURN_TYPE,
functionVisibility,
restricting,
restricting.effectiveVisibility,
context
)
}
}
declaration.valueParameters.forEachIndexed { i, valueParameter ->
if (i < declaration.valueParameters.size) {
val restricting =
valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.findVisibilityExposure(context, functionVisibility)
if (restricting != null) {
reporter.reportOn( reporter.reportOn(
valueParameter.source, declaration.source,
FirErrors.EXPOSED_PARAMETER_TYPE, FirErrors.EXPOSED_FUNCTION_RETURN_TYPE,
functionVisibility, functionVisibility,
restricting, restricting,
restricting.effectiveVisibility, restrictingVisibility,
context context
) )
} }
}
declaration.valueParameters.forEachIndexed { i, valueParameter ->
if (i < declaration.valueParameters.size) {
val (restricting, restrictingVisibility) = valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.findVisibilityExposure(context, functionVisibility) ?: return@forEachIndexed
reporter.reportOn(
valueParameter.source,
FirErrors.EXPOSED_PARAMETER_TYPE,
functionVisibility,
restricting,
restrictingVisibility,
context
)
} }
} }
checkMemberReceiver(declaration.receiverTypeRef, declaration as? FirCallableDeclaration, reporter, context) checkMemberReceiver(declaration.receiverTypeRef, declaration as? FirCallableDeclaration, reporter, context)
@@ -149,24 +142,22 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
val propertyVisibility = declaration.effectiveVisibility val propertyVisibility = declaration.effectiveVisibility
if (propertyVisibility == EffectiveVisibility.Local) return if (propertyVisibility == EffectiveVisibility.Local) return
val restricting = declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()
declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?.findVisibilityExposure(context, propertyVisibility)?.let { (restricting, restrictingVisibility) ->
?.findVisibilityExposure(context, propertyVisibility) val diagnostic = if (declaration.fromPrimaryConstructor == true) {
if (restricting != null) { FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR
val diagnostic = if (declaration.fromPrimaryConstructor == true) { } else {
FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR FirErrors.EXPOSED_PROPERTY_TYPE
} else { }
FirErrors.EXPOSED_PROPERTY_TYPE reporter.reportOn(
declaration.source,
diagnostic,
propertyVisibility,
restricting,
restrictingVisibility,
context
)
} }
reporter.reportOn(
declaration.source,
diagnostic,
propertyVisibility,
restricting,
restricting.effectiveVisibility,
context
)
}
checkMemberReceiver(declaration.receiverTypeRef, declaration, reporter, context) checkMemberReceiver(declaration.receiverTypeRef, declaration, reporter, context)
} }
@@ -181,35 +172,34 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
val memberVisibility = memberDeclaration.effectiveVisibility val memberVisibility = memberDeclaration.effectiveVisibility
if (memberVisibility == EffectiveVisibility.Local) return if (memberVisibility == EffectiveVisibility.Local) return
val restricting = receiverParameterType.findVisibilityExposure(context, memberVisibility) val (restricting, restrictingVisibility) = receiverParameterType.findVisibilityExposure(context, memberVisibility) ?: return
if (restricting != null) { reporter.reportOn(
reporter.reportOn( typeRef.source,
typeRef.source, FirErrors.EXPOSED_RECEIVER_TYPE,
FirErrors.EXPOSED_RECEIVER_TYPE, memberVisibility,
memberVisibility, restricting,
restricting, restrictingVisibility,
restricting.effectiveVisibility, context
context )
)
}
} }
private fun ConeKotlinType.findVisibilityExposure( private fun ConeKotlinType.findVisibilityExposure(
context: CheckerContext, context: CheckerContext,
base: EffectiveVisibility base: EffectiveVisibility
): FirMemberDeclaration? { ): Pair<FirBasedSymbol<*>, EffectiveVisibility>? {
val type = this as? ConeClassLikeType ?: return null val type = this as? ConeClassLikeType ?: return null
val fir = type.fullyExpandedType(context.session).lookupTag.toSymbol(context.session)?.let { firSymbol -> val classSymbol = type.fullyExpandedType(context.session).lookupTag.toSymbol(context.session) ?: return null
firSymbol.ensureResolved(FirResolvePhase.DECLARATIONS)
firSymbol.fir
} ?: return null
if (fir is FirMemberDeclaration) { val effectiveVisibility = when (classSymbol) {
val effectiveVisibility = fir.effectiveVisibility is FirRegularClassSymbol -> classSymbol.effectiveVisibility
is FirTypeAliasSymbol -> classSymbol.effectiveVisibility
else -> null
}
if (effectiveVisibility != null) {
when (effectiveVisibility.relation(base, context.session.typeContext)) { when (effectiveVisibility.relation(base, context.session.typeContext)) {
EffectiveVisibility.Permissiveness.LESS, EffectiveVisibility.Permissiveness.LESS,
EffectiveVisibility.Permissiveness.UNKNOWN -> { EffectiveVisibility.Permissiveness.UNKNOWN -> {
return fir return classSymbol to effectiveVisibility
} }
else -> { else -> {
} }
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.scopes.getFunctions import org.jetbrains.kotlin.fir.scopes.getFunctions
import org.jetbrains.kotlin.fir.scopes.getProperties import org.jetbrains.kotlin.fir.scopes.getProperties
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() { object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
@@ -33,16 +35,16 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
val scope = declaration.unsubstitutedScope(context) val scope = declaration.unsubstitutedScope(context)
val classSymbol = declaration.symbol val classSymbol = declaration.symbol
var abstractFunction: FirSimpleFunction? = null var abstractFunctionSymbol: FirNamedFunctionSymbol? = null
for (name in scope.getCallableNames()) { for (name in scope.getCallableNames()) {
val functions = scope.getFunctions(name) val functions = scope.getFunctions(name)
val properties = scope.getProperties(name) val properties = scope.getProperties(name)
for (function in functions) { for (function in functions) {
if (function.fir.isAbstract) { if (function.isAbstract) {
if (abstractFunction == null) { if (abstractFunctionSymbol == null) {
abstractFunction = function.fir abstractFunctionSymbol = function
} else { } else {
reporter.reportOn(declaration.source, FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS, context) reporter.reportOn(declaration.source, FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS, context)
} }
@@ -50,10 +52,10 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
} }
for (property in properties) { for (property in properties) {
val firProperty = property.fir as? FirProperty ?: continue val firProperty = property as? FirPropertySymbol ?: continue
if (firProperty.isAbstract) { if (firProperty.isAbstract) {
val source = val source =
if (firProperty.getContainingClassSymbol(context) != classSymbol) if (firProperty.getContainingClassSymbol(context.session) != classSymbol)
declaration.source declaration.source
else else
firProperty.source firProperty.source
@@ -63,33 +65,33 @@ object FirFunInterfaceDeclarationChecker : FirRegularClassChecker() {
} }
} }
if (abstractFunction == null) { if (abstractFunctionSymbol == null) {
reporter.reportOn(declaration.source, FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS, context) reporter.reportOn(declaration.source, FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS, context)
return return
} }
val inFunInterface = abstractFunction.getContainingClassSymbol(context) === classSymbol val inFunInterface = abstractFunctionSymbol.getContainingClassSymbol(context.session) === classSymbol
when { when {
abstractFunction.typeParameters.isNotEmpty() -> abstractFunctionSymbol.typeParameterSymbols.isNotEmpty() ->
reporter.reportOn( reporter.reportOn(
if (inFunInterface) abstractFunction.source else declaration.source, if (inFunInterface) abstractFunctionSymbol.source else declaration.source,
FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS, FUN_INTERFACE_ABSTRACT_METHOD_WITH_TYPE_PARAMETERS,
context context
) )
abstractFunction.isSuspend -> abstractFunctionSymbol.isSuspend ->
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.SuspendFunctionsInFunInterfaces)) { if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.SuspendFunctionsInFunInterfaces)) {
reporter.reportOn( reporter.reportOn(
if (inFunInterface) abstractFunction.source else declaration.source, if (inFunInterface) abstractFunctionSymbol.source else declaration.source,
FUN_INTERFACE_WITH_SUSPEND_FUNCTION, FUN_INTERFACE_WITH_SUSPEND_FUNCTION,
context context
) )
} }
} }
abstractFunction.valueParameters.forEach { abstractFunctionSymbol.valueParameterSymbols.forEach {
if (it.defaultValue != null) { if (it.hasDefaultValue) {
reporter.reportOn( reporter.reportOn(
if (inFunInterface) it.source else declaration.source, if (inFunInterface) it.source else declaration.source,
FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE, FUN_INTERFACE_ABSTRACT_METHOD_WITH_DEFAULT_VALUE,
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirRealSourceElementKind import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isInline import org.jetbrains.kotlin.fir.analysis.checkers.isInlineClass
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.arrayElementType import org.jetbrains.kotlin.fir.types.arrayElementType
@@ -70,7 +71,7 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
for (varargParameter in varargParameters) { for (varargParameter in varargParameters) {
val varargParameterType = varargParameter.returnTypeRef.coneType.arrayElementType() ?: continue val varargParameterType = varargParameter.returnTypeRef.coneType.arrayElementType() ?: continue
if (AbstractTypeChecker.isSubtypeOf(context.session.typeContext, varargParameterType, nullableNothingType) || if (AbstractTypeChecker.isSubtypeOf(context.session.typeContext, varargParameterType, nullableNothingType) ||
(varargParameterType.isInline(context.session) && !varargParameterType.isUnsignedTypeOrNullableUnsignedType) (varargParameterType.isInlineClass(context.session) && !varargParameterType.isUnsignedTypeOrNullableUnsignedType)
// Note: comparing with FE1.0, we skip checking if the type is not primitive because primitive types are not inline. That // Note: comparing with FE1.0, we skip checking if the type is not primitive because primitive types are not inline. That
// is any primitive values are already allowed by the inline check. // is any primitive values are already allowed by the inline check.
) { ) {
@@ -95,6 +96,8 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) { override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
val namedReference = qualifiedAccessExpression.calleeReference as? FirResolvedNamedReference ?: return val namedReference = qualifiedAccessExpression.calleeReference as? FirResolvedNamedReference ?: return
@OptIn(SymbolInternals::class)
val referredParameter = namedReference.resolvedSymbol.fir as? FirValueParameter ?: return val referredParameter = namedReference.resolvedSymbol.fir as? FirValueParameter ?: return
val referredParameterIndex = function.valueParameters.indexOf(referredParameter) val referredParameterIndex = function.valueParameters.indexOf(referredParameter)
// Skip if the referred parameter is not declared in the same function. // Skip if the referred parameter is not declared in the same function.
@@ -69,9 +69,9 @@ object FirImplementationMismatchChecker : FirClassChecker() {
symbol: FirCallableSymbol<*>, symbol: FirCallableSymbol<*>,
classScope: FirTypeScope classScope: FirTypeScope
) { ) {
fun reportTypeMismatch(member1: FirCallableDeclaration, member2: FirCallableDeclaration, isDelegation: Boolean) { fun reportTypeMismatch(member1: FirCallableSymbol<*>, member2: FirCallableSymbol<*>, isDelegation: Boolean) {
val error = when { val error = when {
member1 is FirProperty && member2 is FirProperty -> { member1 is FirPropertySymbol && member2 is FirPropertySymbol -> {
if (member1.isVar || member2.isVar) { if (member1.isVar || member2.isVar) {
FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE
} else { } else {
@@ -88,13 +88,13 @@ object FirImplementationMismatchChecker : FirClassChecker() {
} }
fun canOverride( fun canOverride(
inheritedMember: FirCallableDeclaration, inheritedMember: FirCallableSymbol<*>,
inheritedType: ConeKotlinType, inheritedType: ConeKotlinType,
baseMember: FirCallableDeclaration, baseMember: FirCallableSymbol<*>,
baseType: ConeKotlinType baseType: ConeKotlinType
): Boolean { ): Boolean {
val inheritedTypeSubstituted = inheritedType.substituteTypeParameters(inheritedMember, baseMember, context) val inheritedTypeSubstituted = inheritedType.substituteTypeParameters(inheritedMember, baseMember, context)
return if (baseMember is FirProperty && baseMember.isVar) return if (baseMember is FirPropertySymbol && baseMember.isVar)
AbstractTypeChecker.equalTypes(typeCheckerContext, inheritedTypeSubstituted, baseType) AbstractTypeChecker.equalTypes(typeCheckerContext, inheritedTypeSubstituted, baseType)
else else
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedTypeSubstituted, baseType) AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedTypeSubstituted, baseType)
@@ -102,8 +102,8 @@ object FirImplementationMismatchChecker : FirClassChecker() {
val intersectionSymbols = when { val intersectionSymbols = when {
//substitution override means simple materialization of single method, so nothing to check //substitution override means simple materialization of single method, so nothing to check
symbol.fir.isSubstitutionOverride -> return symbol.isSubstitutionOverride -> return
symbol.fir.delegatedWrapperData != null -> { symbol.delegatedWrapperData != null -> {
val allOverridden = classScope.getDirectOverriddenMembers(symbol) val allOverridden = classScope.getDirectOverriddenMembers(symbol)
//if there is intersection override - take its intersections - they will contain all substitutions //if there is intersection override - take its intersections - they will contain all substitutions
//otherwise we get base members with unsubstituted params too //otherwise we get base members with unsubstituted params too
@@ -119,26 +119,25 @@ object FirImplementationMismatchChecker : FirClassChecker() {
} }
val withTypes = intersectionSymbols.map { val withTypes = intersectionSymbols.map {
it.fir to context.returnTypeCalculator.tryCalculateReturnType(it.fir).coneType it to context.returnTypeCalculator.tryCalculateReturnType(it).coneType
} }
if (withTypes.any { it.second is ConeKotlinErrorType }) return if (withTypes.any { it.second is ConeKotlinErrorType }) return
var delegation: FirCallableDeclaration? = null var delegation: FirCallableSymbol<*>? = null
val implementations = mutableListOf<FirCallableDeclaration>() val implementations = mutableListOf<FirCallableSymbol<*>>()
for (intSymbol in intersectionSymbols) { for (intSymbol in intersectionSymbols) {
val fir = intSymbol.fir if (intSymbol.delegatedWrapperData?.containingClass?.classId == containingClass.classId) {
if (fir.delegatedWrapperData?.containingClass?.classId == containingClass.classId) { delegation = intSymbol
delegation = fir
break break
} }
if (!(fir as FirCallableMemberDeclaration).isAbstract) { if (!intSymbol.isAbstract) {
implementations.add(fir) implementations.add(intSymbol)
} }
} }
var someClash: Pair<FirCallableDeclaration, FirCallableDeclaration>? = null var someClash: Pair<FirCallableSymbol<*>, FirCallableSymbol<*>>? = null
val compatible = withTypes.any { (m1, type1) -> val compatible = withTypes.any { (m1, type1) ->
withTypes.all { (m2, type2) -> withTypes.all { (m2, type2) ->
val result = canOverride(m1, type1, m2, type2) val result = canOverride(m1, type1, m2, type2)
@@ -172,15 +171,15 @@ object FirImplementationMismatchChecker : FirClassChecker() {
symbol: FirVariableSymbol<*>, symbol: FirVariableSymbol<*>,
classScope: FirTypeScope classScope: FirTypeScope
) { ) {
if (symbol !is FirPropertySymbol || symbol.fir.isVar) return if (symbol !is FirPropertySymbol || symbol.isVar) return
if (symbol.fir.delegatedWrapperData == null) return if (symbol.delegatedWrapperData == null) return
val overriddenVar = val overriddenVar =
classScope.getDirectOverriddenProperties(symbol, true) classScope.getDirectOverriddenProperties(symbol, true)
.find { it.fir.isVar } .find { it.isVar }
?: return ?: return
reporter.reportOn(containingClass.source, FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, symbol.fir, overriddenVar.fir, context) reporter.reportOn(containingClass.source, FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, symbol, overriddenVar, context)
} }
private fun checkConflictingMembers( private fun checkConflictingMembers(
@@ -190,23 +189,23 @@ object FirImplementationMismatchChecker : FirClassChecker() {
scope: FirTypeScope, scope: FirTypeScope,
name: Name name: Name
) { ) {
val allFunctions = mutableListOf<FirSimpleFunction>() val allFunctions = mutableListOf<FirNamedFunctionSymbol>()
scope.processFunctionsByName(name) { sym -> scope.processFunctionsByName(name) { sym ->
val declaredInThisClass = sym.callableId.classId == containingClass.classId val declaredInThisClass = sym.callableId.classId == containingClass.classId
when { when {
sym is FirIntersectionOverrideFunctionSymbol && declaredInThisClass -> sym is FirIntersectionOverrideFunctionSymbol && declaredInThisClass ->
sym.intersections.mapNotNullTo(allFunctions) { (it as? FirNamedFunctionSymbol)?.fir } sym.intersections.mapNotNullTo(allFunctions) { it as? FirNamedFunctionSymbol }
!declaredInThisClass -> allFunctions.add(sym.fir) !declaredInThisClass -> allFunctions.add(sym)
} }
} }
val sameArgumentGroups = allFunctions.groupBy { function -> val sameArgumentGroups = allFunctions.groupBy { function ->
function.valueParameters.map { it.returnTypeRef.coneType } function.valueParameterSymbols.map { it.resolvedReturnTypeRef.coneType }
}.values }.values
val clashes = sameArgumentGroups.mapNotNull { fs -> val clashes = sameArgumentGroups.mapNotNull { fs ->
fs.zipWithNext().find { (m1, m2) -> fs.zipWithNext().find { (m1, m2) ->
m1.isSuspend != m2.isSuspend || m1.typeParameters.size != m2.typeParameters.size m1.isSuspend != m2.isSuspend || m1.typeParameterSymbols.size != m2.typeParameterSymbols.size
} }
} }
@@ -216,17 +215,17 @@ object FirImplementationMismatchChecker : FirClassChecker() {
} }
private fun ConeKotlinType.substituteTypeParameters( private fun ConeKotlinType.substituteTypeParameters(
fromDeclaration: FirCallableDeclaration, fromDeclaration: FirCallableSymbol<*>,
toDeclaration: FirCallableDeclaration, toDeclaration: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
): ConeKotlinType { ): ConeKotlinType {
val fromParams = (fromDeclaration as? FirTypeParametersOwner)?.typeParameters ?: return this val fromParams = fromDeclaration.typeParameterSymbols
val toParams = (toDeclaration as? FirTypeParametersOwner)?.typeParameters ?: return this val toParams = toDeclaration.typeParameterSymbols
val substitutionMap = fromParams.zip(toParams) { from, to -> val substitutionMap = fromParams.zip(toParams) { from, to ->
from.symbol to to.toConeType() from to to.toConeType()
}.toMap() }.toMap()
return substitutorByMap(substitutionMap, context.session).substituteOrSelf(this) return substitutorByMap(substitutionMap, context.session).substituteOrSelf(this)
} }
} }
@@ -5,17 +5,18 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.collectEnumEntries
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.followAllAlias import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.declarations.utils.isOperator import org.jetbrains.kotlin.fir.declarations.utils.isOperator
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.symbols.impl.isStatic import org.jetbrains.kotlin.fir.symbols.impl.isStatic
@@ -44,9 +45,9 @@ object FirImportsChecker : FirFileChecker() {
val fqName = import.importedFqName ?: return val fqName = import.importedFqName ?: return
if (fqName.isRoot || fqName.parent().isRoot) return if (fqName.isRoot || fqName.parent().isRoot) return
val classId = ClassId.topLevel(fqName.parent()) val classId = ClassId.topLevel(fqName.parent())
val classFir = classId.resolveToClass(context) ?: return val classSymbol = classId.resolveToClass(context) ?: return
if (classFir.isEnumClass && classFir.collectEnumEntries().any { it.name == fqName.shortName() }) { if (classSymbol.isEnumClass && classSymbol.collectEnumEntries().any { it.callableId.callableName == fqName.shortName() }) {
reporter.reportOn(import.source, FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON, classFir.name, context) reporter.reportOn(import.source, FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON, classSymbol.classId.shortClassName, context)
} }
} }
@@ -58,10 +59,10 @@ object FirImportsChecker : FirFileChecker() {
val classId = (import as? FirResolvedImport)?.resolvedClassId val classId = (import as? FirResolvedImport)?.resolvedClassId
if (classId != null) { if (classId != null) {
val classFir = classId.resolveToClass(context) ?: return val classSymbol = classId.resolveToClass(context) ?: return
if (classFir.classKind.isSingleton) return if (classSymbol.classKind.isSingleton) return
if (!classFir.canBeImported(context, importedName)) { if (!classSymbol.canBeImported(context, importedName)) {
reporter.reportOn(import.source, FirErrors.CANNOT_BE_IMPORTED, importedName, context) reporter.reportOn(import.source, FirErrors.CANNOT_BE_IMPORTED, importedName, context)
} }
} else { } else {
@@ -106,7 +107,7 @@ object FirImportsChecker : FirFileChecker() {
classFir.classKind.isSingleton && classFir.hasFunction(context, importedName) { it.isOperator } classFir.classKind.isSingleton && classFir.hasFunction(context, importedName) { it.isOperator }
} else { } else {
context.session.symbolProvider.getTopLevelFunctionSymbols(import.packageFqName, importedName).any { context.session.symbolProvider.getTopLevelFunctionSymbols(import.packageFqName, importedName).any {
it.fir.isOperator it.isOperator
} }
} }
if (illegalRename) { if (illegalRename) {
@@ -130,26 +131,30 @@ object FirImportsChecker : FirFileChecker() {
} }
} }
private fun ClassId.resolveToClass(context: CheckerContext): FirRegularClass? { private fun ClassId.resolveToClass(context: CheckerContext): FirRegularClassSymbol? {
val classSymbol = context.session.symbolProvider.getClassLikeSymbolByFqName(this) ?: return null val classSymbol = context.session.symbolProvider.getClassLikeSymbolByFqName(this) ?: return null
return when (classSymbol) { return when (classSymbol) {
is FirRegularClassSymbol -> classSymbol.fir is FirRegularClassSymbol -> classSymbol
is FirTypeAliasSymbol -> classSymbol.fir.followAllAlias(context.session) as? FirRegularClass is FirTypeAliasSymbol -> classSymbol.fullyExpandedClass(context.session)
else -> null else -> null
} }
} }
private fun FirRegularClass.hasFunction(context: CheckerContext, name: Name, predicate: (FirSimpleFunction) -> Boolean): Boolean { private fun FirRegularClassSymbol.hasFunction(
context: CheckerContext,
name: Name,
predicate: (FirNamedFunctionSymbol) -> Boolean
): Boolean {
var result = false var result = false
context.session.declaredMemberScope(this).processFunctionsByName(name) { sym -> context.session.declaredMemberScope(this).processFunctionsByName(name) { sym ->
if (!result) { if (!result) {
result = predicate(sym.fir) result = predicate(sym)
} }
} }
return result return result
} }
private fun FirRegularClass.canBeImported( private fun FirRegularClassSymbol.canBeImported(
context: CheckerContext, context: CheckerContext,
name: Name name: Name
): Boolean { ): Boolean {
@@ -50,7 +50,7 @@ object FirInapplicableLateinitChecker : FirPropertyChecker() {
} }
private fun FirProperty.isNullable() = when (val type = returnTypeRef.coneType) { private fun FirProperty.isNullable() = when (val type = returnTypeRef.coneType) {
is ConeTypeParameterType -> type.isNullable || type.lookupTag.typeParameterSymbol.fir.bounds.any { it.coneType.isNullable } is ConeTypeParameterType -> type.isNullable || type.lookupTag.typeParameterSymbol.resolvedBounds.any { it.coneType.isNullable }
else -> type.isNullable else -> type.isNullable
} }
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.resolve.calls.isPotentiallyArray import org.jetbrains.kotlin.fir.resolve.calls.isPotentiallyArray
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -47,7 +48,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
} }
for (supertypeEntry in declaration.superTypeRefs) { for (supertypeEntry in declaration.superTypeRefs) {
if (supertypeEntry.toRegularClass(context.session)?.isInterface != true) { if (supertypeEntry.toRegularClassSymbol(context.session)?.isInterface != true) {
reporter.reportOnWithSuppression(supertypeEntry, FirErrors.INLINE_CLASS_CANNOT_EXTEND_CLASSES, context) reporter.reportOnWithSuppression(supertypeEntry, FirErrors.INLINE_CLASS_CANNOT_EXTEND_CLASSES, context)
} }
} }
@@ -200,16 +201,18 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
private fun ConeKotlinType.isRecursiveInlineClassType(visited: HashSet<ConeKotlinType>, session: FirSession): Boolean { private fun ConeKotlinType.isRecursiveInlineClassType(visited: HashSet<ConeKotlinType>, session: FirSession): Boolean {
if (!visited.add(this)) return true if (!visited.add(this)) return true
val asRegularClass = this.toRegularClass(session) ?: return false val asRegularClass = this.toRegularClassSymbol(session) ?: return false
return asRegularClass.isInlineOrValueClass() && if (!asRegularClass.isInlineOrValueClass()) return false
asRegularClass.primaryConstructor val primaryConstructor = asRegularClass.declarationSymbols
?.takeIf { it.source?.kind is FirRealSourceElementKind } .firstOrNull { it is FirConstructorSymbol && it.isPrimary } as FirConstructorSymbol?
?.valueParameters ?: return false
?.firstOrNull() return primaryConstructor
?.returnTypeRef .valueParameterSymbols
?.coneType .firstOrNull()
?.isRecursiveInlineClassType(visited, session) == true ?.resolvedReturnTypeRef
?.coneType
?.isRecursiveInlineClassType(visited, session) == true
} }
private fun FirRegularClass.isSubtypeOfCloneable(session: FirSession): Boolean { private fun FirRegularClass.isSubtypeOfCloneable(session: FirSession): Boolean {
@@ -26,9 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibility import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibility
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isMarkedNullable import org.jetbrains.kotlin.fir.types.isMarkedNullable
import org.jetbrains.kotlin.fir.types.toSymbol import org.jetbrains.kotlin.fir.types.toSymbol
@@ -53,16 +51,16 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val body = function.body ?: return val body = function.body ?: return
val inlinableParameters = function.valueParameters.filter { val inalienableParameters = function.valueParameters.filter {
if (it.isNoinline) return@filter false if (it.isNoinline) return@filter false
val type = it.returnTypeRef.coneType val type = it.returnTypeRef.coneType
!type.isMarkedNullable && type.isFunctionalType(context.session) { kind -> !kind.isReflectType } !type.isMarkedNullable && type.isFunctionalType(context.session) { kind -> !kind.isReflectType }
} }.map { it.symbol }
val visitor = Visitor( val visitor = Visitor(
function, function,
effectiveVisibility, effectiveVisibility,
inlinableParameters, inalienableParameters,
context.session, context.session,
reporter reporter
) )
@@ -72,7 +70,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
private class Visitor( private class Visitor(
val inlineFunction: FirFunction, val inlineFunction: FirFunction,
val inlineFunEffectiveVisibility: EffectiveVisibility, val inlineFunEffectiveVisibility: EffectiveVisibility,
val inlinableParameters: List<FirValueParameter>, val inalienableParameters: List<FirValueParameterSymbol>,
val session: FirSession, val session: FirSession,
val reporter: DiagnosticReporter val reporter: DiagnosticReporter
) : FirDefaultVisitor<Unit, CheckerContext>() { ) : FirDefaultVisitor<Unit, CheckerContext>() {
@@ -100,7 +98,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: CheckerContext) { override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: CheckerContext) {
val propertySymbol = variableAssignment.calleeReference.toResolvedCallableSymbol() as? FirPropertySymbol ?: return val propertySymbol = variableAssignment.calleeReference.toResolvedCallableSymbol() as? FirPropertySymbol ?: return
val setterSymbol = propertySymbol.fir.setter?.symbol ?: return val setterSymbol = propertySymbol.setterSymbol ?: return
checkQualifiedAccess(variableAssignment, setterSymbol, data) checkQualifiedAccess(variableAssignment, setterSymbol, data)
} }
@@ -118,16 +116,16 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
targetSymbol: FirBasedSymbol<*>?, targetSymbol: FirBasedSymbol<*>?,
context: CheckerContext context: CheckerContext
) { ) {
val calledFunction = (targetSymbol as? FirNamedFunctionSymbol)?.fir ?: return val calledFunctionSymbol = targetSymbol as? FirNamedFunctionSymbol ?: return
val argumentMapping = functionCall.resolvedArgumentMapping ?: return val argumentMapping = functionCall.resolvedArgumentMapping ?: return
for ((wrappedArgument, valueParameter) in argumentMapping) { for ((wrappedArgument, valueParameter) in argumentMapping) {
val argument = wrappedArgument.unwrapArgument() val argument = wrappedArgument.unwrapArgument()
val resolvedArgumentSymbol = argument.toResolvedCallableSymbol() as? FirVariableSymbol<*> ?: continue val resolvedArgumentSymbol = argument.toResolvedCallableSymbol() as? FirVariableSymbol<*> ?: continue
val valueParameterOfOriginalInlineFunction = inlinableParameters.firstOrNull { it == resolvedArgumentSymbol.fir } val valueParameterOfOriginalInlineFunction = inalienableParameters.firstOrNull { it == resolvedArgumentSymbol }
if (valueParameterOfOriginalInlineFunction != null) { if (valueParameterOfOriginalInlineFunction != null) {
val factory = when { val factory = when {
calledFunction.isInline -> when { calledFunctionSymbol.isInline -> when {
valueParameter.isNoinline -> FirErrors.USAGE_IS_NOT_INLINABLE valueParameter.isNoinline -> FirErrors.USAGE_IS_NOT_INLINABLE
valueParameter.isCrossinline && !valueParameterOfOriginalInlineFunction.isCrossinline valueParameter.isCrossinline && !valueParameterOfOriginalInlineFunction.isCrossinline
-> FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED -> FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED
@@ -135,7 +133,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
} }
else -> FirErrors.USAGE_IS_NOT_INLINABLE else -> FirErrors.USAGE_IS_NOT_INLINABLE
} }
reporter.reportOn(argument.source, factory, valueParameterOfOriginalInlineFunction.symbol, context) reporter.reportOn(argument.source, factory, valueParameterOfOriginalInlineFunction, context)
} }
} }
} }
@@ -147,13 +145,12 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
context: CheckerContext context: CheckerContext
) { ) {
val receiverSymbol = receiverExpression.toResolvedCallableSymbol() ?: return val receiverSymbol = receiverExpression.toResolvedCallableSymbol() ?: return
if (receiverSymbol.fir in inlinableParameters) { if (receiverSymbol in inalienableParameters) {
val valueParameter = receiverSymbol.fir as FirValueParameter
if (!isInvokeOrInlineExtension(targetSymbol)) { if (!isInvokeOrInlineExtension(targetSymbol)) {
reporter.reportOn( reporter.reportOn(
qualifiedAccessExpression.source, qualifiedAccessExpression.source,
FirErrors.USAGE_IS_NOT_INLINABLE, FirErrors.USAGE_IS_NOT_INLINABLE,
valueParameter.symbol, receiverSymbol,
context context
) )
} }
@@ -162,10 +159,9 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
private fun isInvokeOrInlineExtension(targetSymbol: FirBasedSymbol<*>?): Boolean { private fun isInvokeOrInlineExtension(targetSymbol: FirBasedSymbol<*>?): Boolean {
if (targetSymbol !is FirNamedFunctionSymbol) return false if (targetSymbol !is FirNamedFunctionSymbol) return false
val function = targetSymbol.fir if (targetSymbol.isInline) return true
if (function.isInline) return true return targetSymbol.name == OperatorNameConventions.INVOKE &&
return function.name == OperatorNameConventions.INVOKE && targetSymbol.dispatchReceiverType?.isBuiltinFunctionalType(session) == true
function.dispatchReceiverType?.isBuiltinFunctionalType(session) == true
} }
private fun checkQualifiedAccess( private fun checkQualifiedAccess(
@@ -174,16 +170,14 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
context: CheckerContext context: CheckerContext
) { ) {
val source = qualifiedAccess.source ?: return val source = qualifiedAccess.source ?: return
if (targetSymbol == null) return if (targetSymbol !is FirCallableSymbol<*>) return
val targetFir = targetSymbol.fir as? FirCallableDeclaration
if (targetSymbol.fir in inlinableParameters) { if (targetSymbol in inalienableParameters) {
if (!qualifiedAccess.partOfCall(context)) { if (!qualifiedAccess.partOfCall(context)) {
val valueParameter = targetSymbol.fir as FirValueParameter reporter.reportOn(source, FirErrors.USAGE_IS_NOT_INLINABLE, targetSymbol, context)
reporter.reportOn(source, FirErrors.USAGE_IS_NOT_INLINABLE, valueParameter.symbol, context)
} }
} }
checkVisibilityAndAccess(qualifiedAccess, targetFir, source, context) checkVisibilityAndAccess(qualifiedAccess, targetSymbol, source, context)
checkRecursion(targetSymbol, source, context) checkRecursion(targetSymbol, source, context)
} }
@@ -199,7 +193,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
private fun checkVisibilityAndAccess( private fun checkVisibilityAndAccess(
accessExpression: FirQualifiedAccess, accessExpression: FirQualifiedAccess,
calledDeclaration: FirCallableDeclaration?, calledDeclaration: FirCallableSymbol<*>?,
source: FirSourceElement, source: FirSourceElement,
context: CheckerContext context: CheckerContext
) { ) {
@@ -221,7 +215,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
reporter.reportOn( reporter.reportOn(
source, source,
FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE, FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE,
calledDeclaration.symbol, calledDeclaration,
inlineFunction.symbol, inlineFunction.symbol,
context context
) )
@@ -232,7 +226,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
} }
} }
val isConstructorCall = calledDeclaration is FirConstructor val isConstructorCall = calledDeclaration is FirConstructorSymbol
if ( if (
isInlineFunPublicOrPublishedApi && isInlineFunPublicOrPublishedApi &&
inlineFunEffectiveVisibility.toVisibility() !== Visibilities.Protected && inlineFunEffectiveVisibility.toVisibility() !== Visibilities.Protected &&
@@ -243,12 +237,12 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
prohibitProtectedCallFromInline -> FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR prohibitProtectedCallFromInline -> FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR
else -> FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE else -> FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE
} }
reporter.reportOn(source, factory, calledDeclaration.symbol, inlineFunction.symbol, context) reporter.reportOn(source, factory, calledDeclaration, inlineFunction.symbol, context)
} }
} }
private fun checkPrivateClassMemberAccess( private fun checkPrivateClassMemberAccess(
calledDeclaration: FirCallableDeclaration, calledDeclaration: FirCallableSymbol<*>,
source: FirSourceElement, source: FirSourceElement,
context: CheckerContext context: CheckerContext
) { ) {
@@ -257,7 +251,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
reporter.reportOn( reporter.reportOn(
source, source,
FirErrors.PRIVATE_CLASS_MEMBER_FROM_INLINE, FirErrors.PRIVATE_CLASS_MEMBER_FROM_INLINE,
calledDeclaration.symbol, calledDeclaration,
inlineFunction.symbol, inlineFunction.symbol,
context context
) )
@@ -266,7 +260,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
} }
private fun checkSuperCalls( private fun checkSuperCalls(
calledDeclaration: FirCallableDeclaration, calledDeclaration: FirCallableSymbol<*>,
callExpression: FirQualifiedAccess, callExpression: FirQualifiedAccess,
context: CheckerContext context: CheckerContext
) { ) {
@@ -278,7 +272,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
reporter.reportOn( reporter.reportOn(
callExpression.dispatchReceiver.source, callExpression.dispatchReceiver.source,
FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE, FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE,
calledDeclaration.symbol, calledDeclaration,
context context
) )
} }
@@ -286,12 +280,12 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
} }
private fun FirBasedSymbol<*>.isDefinedInInlineFunction(): Boolean { private fun FirBasedSymbol<*>.isDefinedInInlineFunction(): Boolean {
return when (val fir = this.fir) { return when (val symbol = this) {
is FirAnonymousFunction -> true is FirAnonymousFunctionSymbol -> true
is FirMemberDeclaration -> fir.isLocalMember is FirCallableSymbol<*> -> symbol.isLocalMember
is FirAnonymousObject -> true is FirAnonymousObjectSymbol -> true
is FirRegularClass -> fir.classId.isLocal is FirRegularClassSymbol -> symbol.classId.isLocal
else -> error("Unknown callable declaration type: ${fir.render()}") else -> error("Unknown callable declaration type: $symbol")
} }
} }
@@ -305,13 +299,13 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
} }
} }
private fun FirCallableDeclaration.isInsidePrivateClass(): Boolean { private fun FirCallableSymbol<*>.isInsidePrivateClass(): Boolean {
val containingClass = this.containingClass()?.toSymbol(session)?.fir ?: return false val containingClassSymbol = this.containingClass()?.toSymbol(session) ?: return false
val containingClassVisibility = when (containingClass) { val containingClassVisibility = when (containingClassSymbol) {
is FirAnonymousObject -> return false is FirAnonymousObjectSymbol -> return false
is FirRegularClass -> containingClass.visibility is FirRegularClassSymbol -> containingClassSymbol.visibility
is FirTypeAlias -> containingClass.visibility is FirTypeAliasSymbol -> containingClassSymbol.visibility
} }
return containingClassVisibility == Visibilities.Private || containingClassVisibility == Visibilities.PrivateToThis return containingClassVisibility == Visibilities.Private || containingClassVisibility == Visibilities.PrivateToThis
} }
@@ -12,11 +12,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.inference.isKClassType import org.jetbrains.kotlin.fir.resolve.inference.isKClassType
import org.jetbrains.kotlin.fir.scopes.impl.toConeType import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
// See FE1.0 [KClassWithIncorrectTypeArgumentChecker] // See FE1.0 [KClassWithIncorrectTypeArgumentChecker]
@@ -45,7 +45,7 @@ object FirKClassWithIncorrectTypeArgumentChecker : FirFileChecker() {
val typeArgument = (returnType.typeArguments[0] as ConeKotlinTypeProjection).type val typeArgument = (returnType.typeArguments[0] as ConeKotlinTypeProjection).type
typeArgument.typeParameterFromError?.let { typeArgument.typeParameterFromError?.let {
reporter.reportOn(source, FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE, it.symbol, context) reporter.reportOn(source, FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE, it, context)
} }
} }
@@ -58,14 +58,14 @@ object FirKClassWithIncorrectTypeArgumentChecker : FirFileChecker() {
} }
} ?: return false } ?: return false
with(context) { with(context) {
argumentType.typeParameterFromError?.let { typeParameter -> argumentType.typeParameterFromError?.let { typeParameterSymbol ->
return typeParameter.toConeType().isNullableType() return typeParameterSymbol.toConeType().isNullableType()
} }
return argumentType is ConeKotlinErrorType || argumentType.isNullableType() return argumentType is ConeKotlinErrorType || argumentType.isNullableType()
} }
} }
private val ConeKotlinType.typeParameterFromError: FirTypeParameter? private val ConeKotlinType.typeParameterFromError: FirTypeParameterSymbol?
get() = ((this as? ConeKotlinErrorType)?.diagnostic as? ConeTypeParameterInQualifiedAccess)?.symbol?.fir get() = ((this as? ConeKotlinErrorType)?.diagnostic as? ConeTypeParameterInQualifiedAccess)?.symbol
} }
@@ -35,6 +35,7 @@ object FirMemberFunctionsChecker : FirClassChecker() {
) { ) {
val source = function.source ?: return val source = function.source ?: return
if (source.kind is FirFakeSourceElementKind) return if (source.kind is FirFakeSourceElementKind) return
val functionSymbol = function.symbol
// If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`. // If multiple (potentially conflicting) modality modifiers are specified, not all modifiers are recorded at `status`.
// So, our source of truth should be the full modifier list retrieved from the source. // So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = source.getModifierList() val modifierList = source.getModifierList()
@@ -45,13 +46,13 @@ object FirMemberFunctionsChecker : FirClassChecker() {
reporter.reportOn( reporter.reportOn(
source, source,
FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS,
function, functionSymbol,
containingDeclaration, containingDeclaration.symbol,
context context
) )
} }
if (function.hasBody) { if (function.hasBody) {
reporter.reportOn(source, FirErrors.ABSTRACT_FUNCTION_WITH_BODY, function, context) reporter.reportOn(source, FirErrors.ABSTRACT_FUNCTION_WITH_BODY, functionSymbol, context)
} }
} }
val isInsideExpectClass = isInsideExpectClass(containingDeclaration, context) val isInsideExpectClass = isInsideExpectClass(containingDeclaration, context)
@@ -59,13 +60,13 @@ object FirMemberFunctionsChecker : FirClassChecker() {
if (!function.hasBody) { if (!function.hasBody) {
if (containingDeclaration.isInterface) { if (containingDeclaration.isInterface) {
if (Visibilities.isPrivate(function.visibility)) { if (Visibilities.isPrivate(function.visibility)) {
reporter.reportOn(source, FirErrors.PRIVATE_FUNCTION_WITH_NO_BODY, function, context) reporter.reportOn(source, FirErrors.PRIVATE_FUNCTION_WITH_NO_BODY, functionSymbol, context)
} }
if (!isInsideExpectClass && !hasAbstractModifier && hasOpenModifier) { if (!isInsideExpectClass && !hasAbstractModifier && hasOpenModifier) {
reporter.reportOn(source, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, context) reporter.reportOn(source, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, context)
} }
} else if (!isInsideExpectClass && !hasAbstractModifier && !function.isExternal) { } else if (!isInsideExpectClass && !hasAbstractModifier && !function.isExternal) {
reporter.reportOn(source, FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, function, context) reporter.reportOn(source, FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, functionSymbol, context)
} }
} }
@@ -39,7 +39,7 @@ object FirMemberPropertiesChecker : FirClassChecker() {
mutableMapOf<FirPropertySymbol, EventOccurrencesRange>().withDefault { EventOccurrencesRange.ZERO } mutableMapOf<FirPropertySymbol, EventOccurrencesRange>().withDefault { EventOccurrencesRange.ZERO }
// If all member properties have its own initializer, we don't need to collect property initialization info at all. // If all member properties have its own initializer, we don't need to collect property initialization info at all.
if (memberPropertySymbols.any { it.fir.initializer == null }) { if (memberPropertySymbols.any { !it.hasInitializer }) {
collectPropertyInitialization(declaration, memberPropertySymbols, initializedInConstructor, initializedInInitOrOtherProperty) collectPropertyInitialization(declaration, memberPropertySymbols, initializedInConstructor, initializedInInitOrOtherProperty)
} }
@@ -137,7 +137,7 @@ object FirMemberPropertiesChecker : FirClassChecker() {
collectInfoFromGraph(graph, initializedInInitOrOtherProperty, EventOccurrencesRange::plus) collectInfoFromGraph(graph, initializedInInitOrOtherProperty, EventOccurrencesRange::plus)
} }
val propertyInitGraphs = memberPropertySymbols.mapNotNull { it.fir.controlFlowGraphReference?.controlFlowGraph } val propertyInitGraphs = memberPropertySymbols.mapNotNull { it.controlFlowGraphReference?.controlFlowGraph }
for (graph in propertyInitGraphs) { for (graph in propertyInitGraphs) {
collectInfoFromGraph(graph, initializedInInitOrOtherProperty, EventOccurrencesRange::plus) collectInfoFromGraph(graph, initializedInInitOrOtherProperty, EventOccurrencesRange::plus)
} }
@@ -187,8 +187,8 @@ object FirMemberPropertiesChecker : FirClassChecker() {
reporter.reportOn( reporter.reportOn(
it, it,
FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS,
property, property.symbol,
containingDeclaration, containingDeclaration.symbol,
context context
) )
return return
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.containingClass import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -48,6 +47,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
if (declaration is FirRegularClass && declaration.isExpect) return if (declaration is FirRegularClass && declaration.isExpect) return
val classKind = declaration.classKind val classKind = declaration.classKind
if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return
val classSymbol = declaration.symbol
val classScope = declaration.unsubstitutedScope(context) val classScope = declaration.unsubstitutedScope(context)
@@ -59,23 +59,21 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
val invisibleSymbols = mutableListOf<FirCallableSymbol<*>>() val invisibleSymbols = mutableListOf<FirCallableSymbol<*>>()
fun collectSymbol(symbol: FirCallableSymbol<*>) { fun collectSymbol(symbol: FirCallableSymbol<*>) {
val fir = symbol.fir val delegatedWrapperData = symbol.delegatedWrapperData
val delegatedWrapperData = fir.delegatedWrapperData
if (delegatedWrapperData != null) { if (delegatedWrapperData != null) {
val directOverriddenMembers = classScope.getDirectOverriddenMembers( val directOverriddenMembers = classScope.getDirectOverriddenMembers(
symbol, symbol,
unwrapIntersectionAndSubstitutionOverride = true unwrapIntersectionAndSubstitutionOverride = true
) )
val delegatedTo = delegatedWrapperData.wrapped.unwrapFakeOverrides() val delegatedTo = delegatedWrapperData.wrapped.unwrapFakeOverrides().symbol
if (symbol.fir.multipleDelegatesWithTheSameSignature == true) { if (symbol.multipleDelegatesWithTheSameSignature == true) {
manyImplementationsDelegationSymbols.add(symbol) manyImplementationsDelegationSymbols.add(symbol)
} }
val firstFinal = directOverriddenMembers.firstOrNull { it.fir.isFinal } val firstFinal = directOverriddenMembers.firstOrNull { it.isFinal }
val firstOpen = directOverriddenMembers.firstOrNull { it.fir.isOpen && delegatedTo != it.unwrapFakeOverrides().fir } val firstOpen = directOverriddenMembers.firstOrNull { it.isOpen && delegatedTo != it.unwrapFakeOverrides() }
when { when {
firstFinal != null -> firstFinal != null ->
@@ -87,10 +85,10 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
return return
} }
when (fir.getImplementationStatus(context.sessionHolder, declaration)) { when (symbol.getImplementationStatus(context.sessionHolder, classSymbol)) {
ImplementationStatus.AMBIGUOUSLY_INHERITED -> notImplementedIntersectionSymbols.add(symbol) ImplementationStatus.AMBIGUOUSLY_INHERITED -> notImplementedIntersectionSymbols.add(symbol)
ImplementationStatus.NOT_IMPLEMENTED -> when { ImplementationStatus.NOT_IMPLEMENTED -> when {
fir.isVisibleInClass(declaration) -> notImplementedSymbols.add(symbol) symbol.isVisibleInClass(classSymbol) -> notImplementedSymbols.add(symbol)
else -> invisibleSymbols.add(symbol) else -> invisibleSymbols.add(symbol)
} }
else -> { else -> {
@@ -105,32 +103,32 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
} }
if (!canHaveAbstractDeclarations && notImplementedSymbols.isNotEmpty()) { if (!canHaveAbstractDeclarations && notImplementedSymbols.isNotEmpty()) {
val notImplemented = notImplementedSymbols.first().unwrapFakeOverrides().fir val notImplemented = notImplementedSymbols.first().unwrapFakeOverrides()
if (notImplemented.isFromInterfaceOrEnum(context)) { if (notImplemented.isFromInterfaceOrEnum(context)) {
reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, declaration, notImplemented, context) reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
} else { } else {
reporter.reportOn(source, ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, declaration, notImplemented, context) reporter.reportOn(source, ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
} }
} }
if (!canHaveAbstractDeclarations && invisibleSymbols.isNotEmpty()) { if (!canHaveAbstractDeclarations && invisibleSymbols.isNotEmpty()) {
val invisible = invisibleSymbols.first().fir val invisible = invisibleSymbols.first()
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses)) { if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses)) {
reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER, declaration, invisible, context) reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER, classSymbol, invisible, context)
} else { } else {
reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING, declaration, invisible, context) reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING, classSymbol, invisible, context)
} }
} }
manyImplementationsDelegationSymbols.firstOrNull()?.let { manyImplementationsDelegationSymbols.firstOrNull()?.let {
reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, declaration, it.fir, context) reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, classSymbol, it, context)
} }
delegationOverrideOfFinal.firstOrNull()?.let { (delegated, final) -> delegationOverrideOfFinal.firstOrNull()?.let { (delegated, final) ->
reporter.reportOn( reporter.reportOn(
source, source,
OVERRIDING_FINAL_MEMBER_BY_DELEGATION, OVERRIDING_FINAL_MEMBER_BY_DELEGATION,
delegated.fir, delegated,
final.fir, final,
context context
) )
} }
@@ -139,33 +137,32 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
reporter.reportOn( reporter.reportOn(
source, source,
DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE, DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE,
delegated.fir, delegated,
open.fir, open,
context context
) )
} }
if (manyImplementationsDelegationSymbols.isEmpty() && notImplementedIntersectionSymbols.isNotEmpty()) { if (manyImplementationsDelegationSymbols.isEmpty() && notImplementedIntersectionSymbols.isNotEmpty()) {
val notImplementedIntersectionSymbol = notImplementedIntersectionSymbols.first() val notImplementedIntersectionSymbol = notImplementedIntersectionSymbols.first()
val notImplementedIntersection = notImplementedIntersectionSymbol.fir
val intersections = (notImplementedIntersectionSymbol as FirIntersectionCallableSymbol).intersections val intersections = (notImplementedIntersectionSymbol as FirIntersectionCallableSymbol).intersections
if (intersections.any { if (intersections.any {
(it.containingClass()?.toSymbol(context.session)?.fir as? FirRegularClass)?.classKind == ClassKind.CLASS (it.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS
} }
) { ) {
reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, declaration, notImplementedIntersection, context) reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplementedIntersectionSymbol, context)
} else { } else {
reporter.reportOn( reporter.reportOn(
source, source,
FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED,
declaration, classSymbol,
notImplementedIntersection, notImplementedIntersectionSymbol,
context context
) )
} }
} }
} }
private fun FirCallableDeclaration.isFromInterfaceOrEnum(context: CheckerContext): Boolean = private fun FirCallableSymbol<*>.isFromInterfaceOrEnum(context: CheckerContext): Boolean =
(getContainingClassSymbol(context) as? FirRegularClassSymbol)?.let { it.isInterface || it.isEnumClass } == true (getContainingClassSymbol(context.session) as? FirRegularClassSymbol)?.let { it.isInterface || it.isEnumClass } == true
} }
@@ -16,23 +16,25 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.overridesBackwardCompatibilityHelper import org.jetbrains.kotlin.fir.analysis.overridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.declarations.utils.isOverride import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
import org.jetbrains.kotlin.fir.scopes.impl.toConeType import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.upperBoundIfFlexible import org.jetbrains.kotlin.fir.types.upperBoundIfFlexible
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirOverrideChecker : FirClassChecker() { object FirOverrideChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -45,45 +47,45 @@ object FirOverrideChecker : FirClassChecker() {
for (it in declaration.declarations) { for (it in declaration.declarations) {
if (it is FirSimpleFunction || it is FirProperty) { if (it is FirSimpleFunction || it is FirProperty) {
checkMember(it as FirCallableDeclaration, declaration, reporter, typeCheckerContext, firTypeScope, context) checkMember((it as FirCallableDeclaration).symbol, declaration, reporter, typeCheckerContext, firTypeScope, context)
} }
} }
} }
private fun FirTypeScope.retrieveDirectOverriddenOf(member: FirCallableDeclaration): List<FirCallableSymbol<*>> { private fun FirTypeScope.retrieveDirectOverriddenOf(memberSymbol: FirCallableSymbol<*>): List<FirCallableSymbol<*>> {
return when (member) { return when (memberSymbol) {
is FirSimpleFunction -> { is FirNamedFunctionSymbol -> {
processFunctionsByName(member.name) {} processFunctionsByName(memberSymbol.name) {}
getDirectOverriddenFunctions(member.symbol) getDirectOverriddenFunctions(memberSymbol)
} }
is FirProperty -> { is FirPropertySymbol -> {
processPropertiesByName(member.name) {} processPropertiesByName(memberSymbol.name) {}
getDirectOverriddenProperties(member.symbol) getDirectOverriddenProperties(memberSymbol)
} }
else -> throw IllegalArgumentException("unexpected member kind $member") else -> throw IllegalArgumentException("unexpected member kind $memberSymbol")
} }
} }
private fun ConeKotlinType.substituteAllTypeParameters( private fun ConeKotlinType.substituteAllTypeParameters(
overrideDeclaration: FirCallableDeclaration, overrideDeclaration: FirCallableSymbol<*>,
baseDeclaration: FirCallableDeclaration, baseDeclaration: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
): ConeKotlinType { ): ConeKotlinType {
if (overrideDeclaration.typeParameters.isEmpty()) { val overrideTypeParameters = overrideDeclaration.typeParameterSymbols
if (overrideTypeParameters.isEmpty()) {
return this return this
} }
val parametersOwner = baseDeclaration.safeAs<FirTypeParametersOwner>() val baseTypeParameters = baseDeclaration.typeParameterSymbols
?: return this
val map = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>() val map = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
val size = minOf(overrideDeclaration.typeParameters.size, parametersOwner.typeParameters.size) val size = minOf(overrideTypeParameters.size, baseTypeParameters.size)
for (it in 0 until size) { for (it in 0 until size) {
val to = overrideDeclaration.typeParameters[it] val to = overrideTypeParameters[it]
val from = parametersOwner.typeParameters[it] val from = baseTypeParameters[it]
map[from.symbol] = to.toConeType() map[from] = to.toConeType()
} }
return substitutorByMap(map, context.session).substituteOrSelf(this) return substitutorByMap(map, context.session).substituteOrSelf(this)
@@ -91,32 +93,32 @@ object FirOverrideChecker : FirClassChecker() {
private fun checkModality( private fun checkModality(
overriddenSymbols: List<FirCallableSymbol<*>>, overriddenSymbols: List<FirCallableSymbol<*>>,
): FirCallableDeclaration? { ): FirCallableSymbol<*>? {
for (overridden in overriddenSymbols) { for (overridden in overriddenSymbols) {
val modality = (overridden.fir as FirMemberDeclaration).status.modality val modality = overridden.modality
val isEffectivelyFinal = modality == null || modality == Modality.FINAL val isEffectivelyFinal = modality == null || modality == Modality.FINAL
if (isEffectivelyFinal) { if (isEffectivelyFinal) {
return overridden.fir return overridden
} }
} }
return null return null
} }
private fun FirProperty.checkMutability( private fun FirPropertySymbol.checkMutability(
overriddenSymbols: List<FirCallableSymbol<*>>, overriddenSymbols: List<FirCallableSymbol<*>>,
): FirMemberDeclaration? { ): FirCallableSymbol<*>? {
if (isVar) return null if (isVar) return null
return overriddenSymbols.find { (it.fir as? FirProperty)?.isVar == true }?.fir as? FirMemberDeclaration? return overriddenSymbols.find { (it as? FirPropertySymbol)?.isVar == true }
} }
private fun FirCallableDeclaration.checkVisibility( private fun FirCallableSymbol<*>.checkVisibility(
containingClass: FirClass, containingClass: FirClass,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
overriddenSymbols: List<FirCallableSymbol<*>>, overriddenSymbols: List<FirCallableSymbol<*>>,
context: CheckerContext context: CheckerContext
) { ) {
val visibilities = overriddenSymbols.map { val visibilities = overriddenSymbols.map {
it to (it.fir as FirMemberDeclaration).visibility it to it.visibility
}.sortedBy { pair -> }.sortedBy { pair ->
// Regard `null` compare as Int.MIN so that we can report CANNOT_CHANGE_... first deterministically // Regard `null` compare as Int.MIN so that we can report CANNOT_CHANGE_... first deterministically
Visibilities.compare(visibility, pair.second) ?: Int.MIN_VALUE Visibilities.compare(visibility, pair.second) ?: Int.MIN_VALUE
@@ -125,10 +127,10 @@ object FirOverrideChecker : FirClassChecker() {
for ((overridden, overriddenVisibility) in visibilities) { for ((overridden, overriddenVisibility) in visibilities) {
val compare = Visibilities.compare(visibility, overriddenVisibility) val compare = Visibilities.compare(visibility, overriddenVisibility)
if (compare == null) { if (compare == null) {
reporter.reportCannotChangeAccessPrivilege(this, overridden.fir, context) reporter.reportCannotChangeAccessPrivilege(this, overridden, context)
return return
} else if (compare < 0) { } else if (compare < 0) {
reporter.reportCannotWeakenAccessPrivilege(this, overridden.fir, context) reporter.reportCannotWeakenAccessPrivilege(this, overridden, context)
return return
} }
} }
@@ -137,45 +139,47 @@ object FirOverrideChecker : FirClassChecker() {
val containingDeclarations = context.containingDeclarations + containingClass val containingDeclarations = context.containingDeclarations + containingClass
val visibilityChecker = context.session.visibilityChecker val visibilityChecker = context.session.visibilityChecker
val hasVisibleBase = overriddenSymbols.any { val hasVisibleBase = overriddenSymbols.any {
val fir = it.fir as? FirCallableDeclaration ?: return@any true it.ensureResolved(FirResolvePhase.STATUS)
@OptIn(SymbolInternals::class)
val fir = it.fir
visibilityChecker.isVisible(fir, context.session, file, containingDeclarations, null) visibilityChecker.isVisible(fir, context.session, file, containingDeclarations, null)
} }
if (!hasVisibleBase) { if (!hasVisibleBase) {
//NB: Old FE reports this in an attempt to override private member, //NB: Old FE reports this in an attempt to override private member,
//while the new FE doesn't treat super's private members as overridable, so you won't get them here //while the new FE doesn't treat super's private members as overridable, so you won't get them here
//instead you will get NOTHING_TO_OVERRIDE, which seems acceptable //instead you will get NOTHING_TO_OVERRIDE, which seems acceptable
reporter.reportOn(source, FirErrors.CANNOT_OVERRIDE_INVISIBLE_MEMBER, this, overriddenSymbols.first().fir, context) reporter.reportOn(source, FirErrors.CANNOT_OVERRIDE_INVISIBLE_MEMBER, this, overriddenSymbols.first(), context)
} }
} }
// See [OverrideResolver#isReturnTypeOkForOverride] // See [OverrideResolver#isReturnTypeOkForOverride]
private fun FirCallableDeclaration.checkReturnType( private fun FirCallableSymbol<*>.checkReturnType(
overriddenSymbols: List<FirCallableSymbol<*>>, overriddenSymbols: List<FirCallableSymbol<*>>,
typeCheckerContext: AbstractTypeCheckerContext, typeCheckerContext: AbstractTypeCheckerContext,
context: CheckerContext, context: CheckerContext,
): FirMemberDeclaration? { ): FirCallableSymbol<*>? {
val overridingReturnType = returnTypeRef.coneType val overridingReturnType = resolvedReturnTypeRef.coneType
// Don't report *_ON_OVERRIDE diagnostics according to an error return type. That should be reported separately. // Don't report *_ON_OVERRIDE diagnostics according to an error return type. That should be reported separately.
if (overridingReturnType is ConeKotlinErrorType) { if (overridingReturnType is ConeKotlinErrorType) {
return null return null
} }
val bounds = overriddenSymbols.map { context.returnTypeCalculator.tryCalculateReturnType(it.fir).coneType.upperBoundIfFlexible() } val bounds = overriddenSymbols.map { context.returnTypeCalculator.tryCalculateReturnType(it).coneType.upperBoundIfFlexible() }
for (it in bounds.indices) { for (it in bounds.indices) {
val overriddenDeclaration = overriddenSymbols[it].fir val overriddenDeclaration = overriddenSymbols[it]
val overriddenReturnType = bounds[it].substituteAllTypeParameters(this, overriddenDeclaration, context) val overriddenReturnType = bounds[it].substituteAllTypeParameters(this, overriddenDeclaration, context)
val isReturnTypeOkForOverride = val isReturnTypeOkForOverride =
if (overriddenDeclaration is FirProperty && overriddenDeclaration.isVar) if (overriddenDeclaration is FirPropertySymbol && overriddenDeclaration.isVar)
AbstractTypeChecker.equalTypes(typeCheckerContext, overridingReturnType, overriddenReturnType) AbstractTypeChecker.equalTypes(typeCheckerContext, overridingReturnType, overriddenReturnType)
else else
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, overridingReturnType, overriddenReturnType) AbstractTypeChecker.isSubtypeOf(typeCheckerContext, overridingReturnType, overriddenReturnType)
if (!isReturnTypeOkForOverride) { if (!isReturnTypeOkForOverride) {
return overriddenDeclaration as? FirMemberDeclaration return overriddenDeclaration
} }
} }
@@ -183,12 +187,12 @@ object FirOverrideChecker : FirClassChecker() {
} }
private fun checkMember( private fun checkMember(
member: FirCallableDeclaration, member: FirCallableSymbol<*>,
containingClass: FirClass, containingClass: FirClass,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
typeCheckerContext: AbstractTypeCheckerContext, typeCheckerContext: AbstractTypeCheckerContext,
firTypeScope: FirTypeScope, firTypeScope: FirTypeScope,
context: CheckerContext, context: CheckerContext
) { ) {
val overriddenMemberSymbols = firTypeScope.retrieveDirectOverriddenOf(member) val overriddenMemberSymbols = firTypeScope.retrieveDirectOverriddenOf(member)
@@ -200,15 +204,29 @@ object FirOverrideChecker : FirClassChecker() {
} }
val kind = member.source?.kind val kind = member.source?.kind
// Only report if the current member has real source or it's a member property declared inside the primary constructor. // Only report if the current member has real source or it's a member property declared inside the primary constructor.
if (kind is FirFakeSourceElementKind.DataClassGeneratedMembers) {
overriddenMemberSymbols.find { it.isFinal }?.let { base ->
reporter.reportOn(
containingClass.source,
FirErrors.DATA_CLASS_OVERRIDE_CONFLICT,
member,
base,
context
)
}
return
}
if (kind !is FirRealSourceElementKind && kind !is FirFakeSourceElementKind.PropertyFromParameter) return if (kind !is FirRealSourceElementKind && kind !is FirFakeSourceElementKind.PropertyFromParameter) return
val overridden = overriddenMemberSymbols.first().originalOrSelf() val overridden = overriddenMemberSymbols.first().originalOrSelf()
val originalContainigClass = overridden.containingClass()?.toFirRegularClass(context.session) ?: return val originalContainingClassSymbol = overridden.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol ?: return
reporter.reportOn( reporter.reportOn(
member.source, member.source,
FirErrors.VIRTUAL_MEMBER_HIDDEN, FirErrors.VIRTUAL_MEMBER_HIDDEN,
member, member,
originalContainigClass, originalContainingClassSymbol,
context context
) )
return return
@@ -223,7 +241,7 @@ object FirOverrideChecker : FirClassChecker() {
reporter.reportOverridingFinalMember(member, it, context) reporter.reportOverridingFinalMember(member, it, context)
} }
if (member is FirProperty) { if (member is FirPropertySymbol) {
member.checkMutability(overriddenMemberSymbols)?.let { member.checkMutability(overriddenMemberSymbols)?.let {
reporter.reportVarOverriddenByVal(member, it, context) reporter.reportVarOverriddenByVal(member, it, context)
} }
@@ -237,8 +255,8 @@ object FirOverrideChecker : FirClassChecker() {
context = context, context = context,
) ?: return ) ?: return
when (member) { when (member) {
is FirSimpleFunction -> reporter.reportReturnTypeMismatchOnFunction(member, restriction, context) is FirNamedFunctionSymbol -> reporter.reportReturnTypeMismatchOnFunction(member, restriction, context)
is FirProperty -> { is FirPropertySymbol -> {
if (member.isVar) { if (member.isVar) {
reporter.reportTypeMismatchOnVariable(member, restriction, context) reporter.reportTypeMismatchOnVariable(member, restriction, context)
} else { } else {
@@ -248,15 +266,13 @@ object FirOverrideChecker : FirClassChecker() {
} }
} }
@Suppress("UNUSED_PARAMETER") // TODO: delete me after implementing body private fun DiagnosticReporter.reportNothingToOverride(declaration: FirCallableSymbol<*>, context: CheckerContext) {
private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration, context: CheckerContext) { reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
// TODO: not ready yet, e.g., Collections
// reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
} }
private fun DiagnosticReporter.reportOverridingFinalMember( private fun DiagnosticReporter.reportOverridingFinalMember(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirCallableDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
overridden.containingClass()?.let { containingClass -> overridden.containingClass()?.let { containingClass ->
@@ -265,16 +281,16 @@ object FirOverrideChecker : FirClassChecker() {
} }
private fun DiagnosticReporter.reportVarOverriddenByVal( private fun DiagnosticReporter.reportVarOverriddenByVal(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirMemberDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
reportOn(overriding.source, FirErrors.VAR_OVERRIDDEN_BY_VAL, overriding, overridden, context) reportOn(overriding.source, FirErrors.VAR_OVERRIDDEN_BY_VAL, overriding, overridden, context)
} }
private fun DiagnosticReporter.reportCannotWeakenAccessPrivilege( private fun DiagnosticReporter.reportCannotWeakenAccessPrivilege(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirCallableDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
val containingClass = overridden.containingClass() ?: return val containingClass = overridden.containingClass() ?: return
@@ -289,8 +305,8 @@ object FirOverrideChecker : FirClassChecker() {
} }
private fun DiagnosticReporter.reportCannotChangeAccessPrivilege( private fun DiagnosticReporter.reportCannotChangeAccessPrivilege(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirCallableDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
val containingClass = overridden.containingClass() ?: return val containingClass = overridden.containingClass() ?: return
@@ -305,24 +321,24 @@ object FirOverrideChecker : FirClassChecker() {
} }
private fun DiagnosticReporter.reportReturnTypeMismatchOnFunction( private fun DiagnosticReporter.reportReturnTypeMismatchOnFunction(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirMemberDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
reportOn(overriding.source, FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context) reportOn(overriding.source, FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context)
} }
private fun DiagnosticReporter.reportTypeMismatchOnProperty( private fun DiagnosticReporter.reportTypeMismatchOnProperty(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirMemberDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
reportOn(overriding.source, FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context) reportOn(overriding.source, FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context)
} }
private fun DiagnosticReporter.reportTypeMismatchOnVariable( private fun DiagnosticReporter.reportTypeMismatchOnVariable(
overriding: FirMemberDeclaration, overriding: FirCallableSymbol<*>,
overridden: FirMemberDeclaration, overridden: FirCallableSymbol<*>,
context: CheckerContext context: CheckerContext
) { ) {
reportOn(overriding.source, FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context) reportOn(overriding.source, FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE, overriding, overridden, context)
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.SourceNavigator import org.jetbrains.kotlin.fir.analysis.checkers.SourceNavigator
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -65,9 +65,9 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() {
// No need to check implicit call to the constructor of `kotlin.Any`. // No need to check implicit call to the constructor of `kotlin.Any`.
val constructedTypeRef = delegatedConstructorCall.constructedTypeRef val constructedTypeRef = delegatedConstructorCall.constructedTypeRef
if (constructedTypeRef is FirImplicitAnyTypeRef) return if (constructedTypeRef is FirImplicitAnyTypeRef) return
val superClass = constructedTypeRef.coneType.toRegularClass(context.session) ?: return val superClassSymbol = constructedTypeRef.coneType.toRegularClassSymbol(context.session) ?: return
// Subclassing a singleton should be reported as SINGLETON_IN_SUPERTYPE // Subclassing a singleton should be reported as SINGLETON_IN_SUPERTYPE
if (superClass.classKind.isSingleton) return if (superClassSymbol.classKind.isSingleton) return
if (regularClass.isEffectivelyExpect(containingClass, context) || if (regularClass.isEffectivelyExpect(containingClass, context) ||
regularClass.isEffectivelyExternal(containingClass, context) regularClass.isEffectivelyExternal(containingClass, context)
) { ) {
@@ -75,7 +75,7 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() {
} }
val delegatedCallSource = delegatedConstructorCall.source ?: return val delegatedCallSource = delegatedConstructorCall.source ?: return
if (delegatedCallSource.kind !is FirFakeSourceElementKind) return if (delegatedCallSource.kind !is FirFakeSourceElementKind) return
if (superClass.symbol.classId == StandardClassIds.Enum) return if (superClassSymbol.classId == StandardClassIds.Enum) return
if (delegatedCallSource.elementType != KtNodeTypes.SUPER_TYPE_CALL_ENTRY) { if (delegatedCallSource.elementType != KtNodeTypes.SUPER_TYPE_CALL_ENTRY) {
reporter.reportOn(constructedTypeRef.source, FirErrors.SUPERTYPE_NOT_INITIALIZED, context) reporter.reportOn(constructedTypeRef.source, FirErrors.SUPERTYPE_NOT_INITIALIZED, context)
} }
@@ -13,9 +13,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirProjectionRelationChecker : FirBasicDeclarationChecker() { object FirProjectionRelationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -49,8 +49,8 @@ object FirProjectionRelationChecker : FirBasicDeclarationChecker() {
) { ) {
val type = typeRef.coneTypeSafe<ConeClassLikeType>() val type = typeRef.coneTypeSafe<ConeClassLikeType>()
val fullyExpandedType = type?.fullyExpandedType(context.session) ?: return val fullyExpandedType = type?.fullyExpandedType(context.session) ?: return
val declaration = fullyExpandedType.toSymbol(context.session)?.fir.safeAs<FirRegularClass>() ?: return val declaration = fullyExpandedType.toSymbol(context.session) as? FirRegularClassSymbol ?: return
val typeParameters = declaration.typeParameters val typeParameters = declaration.typeParameterSymbols
val typeArguments = type.typeArguments val typeArguments = type.typeArguments
val size = minOf(typeParameters.size, typeArguments.size) val size = minOf(typeParameters.size, typeArguments.size)
@@ -60,9 +60,7 @@ object FirProjectionRelationChecker : FirBasicDeclarationChecker() {
val actual = typeArguments[it] val actual = typeArguments[it]
val fullyExpandedProjection = fullyExpandedType.typeArguments[it] val fullyExpandedProjection = fullyExpandedType.typeArguments[it]
val protoVariance = proto.safeAs<FirTypeParameterRef>() val protoVariance = proto.variance
?.symbol?.fir
?.variance
val projectionRelation = if (fullyExpandedProjection is ConeKotlinTypeConflictingProjection || val projectionRelation = if (fullyExpandedProjection is ConeKotlinTypeConflictingProjection ||
actual is ConeKotlinTypeProjectionIn && protoVariance == Variance.OUT_VARIANCE || actual is ConeKotlinTypeProjectionIn && protoVariance == Variance.OUT_VARIANCE ||
@@ -11,12 +11,12 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirSealedSupertypeChecker : FirClassChecker() { object FirSealedSupertypeChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -36,11 +36,9 @@ object FirSealedSupertypeChecker : FirClassChecker() {
continue continue
} }
val fir = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) val classSymbol = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: continue
?.fir.safeAs<FirRegularClass>()
?: continue
if (fir.status.modality == Modality.SEALED && declaration.classId.packageFqName != fir.classId.packageFqName) { if (classSymbol.modality == Modality.SEALED && declaration.classId.packageFqName != classSymbol.classId.packageFqName) {
reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context) reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context)
continue continue
} }
@@ -55,11 +53,9 @@ object FirSealedSupertypeChecker : FirClassChecker() {
continue continue
} }
val fir = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) val classSymbol = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: continue
?.fir.safeAs<FirRegularClass>()
?: continue
if (fir.status.modality == Modality.SEALED) { if (classSymbol.modality == Modality.SEALED) {
reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS, context) reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS, context)
return return
} }
@@ -47,13 +47,13 @@ object FirSupertypesChecker : FirClassChecker() {
extensionFunctionSupertypeReported = true extensionFunctionSupertypeReported = true
} }
val lookupTag = coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: return@withSuppressedDiagnostics val lookupTag = coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: return@withSuppressedDiagnostics
val superTypeFir = lookupTag.toSymbol(context.session)?.fir val superTypeSymbol = lookupTag.toSymbol(context.session)
if (superTypeFir is FirRegularClass) { if (superTypeSymbol is FirRegularClassSymbol) {
if (!superClassSymbols.add(superTypeFir.symbol)) { if (!superClassSymbols.add(superTypeSymbol)) {
reporter.reportOn(superTypeRef.source, FirErrors.SUPERTYPE_APPEARS_TWICE, context) reporter.reportOn(superTypeRef.source, FirErrors.SUPERTYPE_APPEARS_TWICE, context)
} }
if (superTypeFir.classKind != ClassKind.INTERFACE) { if (superTypeSymbol.classKind != ClassKind.INTERFACE) {
if (classAppeared) { if (classAppeared) {
reporter.reportOn(superTypeRef.source, FirErrors.MANY_CLASSES_IN_SUPERTYPE_LIST, context) reporter.reportOn(superTypeRef.source, FirErrors.MANY_CLASSES_IN_SUPERTYPE_LIST, context)
} else { } else {
@@ -64,8 +64,8 @@ object FirSupertypesChecker : FirClassChecker() {
interfaceWithSuperclassReported = true interfaceWithSuperclassReported = true
} }
} }
val isObject = superTypeFir.classKind == ClassKind.OBJECT val isObject = superTypeSymbol.classKind == ClassKind.OBJECT
if (!finalSupertypeReported && !isObject && superTypeFir.modality == Modality.FINAL) { if (!finalSupertypeReported && !isObject && superTypeSymbol.modality == Modality.FINAL) {
reporter.reportOn(superTypeRef.source, FirErrors.FINAL_SUPERTYPE, context) reporter.reportOn(superTypeRef.source, FirErrors.FINAL_SUPERTYPE, context)
finalSupertypeReported = true finalSupertypeReported = true
} }
@@ -93,7 +93,7 @@ object FirSupertypesChecker : FirClassChecker() {
checkDelegationNotToInterface(declaration, context, reporter) checkDelegationNotToInterface(declaration, context, reporter)
if (declaration is FirRegularClass && declaration.superTypeRefs.size > 1) { if (declaration is FirRegularClass && declaration.superTypeRefs.size > 1) {
checkInconsistentTypeParameters(listOf(Pair(null, declaration)), context, reporter, declaration.source, true) checkInconsistentTypeParameters(listOf(Pair(null, declaration.symbol)), context, reporter, declaration.source, true)
} }
} }
@@ -148,7 +148,7 @@ object FirSupertypesChecker : FirClassChecker() {
coneType: ConeKotlinType, coneType: ConeKotlinType,
context: CheckerContext context: CheckerContext
) { ) {
if (symbol is FirRegularClassSymbol && symbol.fir.classKind == ClassKind.INTERFACE) { if (symbol is FirRegularClassSymbol && symbol.classKind == ClassKind.INTERFACE) {
for (typeArgument in fullyExpandedType.typeArguments) { for (typeArgument in fullyExpandedType.typeArguments) {
if (typeArgument.isConflictingOrNotInvariant) { if (typeArgument.isConflictingOrNotInvariant) {
reporter.reportOn(superTypeRef.source, FirErrors.EXPANDED_TYPE_CANNOT_BE_INHERITED, coneType, context) reporter.reportOn(superTypeRef.source, FirErrors.EXPANDED_TYPE_CANNOT_BE_INHERITED, coneType, context)
@@ -169,8 +169,8 @@ object FirSupertypesChecker : FirClassChecker() {
subDeclaration.name.isSpecial && subDeclaration.name.isSpecial &&
subDeclaration.name.isDelegated subDeclaration.name.isDelegated
) { ) {
val subDeclFir = subDeclaration.returnTypeRef.toRegularClass(context.session) val delegatedClassSymbol = subDeclaration.returnTypeRef.toRegularClassSymbol(context.session)
if (subDeclFir is FirRegularClass && subDeclFir.classKind != ClassKind.INTERFACE) { if (delegatedClassSymbol != null && delegatedClassSymbol.classKind != ClassKind.INTERFACE) {
reporter.reportOn(subDeclaration.returnTypeRef.source, FirErrors.DELEGATION_NOT_TO_INTERFACE, context) reporter.reportOn(subDeclaration.returnTypeRef.source, FirErrors.DELEGATION_NOT_TO_INTERFACE, context)
} }
} }
@@ -35,7 +35,7 @@ object FirTopLevelFunctionsChecker : FirFileChecker() {
if (function.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return if (function.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return
if (function.isExternal) return if (function.isExternal) return
if (!function.hasBody && !function.isExpect) { if (!function.hasBody && !function.isExpect) {
reporter.reportOn(source, FirErrors.NON_MEMBER_FUNCTION_NO_BODY, function, context) reporter.reportOn(source, FirErrors.NON_MEMBER_FUNCTION_NO_BODY, function.symbol, context)
} }
checkExpectDeclarationVisibilityAndBody(function, source, reporter, context) checkExpectDeclarationVisibilityAndBody(function, source, reporter, context)
@@ -24,7 +24,7 @@ object FirTypeConstraintsChecker : FirBasicDeclarationChecker() {
constraint.source, constraint.source,
FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER, FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER,
constraint.name, constraint.name,
declaration, declaration.symbol,
context context
) )
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isOverride import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
@@ -55,7 +56,7 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
if (containingDeclaration is FirSimpleFunction && containingDeclaration.isOverride) return if (containingDeclaration is FirSimpleFunction && containingDeclaration.isOverride) return
if (containingDeclaration is FirProperty && containingDeclaration.isOverride) return if (containingDeclaration is FirProperty && containingDeclaration.isOverride) return
declaration.symbol.fir.bounds.forEach { bound -> declaration.symbol.resolvedBounds.forEach { bound ->
if (!bound.coneType.canHaveSubtypes(context.session)) { if (!bound.coneType.canHaveSubtypes(context.session)) {
reporter.reportOn(bound.source, FirErrors.FINAL_UPPER_BOUND, bound.coneType, context) reporter.reportOn(bound.source, FirErrors.FINAL_UPPER_BOUND, bound.coneType, context)
} }
@@ -63,7 +64,7 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
} }
private fun checkExtensionFunctionTypeBound(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) { private fun checkExtensionFunctionTypeBound(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
declaration.symbol.fir.bounds.forEach { bound -> declaration.symbol.resolvedBounds.forEach { bound ->
if (bound.isExtensionFunctionType(context.session)) { if (bound.isExtensionFunctionType(context.session)) {
reporter.reportOn(bound.source, FirErrors.UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE, context) reporter.reportOn(bound.source, FirErrors.UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE, context)
} }
@@ -107,13 +108,13 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
} }
private fun checkBoundUniqueness(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) { private fun checkBoundUniqueness(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
val seenClasses = mutableSetOf<FirRegularClass>() val seenClasses = mutableSetOf<FirRegularClassSymbol>()
val allNonErrorBounds = declaration.bounds.filter { it !is FirErrorTypeRef } val allNonErrorBounds = declaration.bounds.filter { it !is FirErrorTypeRef }
val uniqueBounds = allNonErrorBounds.distinctBy { it.coneType.classId ?: it.coneType } val uniqueBounds = allNonErrorBounds.distinctBy { it.coneType.classId ?: it.coneType }
uniqueBounds.forEach { bound -> uniqueBounds.forEach { bound ->
bound.coneType.toRegularClass(context.session)?.let { clazz -> bound.coneType.toRegularClassSymbol(context.session)?.let { symbol ->
if (classKinds.contains(clazz.classKind) && seenClasses.add(clazz) && seenClasses.size > 1) { if (classKinds.contains(symbol.classKind) && seenClasses.add(symbol) && seenClasses.size > 1) {
reporter.reportOn(bound.source, FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED, context) reporter.reportOn(bound.source, FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED, context)
} }
} }
@@ -163,19 +164,19 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
) { ) {
if (declaration.bounds.size <= 1) return if (declaration.bounds.size <= 1) return
val firTypeRefClasses = mutableListOf<Pair<FirTypeRef, FirRegularClass>>() val firTypeRefClasses = mutableListOf<Pair<FirTypeRef, FirRegularClassSymbol>>()
val firRegularClassesSet = mutableSetOf<FirRegularClass>() val firRegularClassesSet = mutableSetOf<FirRegularClassSymbol>()
for (bound in declaration.bounds) { for (bound in declaration.bounds) {
val firRegularClass = bound.toRegularClass(context.session) val classSymbol = bound.toRegularClassSymbol(context.session)
if (firRegularClassesSet.contains(firRegularClass)) { if (firRegularClassesSet.contains(classSymbol)) {
// no need to throw INCONSISTENT_TYPE_PARAMETER_BOUNDS diagnostics here because REPEATED_BOUNDS diagnostic is already exist // no need to throw INCONSISTENT_TYPE_PARAMETER_BOUNDS diagnostics here because REPEATED_BOUNDS diagnostic is already exist
return return
} }
if (firRegularClass != null) { if (classSymbol != null) {
firRegularClassesSet.add(firRegularClass) firRegularClassesSet.add(classSymbol)
firTypeRefClasses.add(Pair(bound, firRegularClass)) firTypeRefClasses.add(Pair(bound, classSymbol))
} }
} }
@@ -7,22 +7,21 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
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.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isExtensionMember import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isExtensionMember
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.getContainingClass import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
object FirCallableReferenceChecker : FirQualifiedAccessExpressionChecker() { object FirCallableReferenceChecker : FirQualifiedAccessExpressionChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -45,19 +44,21 @@ object FirCallableReferenceChecker : FirQualifiedAccessExpressionChecker() {
val source = reference.source ?: return val source = reference.source ?: return
if (source.kind is FirFakeSourceElementKind) return if (source.kind is FirFakeSourceElementKind) return
val referredDeclaration = reference.resolvedSymbol.fir val referredSymbol = reference.resolvedSymbol
if (referredDeclaration is FirConstructor && referredDeclaration.getContainingClass(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) { if (referredSymbol is FirConstructorSymbol && referredSymbol.getContainingClassSymbol(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) {
reporter.reportOn(source, FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, context) reporter.reportOn(source, FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, context)
} }
if ((referredDeclaration as? FirCallableDeclaration)?.isExtensionMember == true && if ((referredSymbol as? FirCallableSymbol<*>)?.isExtensionMember == true &&
!referredDeclaration.isLocalMember !referredSymbol.isLocalMember
) { ) {
reporter.reportOn(source, FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED, referredDeclaration, context) reporter.reportOn(source, FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED, referredSymbol, context)
} }
// The counterpart in FE 1.0 checks if the given descriptor is VariableDescriptor yet not PropertyDescriptor. // The counterpart in FE 1.0 checks if the given descriptor is VariableDescriptor yet not PropertyDescriptor.
// Here, we explicitly check if the referred declaration/symbol is value parameter, local variable, or backing field. // Here, we explicitly check if the referred declaration/symbol is value parameter, local variable, or backing field.
if (referredDeclaration is FirValueParameter || if (
(referredDeclaration is FirProperty && (referredDeclaration.isLocal || reference.resolvedSymbol is FirBackingFieldSymbol)) referredSymbol is FirValueParameterSymbol ||
(referredSymbol is FirPropertySymbol && referredSymbol.isLocal) ||
reference.resolvedSymbol is FirBackingFieldSymbol
) { ) {
// TODO: we can't set positioning strategy to meta error. Should report on reference expression, not entire reference access. // TODO: we can't set positioning strategy to meta error. Should report on reference expression, not entire reference access.
reporter.reportOn(source, FirErrors.UNSUPPORTED, "References to variables aren't supported yet", context) reporter.reportOn(source, FirErrors.UNSUPPORTED, "References to variables aren't supported yet", context)
@@ -31,7 +31,7 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
val coneType = catchParameter.returnTypeRef.coneType val coneType = catchParameter.returnTypeRef.coneType
if (coneType is ConeTypeParameterType) { if (coneType is ConeTypeParameterType) {
val isReified = coneType.lookupTag.typeParameterSymbol.fir.isReified val isReified = coneType.lookupTag.typeParameterSymbol.isReified
if (isReified) { if (isReified) {
reporter.reportOn(source, FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE, context) reporter.reportOn(source, FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE, context)
@@ -11,12 +11,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.getChild import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.scopes.impl.toConeType import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens.QUEST import org.jetbrains.kotlin.lexer.KtTokens.QUEST
@@ -63,7 +66,7 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
} }
argument.safeAsTypeParameterSymbol?.let { argument.safeAsTypeParameterSymbol?.let {
if (!it.fir.isReified) { if (!it.isReified) {
// E.g., fun <T: Any> foo(): Any = T::class // E.g., fun <T: Any> foo(): Any = T::class
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_AS_REIFIED, it, context) reporter.reportOn(source, FirErrors.TYPE_PARAMETER_AS_REIFIED, it, context)
} }
@@ -72,7 +75,10 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
if (argument !is FirResolvedQualifier) return if (argument !is FirResolvedQualifier) return
// TODO: differentiate RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS // TODO: differentiate RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS
if (argument.typeArguments.isNotEmpty() && !argument.typeRef.coneType.isAllowedInClassLiteral(context)) { if (argument.typeArguments.isNotEmpty() && !argument.typeRef.coneType.isAllowedInClassLiteral(context)) {
val typeParameters = (argument.symbol?.fir as? FirTypeParameterRefsOwner)?.typeParameters val symbol = argument.symbol
symbol?.ensureResolved(FirResolvePhase.TYPES)
@OptIn(SymbolInternals::class)
val typeParameters = (symbol?.fir as? FirTypeParameterRefsOwner)?.typeParameters
// Among type parameter references, only count actual type parameter while discarding [FirOuterClassTypeParameterRef] // Among type parameter references, only count actual type parameter while discarding [FirOuterClassTypeParameterRef]
val expectedTypeArgumentSize = typeParameters?.filterIsInstance<FirTypeParameter>()?.size ?: 0 val expectedTypeArgumentSize = typeParameters?.filterIsInstance<FirTypeParameter>()?.size ?: 0
if (expectedTypeArgumentSize != argument.typeArguments.size) { if (expectedTypeArgumentSize != argument.typeArguments.size) {
@@ -85,7 +91,7 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
private fun ConeKotlinType.isNullableTypeParameter(context: ConeInferenceContext): Boolean { private fun ConeKotlinType.isNullableTypeParameter(context: ConeInferenceContext): Boolean {
if (this !is ConeTypeParameterType) return false if (this !is ConeTypeParameterType) return false
val typeParameter = lookupTag.typeParameterSymbol.fir val typeParameter = lookupTag.typeParameterSymbol
with(context) { with(context) {
return !typeParameter.isReified && return !typeParameter.isReified &&
// E.g., fun <T> f2(t: T): Any = t::class // E.g., fun <T> f2(t: T): Any = t::class
@@ -120,7 +126,7 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
} else } else
typeArguments.isEmpty() typeArguments.isEmpty()
} }
is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.fir.isReified is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.isReified
else -> false else -> false
} }
} }
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -23,7 +23,7 @@ object FirConstructorCallChecker : FirFunctionCallChecker() {
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
val constructorSymbol = val constructorSymbol =
(expression.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol ?: return (expression.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol ?: return
val declarationClass = constructorSymbol.fir.returnTypeRef.coneType.toRegularClass(context.session) val declarationClass = constructorSymbol.resolvedReturnTypeRef.coneType.toRegularClassSymbol(context.session)
if (declarationClass != null) { if (declarationClass != null) {
if (declarationClass.isAbstract && declarationClass.classKind == ClassKind.CLASS) { if (declarationClass.isAbstract && declarationClass.classKind == ClassKind.CLASS) {
@@ -5,17 +5,24 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.Deprecation
import org.jetbrains.kotlin.fir.declarations.DeprecationLevelValue
import org.jetbrains.kotlin.fir.declarations.getDeprecation
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.FirResolvable
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirDeprecationChecker : FirBasicExpressionChecker() { object FirDeprecationChecker : FirBasicExpressionChecker() {
@@ -30,39 +37,38 @@ object FirDeprecationChecker : FirBasicExpressionChecker() {
if (expression is FirAnnotationCall) return //checked by FirDeprecatedTypeChecker if (expression is FirAnnotationCall) return //checked by FirDeprecatedTypeChecker
val resolvable = expression as? FirResolvable ?: return val resolvable = expression as? FirResolvable ?: return
val reference = resolvable.calleeReference as? FirResolvedNamedReference ?: return val reference = resolvable.calleeReference as? FirResolvedNamedReference ?: return
val referencedFir = reference.resolvedSymbol.fir val referencedSymbol = reference.resolvedSymbol
if (referencedFir !is FirAnnotatedDeclaration) return
reportDeprecationIfNeeded(expression.source, referencedFir, expression, context, reporter) reportDeprecationIfNeeded(expression.source, referencedSymbol, expression, context, reporter)
} }
internal fun reportDeprecationIfNeeded( internal fun reportDeprecationIfNeeded(
source: FirSourceElement?, source: FirSourceElement?,
referencedFir: FirAnnotatedDeclaration, referencedSymbol: FirBasedSymbol<*>,
callSite: FirElement?, callSite: FirElement?,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val deprecation = getWorstDeprecation(callSite, referencedFir, context) ?: return val deprecation = getWorstDeprecation(callSite, referencedSymbol, context) ?: return
val diagnostic = when (deprecation.level) { val diagnostic = when (deprecation.level) {
DeprecationLevelValue.ERROR, DeprecationLevelValue.HIDDEN -> FirErrors.DEPRECATION_ERROR DeprecationLevelValue.ERROR, DeprecationLevelValue.HIDDEN -> FirErrors.DEPRECATION_ERROR
DeprecationLevelValue.WARNING -> FirErrors.DEPRECATION DeprecationLevelValue.WARNING -> FirErrors.DEPRECATION
} }
reporter.reportOn(source, diagnostic, referencedFir.symbol, deprecation.message ?: "", context) reporter.reportOn(source, diagnostic, referencedSymbol, deprecation.message ?: "", context)
} }
private fun getWorstDeprecation( private fun getWorstDeprecation(
callSite: FirElement?, callSite: FirElement?,
fir: FirAnnotatedDeclaration, symbol: FirBasedSymbol<*>,
context: CheckerContext context: CheckerContext
): Deprecation? { ): Deprecation? {
val deprecationInfos = listOfNotNull( val deprecationInfos = listOfNotNull(
fir.getDeprecation(callSite), symbol.getDeprecation(callSite),
fir.safeAs<FirConstructor>()?.returnTypeRef symbol.safeAs<FirConstructorSymbol>()
?.toRegularClass(context.session) ?.resolvedReturnTypeRef
?.toRegularClassSymbol(context.session)
?.getDeprecation(callSite) ?.getDeprecation(callSite)
) )
return deprecationInfos.maxOrNull() return deprecationInfos.maxOrNull()
} }
} }
@@ -133,9 +133,8 @@ object FirForLoopChecker : FirBlockChecker() {
is FirResolvedNamedReference -> { is FirResolvedNamedReference -> {
val symbol = calleeReference.resolvedSymbol val symbol = calleeReference.resolvedSymbol
if (symbol is FirNamedFunctionSymbol) { if (symbol is FirNamedFunctionSymbol) {
val function = symbol.fir if (!symbol.isOperator) {
if (!function.isOperator) { reporter.reportOn(reportSource, OPERATOR_MODIFIER_REQUIRED, symbol, symbol.name.asString(), context)
reporter.reportOn(reportSource, OPERATOR_MODIFIER_REQUIRED, symbol, function.name.asString(), context)
// Don't return true as we want to report other errors // Don't return true as we want to report other errors
} }
} }
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -15,17 +15,18 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isFun import org.jetbrains.kotlin.fir.declarations.utils.isFun
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessExpressionChecker() { object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessExpressionChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
if (expression !is FirCallableReferenceAccess || expression is FirGetClassCall) return if (expression !is FirCallableReferenceAccess || expression is FirGetClassCall) return
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
val referredDeclaration = reference.resolvedSymbol.fir val referredSymbol = reference.resolvedSymbol
if (referredDeclaration is FirSimpleFunction && if (referredSymbol is FirNamedFunctionSymbol &&
referredDeclaration.origin == FirDeclarationOrigin.SamConstructor && referredSymbol.origin == FirDeclarationOrigin.SamConstructor &&
referredDeclaration.returnTypeRef.toRegularClass(context.session)?.isFun == true referredSymbol.resolvedReturnTypeRef.toRegularClassSymbol(context.session)?.isFun == true
) { ) {
reporter.reportOn(reference.source, FUN_INTERFACE_CONSTRUCTOR_REFERENCE, context) reporter.reportOn(reference.source, FUN_INTERFACE_CONSTRUCTOR_REFERENCE, context)
} }
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -22,13 +22,13 @@ object FirNotASupertypeChecker : FirQualifiedAccessExpressionChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val superReference = expression.calleeReference.safeAs<FirSuperReference>()?.takeIf { it.hadExplicitTypeInSource() } val superReference = expression.calleeReference.safeAs<FirSuperReference>()?.takeIf { it.hadExplicitTypeInSource() }
val targetClass = superReference val targetClassSymbol = superReference
?.superTypeRef ?.superTypeRef
?.toRegularClass(context.session) ?.toRegularClassSymbol(context.session)
?: return ?: return
val surrounding = context.findClosestClass(superReference.labelName) ?: return val surrounding = context.findClosestClass(superReference.labelName) ?: return
if (!targetClass.isSupertypeOf(surrounding, context.session)) { if (!targetClassSymbol.isSupertypeOf(surrounding.symbol, context.session)) {
reporter.reportOn(expression.source, FirErrors.NOT_A_SUPERTYPE, context) reporter.reportOn(expression.source, FirErrors.NOT_A_SUPERTYPE, context)
} }
} }
@@ -36,7 +36,7 @@ object FirOptInAnnotationCallChecker : FirAnnotationCallChecker() {
val annotationClasses = expression.findArgumentByName(OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS) val annotationClasses = expression.findArgumentByName(OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS)
for (classSymbol in annotationClasses?.extractClassesFromArgument().orEmpty()) { for (classSymbol in annotationClasses?.extractClassesFromArgument().orEmpty()) {
with(FirOptInUsageBaseChecker) { with(FirOptInUsageBaseChecker) {
if (classSymbol.fir.loadExperimentalityForMarkerAnnotation() == null) { if (classSymbol.loadExperimentalityForMarkerAnnotation() == null) {
reporter.reportOn( reporter.reportOn(
expression.source, expression.source,
FirErrors.USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER, FirErrors.USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER,
@@ -64,4 +64,4 @@ object FirOptInAnnotationCallChecker : FirAnnotationCallChecker() {
reporter.reportOn(element, FirErrors.EXPERIMENTAL_IS_NOT_ENABLED, context) reporter.reportOn(element, FirErrors.EXPERIMENTAL_IS_NOT_ENABLED, context)
} }
} }
} }
@@ -8,15 +8,25 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.findArgumentByName import org.jetbrains.kotlin.fir.declarations.findArgumentByName
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.checkers.Experimentality import org.jetbrains.kotlin.resolve.checkers.Experimentality
import org.jetbrains.kotlin.resolve.checkers.OptInNames import org.jetbrains.kotlin.resolve.checkers.OptInNames
object FirOptInUsageBaseChecker { internal object FirOptInUsageBaseChecker {
internal fun FirRegularClass.loadExperimentalityForMarkerAnnotation(): Experimentality? { fun FirRegularClassSymbol.loadExperimentalityForMarkerAnnotation(): Experimentality? {
ensureResolved(FirResolvePhase.BODY_RESOLVE)
@OptIn(SymbolInternals::class)
return fir.loadExperimentalityForMarkerAnnotation()
}
private fun FirRegularClass.loadExperimentalityForMarkerAnnotation(): Experimentality? {
val experimental = getAnnotationByFqName(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: return null val experimental = getAnnotationByFqName(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: return null
val levelArgument = experimental.findArgumentByName(LEVEL) as? FirQualifiedAccessExpression val levelArgument = experimental.findArgumentByName(LEVEL) as? FirQualifiedAccessExpression
@@ -34,4 +44,4 @@ object FirOptInUsageBaseChecker {
ERROR(Experimentality.Severity.ERROR), ERROR(Experimentality.Severity.ERROR),
DEFAULT(Experimentality.DEFAULT_SEVERITY) DEFAULT(Experimentality.DEFAULT_SEVERITY)
} }
} }
@@ -7,15 +7,15 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
import org.jetbrains.kotlin.fir.analysis.checkers.followAllAlias import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf
import org.jetbrains.kotlin.fir.analysis.checkers.toClassLikeSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessExpressionChecker() { object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessExpressionChecker() {
@@ -26,8 +26,8 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess
?: return ?: return
val explicitType = superReference.superTypeRef val explicitType = superReference.superTypeRef
.firClassLike(context.session) .toClassLikeSymbol(context.session)
?.followAllAlias(context.session).safeAs<FirClass>() ?.fullyExpandedClass(context.session) as? FirClassSymbol<*>
?: return ?: return
val surroundingType = context.findClosestClassOrObject() val surroundingType = context.findClosestClassOrObject()
@@ -37,11 +37,11 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess
// have `explicitType` as their supertype or // have `explicitType` as their supertype or
// equal to it // equal to it
var count = 0 var count = 0
var candidate: FirClass? = null var candidate: FirClassSymbol<*>? = null
for (it in surroundingType.superTypeRefs) { for (it in surroundingType.superTypeRefs) {
val that = it.firClassLike(context.session) val that = it.toClassLikeSymbol(context.session)
?.followAllAlias(context.session).safeAs<FirClass>() ?.fullyExpandedClass(context.session) as? FirClassSymbol<*>
?: continue ?: continue
val isSupertype = explicitType.isSupertypeOf(that, context.session) val isSupertype = explicitType.isSupertypeOf(that, context.session)
@@ -10,29 +10,30 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirSealedClassConstructorCallChecker : FirQualifiedAccessExpressionChecker() { object FirSealedClassConstructorCallChecker : FirQualifiedAccessExpressionChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val constructorFir = expression.calleeReference.safeAs<FirResolvedNamedReference>() val constructorSymbol = expression.calleeReference.safeAs<FirResolvedNamedReference>()
?.resolvedSymbol ?.resolvedSymbol as? FirConstructorSymbol
?.fir.safeAs<FirConstructor>()
?: return ?: return
val typeFir = constructorFir.returnTypeRef.coneType val typeSymbol = constructorSymbol.resolvedReturnTypeRef.coneType
.fullyExpandedType(context.session)
.safeAs<ConeClassLikeType>() .safeAs<ConeClassLikeType>()
?.lookupTag?.toSymbol(context.session) ?.lookupTag?.toSymbol(context.session) as? FirRegularClassSymbol
?.fir as? FirRegularClass
?: return ?: return
if (typeFir.status.modality == Modality.SEALED) { if (typeSymbol.modality == Modality.SEALED) {
reporter.reportOn(expression.source, FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL, context) reporter.reportOn(expression.source, FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL, context)
} }
} }
@@ -26,7 +26,7 @@ object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() {
when (val symbol = expression.symbol) { when (val symbol = expression.symbol) {
is FirRegularClassSymbol -> { is FirRegularClassSymbol -> {
if (symbol.fir.classKind == ClassKind.OBJECT) return if (symbol.classKind == ClassKind.OBJECT) return
reporter.reportOn(expression.source, FirErrors.NO_COMPANION_OBJECT, symbol, context) reporter.reportOn(expression.source, FirErrors.NO_COMPANION_OBJECT, symbol, context)
} }
null -> { null -> {
@@ -34,4 +34,4 @@ object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() {
} }
} }
} }
} }
@@ -29,9 +29,9 @@ object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessExpres
if (closestClass.classKind == ClassKind.INTERFACE) { if (closestClass.classKind == ClassKind.INTERFACE) {
val containingClassSymbol = val containingClassSymbol =
expression.toResolvedCallableSymbol()?.getContainingClassSymbol(context) as? FirRegularClassSymbol ?: return expression.toResolvedCallableSymbol()?.getContainingClassSymbol(context.session) as? FirRegularClassSymbol ?: return
if (containingClassSymbol.classKind == ClassKind.CLASS) { if (containingClassSymbol.source != null && containingClassSymbol.classKind == ClassKind.CLASS) {
reporter.reportOn(expression.explicitReceiver?.source, FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE, context) reporter.reportOn(expression.explicitReceiver?.source, FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE, context)
} }
} }
@@ -18,8 +18,10 @@ import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -73,7 +75,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
val calleeSymbol = reference.resolvedSymbol val calleeSymbol = reference.resolvedSymbol
val calleeContainingClassSymbol = calleeSymbol.getContainingClassSymbol(context) as? FirRegularClassSymbol ?: return val calleeContainingClassSymbol = calleeSymbol.getContainingClassSymbol(context.session) as? FirRegularClassSymbol ?: return
// We're looking for members/entries/companion object in an enum class or members in companion object of an enum class. // We're looking for members/entries/companion object in an enum class or members in companion object of an enum class.
val calleeIsInsideEnum = calleeContainingClassSymbol.isEnumClass val calleeIsInsideEnum = calleeContainingClassSymbol.isEnumClass
val calleeIsInsideEnumCompanion = val calleeIsInsideEnumCompanion =
@@ -103,7 +105,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// INSTANCE(EnumCompanion2.foo()) // INSTANCE(EnumCompanion2.foo())
// } // }
// find an accessed context within the same enum class. // find an accessed context within the same enum class.
it.getContainingClassSymbol(context) == enumClassSymbol it.getContainingClassSymbol(context.session) == enumClassSymbol
}?.symbol ?: return }?.symbol ?: return
val enumMemberProperties = enumClassSymbol.declarationSymbols.filterIsInstance<FirPropertySymbol>() val enumMemberProperties = enumClassSymbol.declarationSymbols.filterIsInstance<FirPropertySymbol>()
@@ -142,7 +144,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
if (calleeContainingClassSymbol == enumClassSymbol.companionObjectSymbol) { if (calleeContainingClassSymbol == enumClassSymbol.companionObjectSymbol) {
// Uninitialized from the point of view of members or enum entries of that enum class // Uninitialized from the point of view of members or enum entries of that enum class
if (accessedContext in enumMemberProperties || accessedContext in enumEntries) { if (accessedContext in enumMemberProperties || accessedContext in enumEntries) {
if (calleeSymbol is FirProperty) { if (calleeSymbol is FirPropertySymbol) {
// From KT-11769 // From KT-11769
// enum class Fruit(...) { // enum class Fruit(...) {
// APPLE(...); // APPLE(...);
@@ -151,7 +153,7 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
// } // }
// val score = ... <!>common<!> // val score = ... <!>common<!>
// } // }
reporter.reportOn(source, FirErrors.UNINITIALIZED_VARIABLE, calleeSymbol.symbol, context) reporter.reportOn(source, FirErrors.UNINITIALIZED_VARIABLE, calleeSymbol, context)
} else { } else {
// enum class EnumCompanion2(...) { // enum class EnumCompanion2(...) {
// INSTANCE(<!>foo<!>()) // INSTANCE(<!>foo<!>())
@@ -219,11 +221,13 @@ object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
private val FirPropertySymbol.lazyDelegation: FirAnonymousFunction? private val FirPropertySymbol.lazyDelegation: FirAnonymousFunction?
get() { get() {
ensureResolved(FirResolvePhase.BODY_RESOLVE) ensureResolved(FirResolvePhase.BODY_RESOLVE)
if (fir.delegate == null || fir.delegate !is FirFunctionCall) return null @OptIn(SymbolInternals::class)
val delegateCall = fir.delegate as FirFunctionCall val property = this.fir
val callee = if (property.delegate == null || property.delegate !is FirFunctionCall) return null
(delegateCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirSimpleFunction ?: return null val delegateCall = property.delegate as FirFunctionCall
if (callee.symbol.callableId.asSingleFqName().asString() != "kotlin.lazy") return null val calleeSymbol =
(delegateCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol ?: return null
if (calleeSymbol.callableId.asSingleFqName().asString() != "kotlin.lazy") return null
val lazyCallArgument = delegateCall.argumentList.arguments.singleOrNull() as? FirLambdaArgumentExpression ?: return null val lazyCallArgument = delegateCall.argumentList.arguments.singleOrNull() as? FirLambdaArgumentExpression ?: return null
return (lazyCallArgument.expression as? FirAnonymousFunctionExpression)?.anonymousFunction return (lazyCallArgument.expression as? FirAnonymousFunctionExpression)?.anonymousFunction
} }
@@ -10,15 +10,17 @@ import org.jetbrains.kotlin.fir.analysis.checkers.checkUpperBoundViolated
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChecker() { object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -27,9 +29,9 @@ object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChec
// it may be the called function declaration // it may be the called function declaration
// or the class declaration // or the class declaration
val calleReference = expression.calleeReference val calleReference = expression.calleeReference
var calleeFir: FirTypeParameterRefsOwner? = null var calleeSymbol: FirCallableSymbol<*>? = null
if (calleReference is FirResolvedNamedReference) { if (calleReference is FirResolvedNamedReference) {
calleeFir = calleReference.safeAs<FirResolvedNamedReference>()?.resolvedSymbol?.fir as? FirTypeParameterRefsOwner calleeSymbol = calleReference.toResolvedCallableSymbol()
} else if (calleReference is FirErrorNamedReference) { } else if (calleReference is FirErrorNamedReference) {
val diagnostic = calleReference.diagnostic val diagnostic = calleReference.diagnostic
if (diagnostic is ConeInapplicableCandidateError && if (diagnostic is ConeInapplicableCandidateError &&
@@ -37,19 +39,19 @@ object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChec
) { ) {
return return
} }
calleeFir = calleReference.candidateSymbol?.fir as? FirTypeParameterRefsOwner calleeSymbol = calleReference.candidateSymbol as? FirCallableSymbol<*>
} }
var typeArguments: List<Any>? = null var typeArguments: List<Any>? = null
var typeArgumentRefsAndSources: List<FirTypeRefSource?>? = null var typeArgumentRefsAndSources: List<FirTypeRefSource?>? = null
val typeParameters = if (calleeFir is FirConstructor) { val typeParameters = if (calleeSymbol is FirConstructorSymbol) {
typeArgumentRefsAndSources = typeArgumentRefsAndSources =
expression.typeArguments.map { FirTypeRefSource((it as? FirTypeProjectionWithVariance)?.typeRef, it.source) } expression.typeArguments.map { FirTypeRefSource((it as? FirTypeProjectionWithVariance)?.typeRef, it.source) }
val prototypeClass = calleeFir.dispatchReceiverType?.toSymbol(context.session)?.fir.safeAs<FirRegularClass>() val prototypeClass = calleeSymbol.dispatchReceiverType?.toSymbol(context.session) as? FirRegularClassSymbol
prototypeClass?.typeParameters?.map { it.symbol } prototypeClass?.typeParameterSymbols
} else { } else {
typeArguments = expression.typeArguments typeArguments = expression.typeArguments
calleeFir?.typeParameters?.map { it.symbol } calleeSymbol?.typeParameterSymbols
} }
checkUpperBoundViolated( checkUpperBoundViolated(
@@ -6,13 +6,13 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isFunctionForExpectTypeFromCastFeature
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionForExpectTypeFromCastFeature import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -68,8 +68,8 @@ object FirUselessTypeOperationCallChecker : FirTypeOperatorCallChecker() {
): Boolean { ): Boolean {
return if (shouldCheckForExactType) { return if (shouldCheckForExactType) {
if (arg is FirFunctionCall) { if (arg is FirFunctionCall) {
val function = arg.toResolvedCallableSymbol()?.fir as? FirFunction val functionSymbol = arg.toResolvedCallableSymbol() as? FirFunctionSymbol<*>
if (function != null && function.isFunctionForExpectTypeFromCastFeature()) return false if (functionSymbol != null && functionSymbol.isFunctionForExpectTypeFromCastFeature()) return false
} }
isExactTypeCast(context, candidateType, targetType) isExactTypeCast(context, candidateType, targetType)
@@ -12,11 +12,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirBackingFieldReference import org.jetbrains.kotlin.fir.references.FirBackingFieldReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
object FirValReassignmentChecker : FirVariableAssignmentChecker() { object FirValReassignmentChecker : FirVariableAssignmentChecker() {
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -30,16 +30,16 @@ object FirValReassignmentChecker : FirVariableAssignmentChecker() {
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return
val property = backingFieldReference.resolvedSymbol.fir val propertySymbol = backingFieldReference.resolvedSymbol
if (property.isVar) return if (propertySymbol.isVar) return
val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter } ?: return val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter }?.symbol ?: return
if (property.getter != closestGetter) return if (propertySymbol.getterSymbol != closestGetter) return
backingFieldReference.source?.let { backingFieldReference.source?.let {
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField)) { if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField)) {
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, property.symbol, context) reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, propertySymbol, context)
} else { } else {
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, property.symbol, context) reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context)
} }
} }
} }
@@ -49,7 +49,7 @@ object FirValReassignmentChecker : FirVariableAssignmentChecker() {
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter
) { ) {
val valueParameter = (expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirValueParameter ?: return val valueParameter = (expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirValueParameterSymbol ?: return
reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter.symbol, context) reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context)
} }
} }
@@ -39,7 +39,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
graph.traverse(TraverseDirection.Forward, reporterVisitor) graph.traverse(TraverseDirection.Forward, reporterVisitor)
for (property in unprocessedProperties) { for (property in unprocessedProperties) {
val source = property.fir.source val source = property.source
if (source is FirFakeSourceElement) continue if (source is FirFakeSourceElement) continue
if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) continue if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) continue
propertiesCharacteristics[property] = EventOccurrencesRange.ZERO propertiesCharacteristics[property] = EventOccurrencesRange.ZERO
@@ -50,7 +50,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
var lastDestructuredVariables = 0 var lastDestructuredVariables = 0
for ((symbol, value) in propertiesCharacteristics) { for ((symbol, value) in propertiesCharacteristics) {
val source = symbol.fir.source val source = symbol.source
if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) { if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) {
lastDestructuringSource = source lastDestructuringSource = source
lastDestructuredVariables = symbol.getDestructuringChildrenCount() ?: continue lastDestructuredVariables = symbol.getDestructuringChildrenCount() ?: continue
@@ -67,14 +67,14 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
destructuringCanBeVal = false destructuringCanBeVal = false
} }
lastDestructuredVariables-- lastDestructuredVariables--
} else if (canBeVal(symbol, value) && symbol.fir.delegate == null) { } else if (canBeVal(symbol, value) && !symbol.hasDelegate) {
reporter.reportOn(source, FirErrors.CAN_BE_VAL, context) reporter.reportOn(source, FirErrors.CAN_BE_VAL, context)
} }
} }
} }
private fun canBeVal(symbol: FirPropertySymbol, value: EventOccurrencesRange) = private fun canBeVal(symbol: FirPropertySymbol, value: EventOccurrencesRange) =
value in canBeValOccurrenceRanges && symbol.fir.isVar value in canBeValOccurrenceRanges && symbol.isVar
private class UninitializedPropertyReporter( private class UninitializedPropertyReporter(
val data: Map<CFGNode<*>, PathAwarePropertyInitializationInfo>, val data: Map<CFGNode<*>, PathAwarePropertyInitializationInfo>,
@@ -106,7 +106,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
} }
private fun FirPropertySymbol.getDestructuringChildrenCount(): Int? { private fun FirPropertySymbol.getDestructuringChildrenCount(): Int? {
val source = fir.source ?: return null val source = source ?: return null
return source.lighterASTNode.getChildren(source.treeStructure).count { return source.lighterASTNode.getChildren(source.treeStructure).count {
it?.tokenType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY it?.tokenType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY
} }
@@ -75,7 +75,7 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
} }
this is FirConstructor -> { this is FirConstructor -> {
val classSymbol = this.getContainingClassSymbol(context) val classSymbol = this.getContainingClassSymbol(context.session)
if ( if (
classSymbol is FirRegularClassSymbol classSymbol is FirRegularClassSymbol
&& (classSymbol.isEnumClass || classSymbol.isSealed) && (classSymbol.isEnumClass || classSymbol.isSealed)
@@ -99,30 +99,16 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
val overriddenFunctions = function.overriddenFunctions(currentClass, context) val overriddenFunctions = function.overriddenFunctions(currentClass, context)
var visibility: Visibility = Visibilities.Private var visibility: Visibility = Visibilities.Private
for (func in overriddenFunctions) { for (func in overriddenFunctions) {
val currentVisibility = func.fir.visibility() val currentVisibility = func.visibility
if (currentVisibility != null) { val compareResult = Visibilities.compare(currentVisibility, visibility)
val compareResult = Visibilities.compare(currentVisibility, visibility) if (compareResult != null && compareResult > 0) {
if (compareResult != null && compareResult > 0) { visibility = currentVisibility
visibility = currentVisibility
}
} }
} }
return visibility return visibility
} }
private fun FirFunction.visibility(): Visibility? {
(symbol.fir as? FirMemberDeclaration)?.visibility?.let {
return it
}
(symbol.fir as? FirPropertyAccessor)?.visibility?.let {
return it
}
return null
}
private val CheckerContext.containingPropertyVisibility private val CheckerContext.containingPropertyVisibility
get() = (this.containingDeclarations.last() as? FirProperty)?.visibility get() = (this.containingDeclarations.last() as? FirProperty)?.visibility
} }
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.isIterator
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
@@ -26,13 +27,15 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.* import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
object UnusedChecker : FirControlFlowChecker() { object UnusedChecker : FirControlFlowChecker() {
override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) { override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) {
if (graph.declaration?.getContainingClassSymbol(context)?.takeIf { !it.isLocal } != null) return if (graph.declaration?.getContainingClassSymbol(context.session)?.takeIf { !it.isLocal } != null) return
val (properties, _) = LocalPropertyAndCapturedWriteCollector.collect(graph) val (properties, _) = LocalPropertyAndCapturedWriteCollector.collect(graph)
if (properties.isEmpty()) return if (properties.isEmpty()) return
@@ -69,7 +72,10 @@ object UnusedChecker : FirControlFlowChecker() {
for (dataPerLabel in dataPerNode.values) { for (dataPerLabel in dataPerNode.values) {
val data = dataPerLabel[variableSymbol] ?: continue val data = dataPerLabel[variableSymbol] ?: continue
val variableSource = variableSymbol.fir.source.takeIf { it?.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION } variableSymbol.ensureResolved(FirResolvePhase.BODY_RESOLVE)
@OptIn(SymbolInternals::class)
val variable = variableSymbol.fir
val variableSource = variable.source.takeIf { it?.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION }
when { when {
data == VariableStatus.UNUSED -> { data == VariableStatus.UNUSED -> {
if ((node.fir.initializer as? FirFunctionCall)?.isIterator != true) { if ((node.fir.initializer as? FirFunctionCall)?.isIterator != true) {
@@ -78,7 +84,7 @@ object UnusedChecker : FirControlFlowChecker() {
} }
} }
data.isRedundantInit -> { data.isRedundantInit -> {
val source = variableSymbol.fir.initializer?.source val source = variable.initializer?.source
reporter.reportOn(source, FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT, context) reporter.reportOn(source, FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT, context)
break break
} }
@@ -276,7 +282,7 @@ object UnusedChecker : FirControlFlowChecker() {
val reference = node.fir.calleeReference as? FirResolvedNamedReference ?: return dataForNode val reference = node.fir.calleeReference as? FirResolvedNamedReference ?: return dataForNode
val functionSymbol = reference.resolvedSymbol as? FirFunctionSymbol<*> ?: return dataForNode val functionSymbol = reference.resolvedSymbol as? FirFunctionSymbol<*> ?: return dataForNode
val symbol = if (functionSymbol.callableId.callableName.identifier == "invoke") { val symbol = if (functionSymbol.callableId.callableName.identifier == "invoke") {
localProperties.find { it.fir.name == reference.name && it.fir.returnTypeRef.coneType.isFunctionalType(session) } localProperties.find { it.name == reference.name && it.resolvedReturnTypeRef.coneType.isFunctionalType(session) }
} else null } else null
symbol ?: return dataForNode symbol ?: return dataForNode
@@ -307,6 +313,9 @@ object UnusedChecker : FirControlFlowChecker() {
} }
} }
private val FirPropertySymbol.isLoopIterator private val FirPropertySymbol.isLoopIterator: Boolean
get() = fir.initializer?.source?.kind == FirFakeSourceElementKind.DesugaredForLoop get() {
@OptIn(SymbolInternals::class)
return fir.initializer?.source?.kind == FirFakeSourceElementKind.DesugaredForLoop
}
} }
@@ -16,15 +16,12 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.coneTypeSafe
object FirDeprecatedTypeChecker : FirTypeRefChecker() { object FirDeprecatedTypeChecker : FirTypeRefChecker() {
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
if (context.findClosest<FirPropertyAccessor>() != null) return if (context.findClosest<FirPropertyAccessor>() != null) return
val resolved = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return val resolved = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return
val symbol = resolved.lookupTag.toSymbol(context.session) ?: return val symbol = resolved.lookupTag.toSymbol(context.session) ?: return
val referencedFir = symbol.fir
FirDeprecationChecker.reportDeprecationIfNeeded(typeRef.source, referencedFir, null, context, reporter) FirDeprecationChecker.reportDeprecationIfNeeded(typeRef.source, symbol, null, context, reporter)
} }
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_POSITION_VARIANCE import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_POSITION_VARIANCE
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.commaSeparated import org.jetbrains.kotlin.diagnostics.rendering.Renderers.commaSeparated
@@ -15,7 +14,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
@@ -474,7 +472,7 @@ class FirDefaultErrorMessages {
map.put( map.put(
QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE, QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE,
"Explicitly qualified supertype is extended by another supertype ''{0}''", "Explicitly qualified supertype is extended by another supertype ''{0}''",
TO_STRING SYMBOL
) )
map.put(SUPERTYPE_INITIALIZED_IN_INTERFACE, "Interfaces cannot initialize supertypes") map.put(SUPERTYPE_INITIALIZED_IN_INTERFACE, "Interfaces cannot initialize supertypes")
map.put(INTERFACE_WITH_SUPERCLASS, "An interface cannot inherit from a class") map.put(INTERFACE_WITH_SUPERCLASS, "An interface cannot inherit from a class")
@@ -670,7 +668,7 @@ class FirDefaultErrorMessages {
map.put(NON_VARARG_SPREAD, "The spread operator (*foo) may only be applied in a vararg position") map.put(NON_VARARG_SPREAD, "The spread operator (*foo) may only be applied in a vararg position")
map.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", FQ_NAMES_IN_TYPES) map.put(TOO_MANY_ARGUMENTS, "Too many arguments for {0}", FQ_NAMES_IN_TYPES)
map.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter") map.put(ARGUMENT_PASSED_TWICE, "An argument is already passed for this parameter")
map.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter ''{0}''", NAME) map.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter ''{0}''", DECLARATION_NAME)
map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING) map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING)
map.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list") map.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list")
map.put(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type") map.put(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type")
@@ -798,7 +796,7 @@ class FirDefaultErrorMessages {
NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER, NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER,
"{0} does not refer to a type parameter of {1}", "{0} does not refer to a type parameter of {1}",
TO_STRING, TO_STRING,
NAME DECLARATION_NAME
) )
map.put(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED, "Bounds are not allowed on type alias parameters") map.put(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED, "Bounds are not allowed on type alias parameters")
@@ -826,7 +824,7 @@ class FirDefaultErrorMessages {
map.put( map.put(
EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED, EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED,
"''{0}'' is a member and an extension at the same time. References to such elements are not allowed", "''{0}'' is a member and an extension at the same time. References to such elements are not allowed",
NAME DECLARATION_NAME
) )
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of a callable reference cannot be a type parameter") map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of a callable reference cannot be a type parameter")
map.put(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, "Annotation class cannot be instantiated") map.put(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, "Annotation class cannot be instantiated")
@@ -872,20 +870,20 @@ class FirDefaultErrorMessages {
FQ_NAMES_IN_TYPES FQ_NAMES_IN_TYPES
) )
map.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, TO_STRING) map.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", DECLARATION_NAME, TO_STRING)
map.put( map.put(
CANNOT_WEAKEN_ACCESS_PRIVILEGE, CANNOT_WEAKEN_ACCESS_PRIVILEGE,
"Cannot weaken access privilege ''{0}'' for ''{1}'' in ''{2}''", "Cannot weaken access privilege ''{0}'' for ''{1}'' in ''{2}''",
VISIBILITY, VISIBILITY,
NAME, DECLARATION_NAME,
TO_STRING TO_STRING
) )
map.put( map.put(
CANNOT_CHANGE_ACCESS_PRIVILEGE, CANNOT_CHANGE_ACCESS_PRIVILEGE,
"Cannot change access privilege ''{0}'' for ''{1}'' in ''{2}''", "Cannot change access privilege ''{0}'' for ''{1}'' in ''{2}''",
VISIBILITY, VISIBILITY,
NAME, DECLARATION_NAME,
TO_STRING TO_STRING
) )
@@ -893,25 +891,25 @@ class FirDefaultErrorMessages {
ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED,
"{0} is not abstract and does not implement abstract member {1}", "{0} is not abstract and does not implement abstract member {1}",
RENDER_CLASS_OR_OBJECT, RENDER_CLASS_OR_OBJECT,
NAME DECLARATION_NAME
) )
map.put( map.put(
ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED,
"{0} is not abstract and does not implement abstract base class member {1}", "{0} is not abstract and does not implement abstract base class member {1}",
RENDER_CLASS_OR_OBJECT, RENDER_CLASS_OR_OBJECT,
NAME DECLARATION_NAME
) )
map.put( map.put(
MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED,
"{0} must override {1} because it inherits many implementations of it", "{0} must override {1} because it inherits many implementations of it",
RENDER_CLASS_OR_OBJECT, RENDER_CLASS_OR_OBJECT,
NAME DECLARATION_NAME
) )
map.put( map.put(
MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED,
"{0} must override {1} because it inherits multiple interface methods of it", "{0} must override {1} because it inherits multiple interface methods of it",
RENDER_CLASS_OR_OBJECT, RENDER_CLASS_OR_OBJECT,
NAME DECLARATION_NAME
) )
map.put( map.put(
@@ -964,49 +962,49 @@ class FirDefaultErrorMessages {
map.put( map.put(
RETURN_TYPE_MISMATCH_ON_INHERITANCE, RETURN_TYPE_MISMATCH_ON_INHERITANCE,
"''{0}'' clashes with ''{1}'': return types are incompatible", "''{0}'' clashes with ''{1}'': return types are incompatible",
NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put( map.put(
PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, PROPERTY_TYPE_MISMATCH_ON_INHERITANCE,
"''{0}'' clashes with ''{1}'': property types are incompatible", "''{0}'' clashes with ''{1}'': property types are incompatible",
NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put( map.put(
VAR_TYPE_MISMATCH_ON_INHERITANCE, VAR_TYPE_MISMATCH_ON_INHERITANCE,
"''{0}'' clashes with ''{1}'': property types do not match", "''{0}'' clashes with ''{1}'': property types do not match",
NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put( map.put(
RETURN_TYPE_MISMATCH_BY_DELEGATION, RETURN_TYPE_MISMATCH_BY_DELEGATION,
"Type of ''{0}'' is not a subtype of overridden by delegation ''{1}''", "Type of ''{0}'' is not a subtype of overridden by delegation ''{1}''",
NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put( map.put(
PROPERTY_TYPE_MISMATCH_BY_DELEGATION, PROPERTY_TYPE_MISMATCH_BY_DELEGATION,
"Type of property ''{0}'' is not a subtype of overridden by delegation ''{1}''", "Type of property ''{0}'' is not a subtype of overridden by delegation ''{1}''",
NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put( map.put(
VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION,
"Val-property ''{0}'' implicitly overrides a var-property ''{1}'' by delegation", "Val-property ''{0}'' implicitly overrides a var-property ''{1}'' by delegation",
NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put( map.put(
CONFLICTING_INHERITED_MEMBERS, CONFLICTING_INHERITED_MEMBERS,
"{0} inherits conflicting members: {1}", "{0} inherits conflicting members: {1}",
commaSeparated(NAME) commaSeparated(DECLARATION_NAME)
) )
// Redeclarations // Redeclarations
@@ -1032,7 +1030,7 @@ class FirDefaultErrorMessages {
ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS,
"Abstract function ''{0}'' in non-abstract class ''{1}''", "Abstract function ''{0}'' in non-abstract class ''{1}''",
DECLARATION_NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put(ABSTRACT_FUNCTION_WITH_BODY, "A function ''{0}'' with body cannot be abstract", DECLARATION_NAME) map.put(ABSTRACT_FUNCTION_WITH_BODY, "A function ''{0}'' with body cannot be abstract", DECLARATION_NAME)
map.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, "Function ''{0}'' without a body must be abstract", DECLARATION_NAME) map.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, "Function ''{0}'' without a body must be abstract", DECLARATION_NAME)
@@ -1068,7 +1066,7 @@ class FirDefaultErrorMessages {
ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS,
"Abstract property ''{0}'' in non-abstract class ''{1}''", "Abstract property ''{0}'' in non-abstract class ''{1}''",
DECLARATION_NAME, DECLARATION_NAME,
NAME DECLARATION_NAME
) )
map.put(PRIVATE_PROPERTY_IN_INTERFACE, "Abstract property in an interface cannot be private") map.put(PRIVATE_PROPERTY_IN_INTERFACE, "Abstract property in an interface cannot be private")
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.diagnostics.rendering.Renderer import org.jetbrains.kotlin.diagnostics.rendering.Renderer
@@ -14,10 +15,8 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.render import org.jetbrains.kotlin.fir.types.render
@@ -50,43 +49,33 @@ object FirDiagnosticRenderers {
} }
val VARIABLE_NAME = Renderer { symbol: FirVariableSymbol<*> -> val VARIABLE_NAME = Renderer { symbol: FirVariableSymbol<*> ->
symbol.fir.name.asString() symbol.name.asString()
} }
val FIR = Renderer { element: FirElement -> val FIR = Renderer { element: FirElement ->
element.render() element.render()
} }
val NAME = Renderer { element: FirElement ->
when (element) {
is FirMemberDeclaration -> DECLARATION_NAME.render(element)
is FirCallableDeclaration -> element.symbol.callableId.callableName.asString()
else -> "???"
}
}
val VISIBILITY = Renderer { visibility: Visibility -> val VISIBILITY = Renderer { visibility: Visibility ->
visibility.externalDisplayName visibility.externalDisplayName
} }
val DECLARATION_NAME = Renderer { declaration: FirMemberDeclaration -> val DECLARATION_NAME = Renderer { symbol: FirBasedSymbol<*> ->
val name = when (declaration) { val name = when (symbol) {
is FirProperty -> declaration.name is FirCallableSymbol<*> -> symbol.name
is FirSimpleFunction -> declaration.name is FirClassLikeSymbol<*> -> symbol.classId.shortClassName
is FirRegularClass -> declaration.name
is FirTypeAlias -> declaration.name
is FirEnumEntry -> declaration.name
is FirField -> declaration.name
is FirValueParameter -> declaration.name
is FirConstructor -> return@Renderer "constructor"
else -> return@Renderer "???" else -> return@Renderer "???"
} }
name.asString() name.asString()
} }
val RENDER_CLASS_OR_OBJECT = Renderer { firClass: FirClass -> val RENDER_CLASS_OR_OBJECT = Renderer { classSymbol: FirClassSymbol<*> ->
val name = firClass.classId.relativeClassName.asString() val name = classSymbol.classId.relativeClassName.asString()
val classOrObject = if (firClass is FirRegularClass) "Class" else "Object" val classOrObject = when (classSymbol.classKind) {
ClassKind.OBJECT -> "Object"
ClassKind.INTERFACE -> "Interface"
else -> "Class"
}
"$classOrObject $name" "$classOrObject $name"
} }
@@ -95,8 +84,9 @@ object FirDiagnosticRenderers {
t.render() t.render()
} }
val FQ_NAMES_IN_TYPES = Renderer { element: FirElement -> val FQ_NAMES_IN_TYPES = Renderer { symbol: FirBasedSymbol<*> ->
element.render(mode = FirRenderer.RenderMode.WithFqNamesExceptAnnotationAndBody) @OptIn(SymbolInternals::class)
symbol.fir.render(mode = FirRenderer.RenderMode.WithFqNamesExceptAnnotationAndBody)
} }
val AMBIGUOUS_CALLS = Renderer { candidates: Collection<FirBasedSymbol<*>> -> val AMBIGUOUS_CALLS = Renderer { candidates: Collection<FirBasedSymbol<*>> ->
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.getChild import org.jetbrains.kotlin.fir.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.isInfix import org.jetbrains.kotlin.fir.declarations.utils.isInfix
import org.jetbrains.kotlin.fir.declarations.utils.isOperator import org.jetbrains.kotlin.fir.declarations.utils.isOperator
import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.diagnostics.*
@@ -21,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPo
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private fun ConeDiagnostic.toFirDiagnostic( private fun ConeDiagnostic.toFirDiagnostic(
source: FirSourceElement, source: FirSourceElement,
@@ -63,10 +62,10 @@ private fun ConeDiagnostic.toFirDiagnostic(
is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.createOn(source, this.candidates) is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.createOn(source, this.candidates)
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.createOn(source) is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.createOn(source)
is ConeValReassignmentError -> when (val symbol = this.variable) { is ConeValReassignmentError -> when (val symbol = this.variable) {
is FirBackingFieldSymbol -> FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR.createOn(source, symbol.fir.symbol) is FirBackingFieldSymbol -> FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR.createOn(source, symbol)
else -> FirErrors.VAL_REASSIGNMENT.createOn(source, symbol) else -> FirErrors.VAL_REASSIGNMENT.createOn(source, symbol)
} }
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source as? FirSourceElement ?: source) is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source ?: source)
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString()) is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
is ConeWrongNumberOfTypeArgumentsError -> is ConeWrongNumberOfTypeArgumentsError ->
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type) FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
@@ -109,13 +108,13 @@ private fun mapUnsafeCallError(
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType) return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType)
} }
val candidateFunction = candidate.symbol.fir as? FirSimpleFunction val candidateFunctionSymbol = candidate.symbol as? FirNamedFunctionSymbol
val candidateFunctionName = candidateFunction?.name val candidateFunctionName = candidateFunctionSymbol?.name
val receiverExpression = candidate.callInfo.explicitReceiver val receiverExpression = candidate.callInfo.explicitReceiver
val singleArgument = candidate.callInfo.argumentList.arguments.singleOrNull() val singleArgument = candidate.callInfo.argumentList.arguments.singleOrNull()
if (receiverExpression != null && singleArgument != null && if (receiverExpression != null && singleArgument != null &&
(source.elementType == KtNodeTypes.OPERATION_REFERENCE || source.elementType == KtNodeTypes.BINARY_EXPRESSION) && (source.elementType == KtNodeTypes.OPERATION_REFERENCE || source.elementType == KtNodeTypes.BINARY_EXPRESSION) &&
(candidateFunction?.isOperator == true || candidateFunction?.isInfix == true) (candidateFunctionSymbol?.isOperator == true || candidateFunctionSymbol?.isInfix == true)
) { ) {
// For augmented assignment operations (e.g., `a += b`), the source is the entire binary expression (BINARY_EXPRESSION). // For augmented assignment operations (e.g., `a += b`), the source is the entire binary expression (BINARY_EXPRESSION).
// TODO: No need to check for source.elementType == BINARY_EXPRESSION if we use operator as callee reference source // TODO: No need to check for source.elementType == BINARY_EXPRESSION if we use operator as callee reference source
@@ -174,8 +173,8 @@ private fun mapInapplicableCandidateError(
) )
is NonVarargSpread -> FirErrors.NON_VARARG_SPREAD.createOn(rootCause.argument.source?.getChild(KtTokens.MUL, depth = 1)!!) is NonVarargSpread -> FirErrors.NON_VARARG_SPREAD.createOn(rootCause.argument.source?.getChild(KtTokens.MUL, depth = 1)!!)
is ArgumentPassedTwice -> FirErrors.ARGUMENT_PASSED_TWICE.createOn(rootCause.argument.source) is ArgumentPassedTwice -> FirErrors.ARGUMENT_PASSED_TWICE.createOn(rootCause.argument.source)
is TooManyArguments -> FirErrors.TOO_MANY_ARGUMENTS.createOn(rootCause.argument.source ?: source, rootCause.function) is TooManyArguments -> FirErrors.TOO_MANY_ARGUMENTS.createOn(rootCause.argument.source ?: source, rootCause.function.symbol)
is NoValueForParameter -> FirErrors.NO_VALUE_FOR_PARAMETER.createOn(qualifiedAccessSource ?: source, rootCause.valueParameter) is NoValueForParameter -> FirErrors.NO_VALUE_FOR_PARAMETER.createOn(qualifiedAccessSource ?: source, rootCause.valueParameter.symbol)
is NameNotFound -> FirErrors.NAMED_PARAMETER_NOT_FOUND.createOn( is NameNotFound -> FirErrors.NAMED_PARAMETER_NOT_FOUND.createOn(
rootCause.argument.source ?: source, rootCause.argument.source ?: source,
rootCause.argument.name.asString() rootCause.argument.name.asString()
@@ -184,7 +183,7 @@ private fun mapInapplicableCandidateError(
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.createOn(rootCause.argument.source ?: source) is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.createOn(rootCause.argument.source ?: source)
is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.createOn(source, rootCause.function) is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.createOn(source, rootCause.function)
is OperatorCallOfNonOperatorFunction -> is OperatorCallOfNonOperatorFunction ->
FirErrors.OPERATOR_MODIFIER_REQUIRED.createOn(source, rootCause.function, rootCause.function.fir.name.asString()) FirErrors.OPERATOR_MODIFIER_REQUIRED.createOn(source, rootCause.function, rootCause.function.name.asString())
is UnstableSmartCast -> FirErrors.SMARTCAST_IMPOSSIBLE.createOn( is UnstableSmartCast -> FirErrors.SMARTCAST_IMPOSSIBLE.createOn(
rootCause.argument.source, rootCause.argument.source,
rootCause.targetType, rootCause.targetType,
@@ -12,6 +12,10 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
@@ -26,10 +30,10 @@ private val LEVEL_NAME = Name.identifier("level")
private val JAVA_ORIGINS = setOf(FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement) private val JAVA_ORIGINS = setOf(FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement)
fun FirAnnotatedDeclaration.getDeprecation(callSite: FirElement?): Deprecation? { fun FirBasedSymbol<*>.getDeprecation(callSite: FirElement?): Deprecation? {
val deprecationInfos = mutableListOf<Deprecation>() val deprecationInfos = mutableListOf<Deprecation>()
when (this) { when (this) {
is FirProperty -> is FirPropertySymbol ->
if (callSite is FirVariableAssignment) { if (callSite is FirVariableAssignment) {
deprecationInfos.addIfNotNull( deprecationInfos.addIfNotNull(
getDeprecationForCallSite(AnnotationUseSiteTarget.PROPERTY_SETTER, AnnotationUseSiteTarget.PROPERTY) getDeprecationForCallSite(AnnotationUseSiteTarget.PROPERTY_SETTER, AnnotationUseSiteTarget.PROPERTY)
@@ -75,12 +79,12 @@ fun List<FirAnnotationCall>.getDeprecationInfosFromAnnotations(currentVersion: A
return DeprecationsPerUseSite.fromMap(deprecationByUseSite) return DeprecationsPerUseSite.fromMap(deprecationByUseSite)
} }
private fun FirAnnotatedDeclaration.getDeprecationForCallSite( private fun FirBasedSymbol<*>.getDeprecationForCallSite(
vararg sites: AnnotationUseSiteTarget vararg sites: AnnotationUseSiteTarget
): Deprecation? { ): Deprecation? {
val deprecations = when (this) { val deprecations = when (this) {
is FirCallableDeclaration -> deprecation is FirCallableSymbol<*> -> deprecation
is FirClassLikeDeclaration -> deprecation is FirClassLikeSymbol<*> -> deprecation
else -> null else -> null
} }
return (deprecations ?: EmptyDeprecationsPerUseSite).forUseSite(*sites) return (deprecations ?: EmptyDeprecationsPerUseSite).forUseSite(*sites)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.lookupTracker import org.jetbrains.kotlin.fir.lookupTracker
@@ -197,7 +198,7 @@ fun Candidate.resolveSubCallArgument(
* It's important to extract type from argument neither from symbol, because of symbol contains * It's important to extract type from argument neither from symbol, because of symbol contains
* placeholder type with value 0, but argument contains type with proper literal value * placeholder type with value 0, but argument contains type with proper literal value
*/ */
val type: ConeKotlinType = context.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).type val type: ConeKotlinType = context.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.fir as FirTypedDeclaration).type
val argumentType = candidate.substitutor.substituteOrSelf(type) val argumentType = candidate.substitutor.substituteOrSelf(type)
resolvePlainArgumentType( resolvePlainArgumentType(
csBuilder, csBuilder,
@@ -297,8 +297,8 @@ internal object CheckCallModifiers : CheckerStage() {
internal object CheckDeprecatedSinceKotlin : ResolutionStage() { internal object CheckDeprecatedSinceKotlin : ResolutionStage() {
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
val fir = (candidate.symbol as? FirCallableSymbol<*>)?.fir ?: return val symbol = candidate.symbol as? FirCallableSymbol<*> ?: return
val deprecation = fir.getDeprecation(callInfo.callSite) val deprecation = symbol.getDeprecation(callInfo.callSite)
if (deprecation != null && deprecation.level == DeprecationLevelValue.HIDDEN) { if (deprecation != null && deprecation.level == DeprecationLevelValue.HIDDEN) {
sink.yieldDiagnostic(HiddenCandidate) sink.yieldDiagnostic(HiddenCandidate)
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.calls.tower package org.jetbrains.kotlin.fir.resolve.calls.tower
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessExpressionBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessExpressionBuilder
@@ -284,7 +285,7 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
candidate candidate
) )
dispatchReceiver = candidate.dispatchReceiverExpression() dispatchReceiver = candidate.dispatchReceiverExpression()
this.typeRef = returnTypeCalculator.tryCalculateReturnType(symbol.firUnsafe()) this.typeRef = returnTypeCalculator.tryCalculateReturnType(symbol.fir as FirTypedDeclaration)
if (!invokeBuiltinExtensionMode) { if (!invokeBuiltinExtensionMode) {
extensionReceiver = extensionReceiverExpression extensionReceiver = extensionReceiverExpression
@@ -308,7 +308,7 @@ private fun Candidate.isFunctionForExpectTypeFromCastFeature(): Boolean {
// Expect type is only being added to calls in a position of cast argument: foo() as R // Expect type is only being added to calls in a position of cast argument: foo() as R
// And that call should be resolved to something materialize()-like: it returns its single generic parameter and doesn't have value parameters // And that call should be resolved to something materialize()-like: it returns its single generic parameter and doesn't have value parameters
// fun <T> materialize(): T // fun <T> materialize(): T
fun FirFunction.isFunctionForExpectTypeFromCastFeature(): Boolean { internal fun FirFunction.isFunctionForExpectTypeFromCastFeature(): Boolean {
val typeParameter = typeParameters.singleOrNull() ?: return false val typeParameter = typeParameters.singleOrNull() ?: return false
val returnType = returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: return false val returnType = returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: return false
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.toEffectiveVisibility import org.jetbrains.kotlin.fir.toEffectiveVisibility
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
@@ -278,3 +280,9 @@ private fun FirDeclaration.hasOwnBodyOrAccessorBody(): Boolean {
private object PublishedApiEffectiveVisibilityKey : FirDeclarationDataKey() private object PublishedApiEffectiveVisibilityKey : FirDeclarationDataKey()
var FirDeclaration.publishedApiEffectiveVisibility: EffectiveVisibility? by FirDeclarationDataRegistry.data(PublishedApiEffectiveVisibilityKey) var FirDeclaration.publishedApiEffectiveVisibility: EffectiveVisibility? by FirDeclarationDataRegistry.data(PublishedApiEffectiveVisibilityKey)
inline val FirCallableSymbol<*>.publishedApiEffectiveVisibility: EffectiveVisibility?
get() {
ensureResolved(FirResolvePhase.STATUS)
return fir.publishedApiEffectiveVisibility
}
@@ -571,7 +571,7 @@ class SupertypeComputationSession {
} }
} }
fun FirTypeRef.firClassLike(session: FirSession): FirClassLikeDeclaration? { internal fun FirTypeRef.firClassLike(session: FirSession): FirClassLikeDeclaration? {
val type = coneTypeSafe<ConeClassLikeType>() ?: return null val type = coneTypeSafe<ConeClassLikeType>() ?: return null
return type.lookupTag.toSymbol(session)?.fir return type.lookupTag.toSymbol(session)?.fir
} }
@@ -10,11 +10,16 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
interface ReturnTypeCalculator { interface ReturnTypeCalculator {
fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef
fun tryCalculateReturnType(symbol: FirCallableSymbol<*>): FirResolvedTypeRef {
return tryCalculateReturnType(symbol.fir)
}
} }
class ReturnTypeCalculatorForFullBodyResolve : ReturnTypeCalculator { class ReturnTypeCalculatorForFullBodyResolve : ReturnTypeCalculator {
@@ -110,7 +110,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
} }
is FirDelegateFieldReference -> { is FirDelegateFieldReference -> {
val delegateFieldSymbol = callee.resolvedSymbol val delegateFieldSymbol = callee.resolvedSymbol
qualifiedAccessExpression.resultType = delegateFieldSymbol.delegate.typeRef qualifiedAccessExpression.resultType = delegateFieldSymbol.fir.delegate!!.typeRef
qualifiedAccessExpression qualifiedAccessExpression
} }
is FirResolvedNamedReference, is FirResolvedNamedReference,
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -93,6 +94,14 @@ fun FirClass.unsubstitutedScope(
return scope return scope
} }
fun FirClassSymbol<*>.unsubstitutedScope(
useSiteSession: FirSession,
scopeSession: ScopeSession,
withForcedTypeCalculator: Boolean
): FirTypeScope {
return fir.unsubstitutedScope(useSiteSession, scopeSession, withForcedTypeCalculator)
}
fun FirClass.scopeForClass( fun FirClass.scopeForClass(
substitutor: ConeSubstitutor, substitutor: ConeSubstitutor,
useSiteSession: FirSession, useSiteSession: FirSession,
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.resolve.declaredMemberScopeProvider import org.jetbrains.kotlin.fir.resolve.declaredMemberScopeProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.getOrPutNullable import org.jetbrains.kotlin.utils.getOrPutNullable
@@ -63,6 +64,10 @@ fun FirSession.declaredMemberScope(klass: FirClass): FirClassDeclaredMemberScope
.declaredMemberScope(klass, useLazyNestedClassifierScope = false, existingNames = null, symbolProvider = null) .declaredMemberScope(klass, useLazyNestedClassifierScope = false, existingNames = null, symbolProvider = null)
} }
fun FirSession.declaredMemberScope(klass: FirClassSymbol<*>): FirClassDeclaredMemberScope {
return declaredMemberScope(klass.fir)
}
fun FirSession.declaredMemberScopeWithLazyNestedScope( fun FirSession.declaredMemberScopeWithLazyNestedScope(
klass: FirClass, klass: FirClass,
existingNames: List<Name>, existingNames: List<Name>,
@@ -202,6 +202,9 @@ private object MultipleDelegatesWithTheSameSignatureKey : FirDeclarationDataKey(
var FirCallableDeclaration.multipleDelegatesWithTheSameSignature: Boolean? by FirDeclarationDataRegistry.data(MultipleDelegatesWithTheSameSignatureKey) var FirCallableDeclaration.multipleDelegatesWithTheSameSignature: Boolean? by FirDeclarationDataRegistry.data(MultipleDelegatesWithTheSameSignatureKey)
val FirCallableSymbol<*>.multipleDelegatesWithTheSameSignature: Boolean?
get() = fir.multipleDelegatesWithTheSameSignature
private object DelegatedWrapperDataKey : FirDeclarationDataKey() private object DelegatedWrapperDataKey : FirDeclarationDataKey()
class DelegatedWrapperData<D : FirCallableDeclaration>( class DelegatedWrapperData<D : FirCallableDeclaration>(
val wrapped: D, val wrapped: D,
@@ -211,6 +214,9 @@ class DelegatedWrapperData<D : FirCallableDeclaration>(
var <D : FirCallableDeclaration> var <D : FirCallableDeclaration>
D.delegatedWrapperData: DelegatedWrapperData<D>? by FirDeclarationDataRegistry.data(DelegatedWrapperDataKey) D.delegatedWrapperData: DelegatedWrapperData<D>? by FirDeclarationDataRegistry.data(DelegatedWrapperDataKey)
val <D : FirCallableDeclaration> FirCallableSymbol<out D>.delegatedWrapperData: DelegatedWrapperData<D>?
get() = fir.delegatedWrapperData
// From the definition of function interfaces in the Java specification (pt. 9.8): // From the definition of function interfaces in the Java specification (pt. 9.8):
// "methods that are members of I that do not have the same signature as any public instance method of the class Object" // "methods that are members of I that do not have the same signature as any public instance method of the class Object"
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -49,4 +50,6 @@ class FirNestedClassifierScope(val klass: FirClass, val useSiteSession: FirSessi
override fun getCallableNames(): Set<Name> = emptySet() override fun getCallableNames(): Set<Name> = emptySet()
} }
fun FirTypeParameterRef.toConeType(): ConeKotlinType = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(symbol), isNullable = false) fun FirTypeParameterRef.toConeType(): ConeKotlinType = symbol.toConeType()
fun FirTypeParameterSymbol.toConeType(): ConeKotlinType = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(this), isNullable = false)
@@ -39,9 +39,13 @@ private object ContainingClassKey : FirDeclarationDataKey()
var FirCallableDeclaration.containingClassAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) var FirCallableDeclaration.containingClassAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
var FirRegularClass.containingClassForLocalAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) var FirRegularClass.containingClassForLocalAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
val FirCallableDeclaration.isIntersectionOverride get() = origin == FirDeclarationOrigin.IntersectionOverride val FirCallableDeclaration.isIntersectionOverride: Boolean get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableDeclaration.isSubstitutionOverride get() = origin == FirDeclarationOrigin.SubstitutionOverride val FirCallableDeclaration.isSubstitutionOverride: Boolean get() = origin == FirDeclarationOrigin.SubstitutionOverride
val FirCallableDeclaration.isSubstitutionOrIntersectionOverride get() = isSubstitutionOverride || isIntersectionOverride val FirCallableDeclaration.isSubstitutionOrIntersectionOverride: Boolean get() = isSubstitutionOverride || isIntersectionOverride
val FirCallableSymbol<*>.isIntersectionOverride: Boolean get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableSymbol<*>.isSubstitutionOverride: Boolean get() = origin == FirDeclarationOrigin.SubstitutionOverride
val FirCallableSymbol<*>.isSubstitutionOrIntersectionOverride: Boolean get() = isSubstitutionOverride || isIntersectionOverride
inline val <reified D : FirCallableDeclaration> D.originalForSubstitutionOverride: D? inline val <reified D : FirCallableDeclaration> D.originalForSubstitutionOverride: D?
get() = if (isSubstitutionOverride) originalForSubstitutionOverrideAttr else null get() = if (isSubstitutionOverride) originalForSubstitutionOverrideAttr else null
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -57,6 +58,22 @@ fun FirClass.isPrimitiveNumberType(): Boolean = classId in PRIMITIVE_NUMBER_CLAS
fun FirClass.isPrimitiveUnsignedNumberType(): Boolean = classId in PRIMITIVE_UNSIGNED_NUMBER_CLASS_IDS fun FirClass.isPrimitiveUnsignedNumberType(): Boolean = classId in PRIMITIVE_UNSIGNED_NUMBER_CLASS_IDS
fun FirClass.isPrimitiveNumberOrUnsignedNumberType(): Boolean = isPrimitiveNumberType() || isPrimitiveUnsignedNumberType() fun FirClass.isPrimitiveNumberOrUnsignedNumberType(): Boolean = isPrimitiveNumberType() || isPrimitiveUnsignedNumberType()
// --------------------------- symbols ---------------------------
fun FirClassSymbol<*>.isDouble(): Boolean = classId == StandardClassIds.Double
fun FirClassSymbol<*>.isFloat(): Boolean = classId == StandardClassIds.Float
fun FirClassSymbol<*>.isLong(): Boolean = classId == StandardClassIds.Long
fun FirClassSymbol<*>.isInt(): Boolean = classId == StandardClassIds.Int
fun FirClassSymbol<*>.isShort(): Boolean = classId == StandardClassIds.Short
fun FirClassSymbol<*>.isByte(): Boolean = classId == StandardClassIds.Byte
fun FirClassSymbol<*>.isBoolean(): Boolean = classId == StandardClassIds.Boolean
fun FirClassSymbol<*>.isChar(): Boolean = classId == StandardClassIds.Char
fun FirClassSymbol<*>.isPrimitiveType(): Boolean = isPrimitiveNumberOrUnsignedNumberType() || isBoolean() || isByte() || isShort() || isChar()
fun FirClassSymbol<*>.isPrimitiveNumberType(): Boolean = classId in PRIMITIVE_NUMBER_CLASS_IDS
fun FirClassSymbol<*>.isPrimitiveUnsignedNumberType(): Boolean = classId in PRIMITIVE_UNSIGNED_NUMBER_CLASS_IDS
fun FirClassSymbol<*>.isPrimitiveNumberOrUnsignedNumberType(): Boolean = isPrimitiveNumberType() || isPrimitiveUnsignedNumberType()
private val PRIMITIVE_NUMBER_CLASS_IDS: Set<ClassId> = setOf( private val PRIMITIVE_NUMBER_CLASS_IDS: Set<ClassId> = setOf(
StandardClassIds.Double, StandardClassIds.Float, StandardClassIds.Long, StandardClassIds.Int, StandardClassIds.Double, StandardClassIds.Float, StandardClassIds.Long, StandardClassIds.Int,
StandardClassIds.Short, StandardClassIds.Byte StandardClassIds.Short, StandardClassIds.Byte
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
// ---------------------- callables with status ---------------------- // ---------------------- callables with status ----------------------
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir.diagnostics package org.jetbrains.kotlin.fir.diagnostics
class ConeUnexpectedTypeArgumentsError(override val reason: String, val source: Any? = null) : ConeDiagnostic() import org.jetbrains.kotlin.fir.FirSourceElement
class ConeUnexpectedTypeArgumentsError(override val reason: String, val source: FirSourceElement? = null) : ConeDiagnostic()
class ConeIntermediateDiagnostic(override val reason: String) : ConeDiagnostic() class ConeIntermediateDiagnostic(override val reason: String) : ConeDiagnostic()
@@ -20,6 +20,12 @@ sealed class FirClassLikeSymbol<D : FirClassLikeDeclaration>(
) : FirClassifierSymbol<D>() { ) : FirClassifierSymbol<D>() {
abstract override fun toLookupTag(): ConeClassLikeLookupTag abstract override fun toLookupTag(): ConeClassLikeLookupTag
val deprecation: DeprecationsPerUseSite?
get() {
ensureResolved(FirResolvePhase.STATUS)
return fir.deprecation
}
override fun toString(): String = "${this::class.simpleName} ${classId.asString()}" override fun toString(): String = "${this::class.simpleName} ${classId.asString()}"
} }
@@ -47,7 +47,10 @@ class FirIntersectionOverrideFunctionSymbol(
class FirConstructorSymbol( class FirConstructorSymbol(
callableId: CallableId callableId: CallableId
) : FirFunctionSymbol<FirConstructor>(callableId) ) : FirFunctionSymbol<FirConstructor>(callableId) {
val isPrimary: Boolean
get() = fir.isPrimary
}
open class FirAccessorSymbol( open class FirAccessorSymbol(
callableId: CallableId, callableId: CallableId,
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.test.utils.AbstractTwoAttributesMetaInfoProcessor
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
@OptIn(SymbolInternals::class)
class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(testServices) { class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
companion object { companion object {
private val allowedKindsForDebugInfo = setOf( private val allowedKindsForDebugInfo = setOf(
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.render import org.jetbrains.kotlin.fir.types.render
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.test.utils.withExtension
import org.jetbrains.kotlin.util.SmartPrinter import org.jetbrains.kotlin.util.SmartPrinter
import org.jetbrains.kotlin.util.withIndent import org.jetbrains.kotlin.util.withIndent
@OptIn(SymbolInternals::class)
class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testServices) { class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
private val dumper = MultiModuleInfoDumperImpl() private val dumper = MultiModuleInfoDumperImpl()
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.FirControlFlowGraphRenderVisitor import org.jetbrains.kotlin.fir.resolve.dfa.cfg.FirControlFlowGraphRenderVisitor
import org.jetbrains.kotlin.fir.resolve.transformers.createAllCompilerResolveProcessors import org.jetbrains.kotlin.fir.resolve.transformers.createAllCompilerResolveProcessors
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
@@ -55,6 +56,7 @@ import java.io.File
* After that you can run action `XDot` in editor with source of test (or with cfg dump) * After that you can run action `XDot` in editor with source of test (or with cfg dump)
* and it will opens xdot with dump for that test * and it will opens xdot with dump for that test
*/ */
@OptIn(SymbolInternals::class)
abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() { abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
companion object { companion object {
const val DUMP_CFG_DIRECTIVE = "DUMP_CFG" const val DUMP_CFG_DIRECTIVE = "DUMP_CFG"
@@ -137,7 +137,7 @@ private object FirToKtConversionCreator {
private val typeMapping: Map<KClass<*>, HLFunctionCallConversion> = mapOf( private val typeMapping: Map<KClass<*>, HLFunctionCallConversion> = mapOf(
FirBasedSymbol::class to HLFunctionCallConversion( FirBasedSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0}.fir as FirDeclaration)", "firSymbolBuilder.buildSymbol({0}.fir)",
KtSymbol::class.createType(), KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
), ),
@@ -145,6 +145,10 @@ private object FirToKtConversionCreator {
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})", "firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0})",
KtClassLikeSymbol::class.createType() KtClassLikeSymbol::class.createType()
), ),
FirClassSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}.fir)",
KtClassLikeSymbol::class.createType()
),
FirRegularClass::class to HLFunctionCallConversion( FirRegularClass::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}) as KtNamedClassOrObjectSymbol", "firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}) as KtNamedClassOrObjectSymbol",
KtNamedClassOrObjectSymbol::class.createType(), KtNamedClassOrObjectSymbol::class.createType(),
@@ -174,6 +178,15 @@ private object FirToKtConversionCreator {
KtSymbol::class.createType(), KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
), ),
FirValueParameterSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0}.fir)",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
FirEnumEntrySymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0}.fir)",
KtSymbol::class.createType(),
),
FirClassLikeSymbol::class to HLFunctionCallConversion( FirClassLikeSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}.fir as FirClass)", "firSymbolBuilder.classifierBuilder.buildClassLikeSymbol({0}.fir as FirClass)",
KtClassLikeSymbol::class.createType(), KtClassLikeSymbol::class.createType(),
@@ -194,6 +207,11 @@ private object FirToKtConversionCreator {
KtCallableSymbol::class.createType(), KtCallableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration")
), ),
FirCallableSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.callableBuilder.buildCallableSymbol({0}.fir)",
KtCallableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration")
),
FirTypeParameterSymbol::class to HLFunctionCallConversion( FirTypeParameterSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol({0}.fir)", "firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol({0}.fir)",
KtTypeParameterSymbol::class.createType(), KtTypeParameterSymbol::class.createType(),
@@ -217,6 +235,11 @@ private object FirToKtConversionCreator {
KtVariableSymbol::class.createType(), KtVariableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
), ),
FirBackingFieldSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir)",
KtVariableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
),
FirVariableSymbol::class to HLFunctionCallConversion( FirVariableSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.variableLikeBuilder.buildVariableLikeSymbol({0}.fir)", "firSymbolBuilder.variableLikeBuilder.buildVariableLikeSymbol({0}.fir)",
KtVariableLikeSymbol::class.createType(), KtVariableLikeSymbol::class.createType(),
@@ -10,7 +10,7 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.SmartPsiElementPointer import com.intellij.psi.SmartPsiElementPointer
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
@@ -242,7 +242,7 @@ private class FirShorteningContext(val firResolveState: FirModuleResolveState) {
} }
fun getRegularClass(typeRef: FirTypeRef): FirRegularClass? { fun getRegularClass(typeRef: FirTypeRef): FirRegularClass? {
return typeRef.toRegularClass(firSession) return typeRef.toRegularClassSymbol(firSession)?.fir
} }
fun toClassSymbol(classId: ClassId) = fun toClassSymbol(classId: ClassId) =
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpression
@@ -230,7 +229,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic -> add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic ->
InvisibleReferenceImpl( InvisibleReferenceImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -280,7 +279,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.DEPRECATION_ERROR) { firDiagnostic -> add(FirErrors.DEPRECATION_ERROR) { firDiagnostic ->
DeprecationErrorImpl( DeprecationErrorImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic.b, firDiagnostic.b,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -288,7 +287,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.DEPRECATION) { firDiagnostic -> add(FirErrors.DEPRECATION) { firDiagnostic ->
DeprecationImpl( DeprecationImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic.b, firDiagnostic.b,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -365,7 +364,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE) { firDiagnostic -> add(FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE) { firDiagnostic ->
QualifiedSupertypeExtendedByOtherSupertypeImpl( QualifiedSupertypeExtendedByOtherSupertypeImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -872,7 +871,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic -> add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic ->
ExposedTypealiasExpandedTypeImpl( ExposedTypealiasExpandedTypeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -881,7 +880,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_FUNCTION_RETURN_TYPE) { firDiagnostic -> add(FirErrors.EXPOSED_FUNCTION_RETURN_TYPE) { firDiagnostic ->
ExposedFunctionReturnTypeImpl( ExposedFunctionReturnTypeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -890,7 +889,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_RECEIVER_TYPE) { firDiagnostic -> add(FirErrors.EXPOSED_RECEIVER_TYPE) { firDiagnostic ->
ExposedReceiverTypeImpl( ExposedReceiverTypeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -899,7 +898,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_PROPERTY_TYPE) { firDiagnostic -> add(FirErrors.EXPOSED_PROPERTY_TYPE) { firDiagnostic ->
ExposedPropertyTypeImpl( ExposedPropertyTypeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -908,7 +907,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR) { firDiagnostic -> add(FirErrors.EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR) { firDiagnostic ->
ExposedPropertyTypeInConstructorImpl( ExposedPropertyTypeInConstructorImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -917,7 +916,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_PARAMETER_TYPE) { firDiagnostic -> add(FirErrors.EXPOSED_PARAMETER_TYPE) { firDiagnostic ->
ExposedParameterTypeImpl( ExposedParameterTypeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -926,7 +925,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_SUPER_INTERFACE) { firDiagnostic -> add(FirErrors.EXPOSED_SUPER_INTERFACE) { firDiagnostic ->
ExposedSuperInterfaceImpl( ExposedSuperInterfaceImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -935,7 +934,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_SUPER_CLASS) { firDiagnostic -> add(FirErrors.EXPOSED_SUPER_CLASS) { firDiagnostic ->
ExposedSuperClassImpl( ExposedSuperClassImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -944,7 +943,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.EXPOSED_TYPE_PARAMETER_BOUND) { firDiagnostic -> add(FirErrors.EXPOSED_TYPE_PARAMETER_BOUND) { firDiagnostic ->
ExposedTypeParameterBoundImpl( ExposedTypeParameterBoundImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1111,7 +1110,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.NONE_APPLICABLE) { firDiagnostic -> add(FirErrors.NONE_APPLICABLE) { firDiagnostic ->
NoneApplicableImpl( NoneApplicableImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1119,7 +1118,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.INAPPLICABLE_CANDIDATE) { firDiagnostic -> add(FirErrors.INAPPLICABLE_CANDIDATE) { firDiagnostic ->
InapplicableCandidateImpl( InapplicableCandidateImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1195,14 +1194,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.TOO_MANY_ARGUMENTS) { firDiagnostic -> add(FirErrors.TOO_MANY_ARGUMENTS) { firDiagnostic ->
TooManyArgumentsImpl( TooManyArgumentsImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.NO_VALUE_FOR_PARAMETER) { firDiagnostic -> add(FirErrors.NO_VALUE_FOR_PARAMETER) { firDiagnostic ->
NoValueForParameterImpl( NoValueForParameterImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1252,7 +1251,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic -> add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic ->
OverloadResolutionAmbiguityImpl( OverloadResolutionAmbiguityImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1261,7 +1260,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.ASSIGN_OPERATOR_AMBIGUITY) { firDiagnostic -> add(FirErrors.ASSIGN_OPERATOR_AMBIGUITY) { firDiagnostic ->
AssignOperatorAmbiguityImpl( AssignOperatorAmbiguityImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1270,7 +1269,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.ITERATOR_AMBIGUITY) { firDiagnostic -> add(FirErrors.ITERATOR_AMBIGUITY) { firDiagnostic ->
IteratorAmbiguityImpl( IteratorAmbiguityImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1279,7 +1278,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.HAS_NEXT_FUNCTION_AMBIGUITY) { firDiagnostic -> add(FirErrors.HAS_NEXT_FUNCTION_AMBIGUITY) { firDiagnostic ->
HasNextFunctionAmbiguityImpl( HasNextFunctionAmbiguityImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1288,7 +1287,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.NEXT_AMBIGUITY) { firDiagnostic -> add(FirErrors.NEXT_AMBIGUITY) { firDiagnostic ->
NextAmbiguityImpl( NextAmbiguityImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1480,7 +1479,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER) { firDiagnostic -> add(FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER) { firDiagnostic ->
NameInConstraintIsNotATypeParameterImpl( NameInConstraintIsNotATypeParameterImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1589,7 +1588,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic -> add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic ->
ExtensionInClassReferenceNotAllowedImpl( ExtensionInClassReferenceNotAllowedImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1627,23 +1626,23 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.NOTHING_TO_OVERRIDE) { firDiagnostic -> add(FirErrors.NOTHING_TO_OVERRIDE) { firDiagnostic ->
NothingToOverrideImpl( NothingToOverrideImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.CANNOT_OVERRIDE_INVISIBLE_MEMBER) { firDiagnostic -> add(FirErrors.CANNOT_OVERRIDE_INVISIBLE_MEMBER) { firDiagnostic ->
CannotOverrideInvisibleMemberImpl( CannotOverrideInvisibleMemberImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.DATA_CLASS_OVERRIDE_CONFLICT) { firDiagnostic -> add(FirErrors.DATA_CLASS_OVERRIDE_CONFLICT) { firDiagnostic ->
DataClassOverrideConflictImpl( DataClassOverrideConflictImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1651,7 +1650,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE) { firDiagnostic -> add(FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE) { firDiagnostic ->
CannotWeakenAccessPrivilegeImpl( CannotWeakenAccessPrivilegeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1660,7 +1659,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE) { firDiagnostic -> add(FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE) { firDiagnostic ->
CannotChangeAccessPrivilegeImpl( CannotChangeAccessPrivilegeImpl(
firDiagnostic.a, firDiagnostic.a,
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1668,7 +1667,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.OVERRIDING_FINAL_MEMBER) { firDiagnostic -> add(FirErrors.OVERRIDING_FINAL_MEMBER) { firDiagnostic ->
OverridingFinalMemberImpl( OverridingFinalMemberImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic.b, firDiagnostic.b,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1676,56 +1675,56 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic -> add(FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic ->
ReturnTypeMismatchOnInheritanceImpl( ReturnTypeMismatchOnInheritanceImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PROPERTY_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic -> add(FirErrors.PROPERTY_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic ->
PropertyTypeMismatchOnInheritanceImpl( PropertyTypeMismatchOnInheritanceImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic -> add(FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic ->
VarTypeMismatchOnInheritanceImpl( VarTypeMismatchOnInheritanceImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.RETURN_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic -> add(FirErrors.RETURN_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic ->
ReturnTypeMismatchByDelegationImpl( ReturnTypeMismatchByDelegationImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PROPERTY_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic -> add(FirErrors.PROPERTY_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic ->
PropertyTypeMismatchByDelegationImpl( PropertyTypeMismatchByDelegationImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION) { firDiagnostic -> add(FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION) { firDiagnostic ->
VarOverriddenByValByDelegationImpl( VarOverriddenByValByDelegationImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.CONFLICTING_INHERITED_MEMBERS) { firDiagnostic -> add(FirErrors.CONFLICTING_INHERITED_MEMBERS) { firDiagnostic ->
ConflictingInheritedMembersImpl( ConflictingInheritedMembersImpl(
firDiagnostic.a.map { firCallableDeclaration -> firDiagnostic.a.map { firCallableSymbol ->
firSymbolBuilder.callableBuilder.buildCallableSymbol(firCallableDeclaration as FirCallableDeclaration) firSymbolBuilder.callableBuilder.buildCallableSymbol(firCallableSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1733,96 +1732,96 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED) { firDiagnostic -> add(FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
AbstractMemberNotImplementedImpl( AbstractMemberNotImplementedImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED) { firDiagnostic -> add(FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
AbstractClassMemberNotImplementedImpl( AbstractClassMemberNotImplementedImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER) { firDiagnostic -> add(FirErrors.INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER) { firDiagnostic ->
InvisibleAbstractMemberFromSuperImpl( InvisibleAbstractMemberFromSuperImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING) { firDiagnostic -> add(FirErrors.INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING) { firDiagnostic ->
InvisibleAbstractMemberFromSuperWarningImpl( InvisibleAbstractMemberFromSuperWarningImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED) { firDiagnostic -> add(FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
ManyImplMemberNotImplementedImpl( ManyImplMemberNotImplementedImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED) { firDiagnostic -> add(FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
ManyInterfacesMemberNotImplementedImpl( ManyInterfacesMemberNotImplementedImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION) { firDiagnostic -> add(FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION) { firDiagnostic ->
OverridingFinalMemberByDelegationImpl( OverridingFinalMemberByDelegationImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE) { firDiagnostic -> add(FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE) { firDiagnostic ->
DelegatedMemberHidesSupertypeOverrideImpl( DelegatedMemberHidesSupertypeOverrideImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic -> add(FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic ->
ReturnTypeMismatchOnOverrideImpl( ReturnTypeMismatchOnOverrideImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic -> add(FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic ->
PropertyTypeMismatchOnOverrideImpl( PropertyTypeMismatchOnOverrideImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic -> add(FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE) { firDiagnostic ->
VarTypeMismatchOnOverrideImpl( VarTypeMismatchOnOverrideImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.VAR_OVERRIDDEN_BY_VAL) { firDiagnostic -> add(FirErrors.VAR_OVERRIDDEN_BY_VAL) { firDiagnostic ->
VarOverriddenByValImpl( VarOverriddenByValImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1841,8 +1840,8 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.VIRTUAL_MEMBER_HIDDEN) { firDiagnostic -> add(FirErrors.VIRTUAL_MEMBER_HIDDEN) { firDiagnostic ->
VirtualMemberHiddenImpl( VirtualMemberHiddenImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b) as KtNamedClassOrObjectSymbol, firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -1856,7 +1855,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.CONFLICTING_OVERLOADS) { firDiagnostic -> add(FirErrors.CONFLICTING_OVERLOADS) { firDiagnostic ->
ConflictingOverloadsImpl( ConflictingOverloadsImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1865,7 +1864,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.REDECLARATION) { firDiagnostic -> add(FirErrors.REDECLARATION) { firDiagnostic ->
RedeclarationImpl( RedeclarationImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -1893,36 +1892,36 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS) { firDiagnostic -> add(FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
AbstractFunctionInNonAbstractClassImpl( AbstractFunctionInNonAbstractClassImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.ABSTRACT_FUNCTION_WITH_BODY) { firDiagnostic -> add(FirErrors.ABSTRACT_FUNCTION_WITH_BODY) { firDiagnostic ->
AbstractFunctionWithBodyImpl( AbstractFunctionWithBodyImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY) { firDiagnostic -> add(FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY) { firDiagnostic ->
NonAbstractFunctionWithNoBodyImpl( NonAbstractFunctionWithNoBodyImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PRIVATE_FUNCTION_WITH_NO_BODY) { firDiagnostic -> add(FirErrors.PRIVATE_FUNCTION_WITH_NO_BODY) { firDiagnostic ->
PrivateFunctionWithNoBodyImpl( PrivateFunctionWithNoBodyImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.NON_MEMBER_FUNCTION_NO_BODY) { firDiagnostic -> add(FirErrors.NON_MEMBER_FUNCTION_NO_BODY) { firDiagnostic ->
NonMemberFunctionNoBodyImpl( NonMemberFunctionNoBodyImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -2014,8 +2013,8 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic -> add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
AbstractPropertyInNonAbstractClassImpl( AbstractPropertyInNonAbstractClassImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration), firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a.fir),
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b), firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -2261,7 +2260,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
ComponentFunctionAmbiguityImpl( ComponentFunctionAmbiguityImpl(
firDiagnostic.a, firDiagnostic.a,
firDiagnostic.b.map { firBasedSymbol -> firDiagnostic.b.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -2292,14 +2291,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.UNINITIALIZED_PARAMETER) { firDiagnostic -> add(FirErrors.UNINITIALIZED_PARAMETER) { firDiagnostic ->
UninitializedParameterImpl( UninitializedParameterImpl(
firSymbolBuilder.variableLikeBuilder.buildVariableLikeSymbol(firDiagnostic.a.fir), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.UNINITIALIZED_ENUM_ENTRY) { firDiagnostic -> add(FirErrors.UNINITIALIZED_ENUM_ENTRY) { firDiagnostic ->
UninitializedEnumEntryImpl( UninitializedEnumEntryImpl(
firSymbolBuilder.variableLikeBuilder.buildVariableLikeSymbol(firDiagnostic.a.fir), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -2355,7 +2354,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.WRONG_INVOCATION_KIND) { firDiagnostic -> add(FirErrors.WRONG_INVOCATION_KIND) { firDiagnostic ->
WrongInvocationKindImpl( WrongInvocationKindImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic.b, firDiagnostic.b,
firDiagnostic.c, firDiagnostic.c,
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
@@ -2364,7 +2363,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.LEAKED_IN_PLACE_LAMBDA) { firDiagnostic -> add(FirErrors.LEAKED_IN_PLACE_LAMBDA) { firDiagnostic ->
LeakedInPlaceLambdaImpl( LeakedInPlaceLambdaImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -2573,7 +2572,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.HAS_NEXT_FUNCTION_NONE_APPLICABLE) { firDiagnostic -> add(FirErrors.HAS_NEXT_FUNCTION_NONE_APPLICABLE) { firDiagnostic ->
HasNextFunctionNoneApplicableImpl( HasNextFunctionNoneApplicableImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -2582,7 +2581,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.NEXT_NONE_APPLICABLE) { firDiagnostic -> add(FirErrors.NEXT_NONE_APPLICABLE) { firDiagnostic ->
NextNoneApplicableImpl( NextNoneApplicableImpl(
firDiagnostic.a.map { firBasedSymbol -> firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -2601,7 +2600,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
DelegateSpecialFunctionAmbiguityImpl( DelegateSpecialFunctionAmbiguityImpl(
firDiagnostic.a, firDiagnostic.a,
firDiagnostic.b.map { firBasedSymbol -> firDiagnostic.b.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -2611,7 +2610,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
DelegateSpecialFunctionNoneApplicableImpl( DelegateSpecialFunctionNoneApplicableImpl(
firDiagnostic.a, firDiagnostic.a,
firDiagnostic.b.map { firBasedSymbol -> firDiagnostic.b.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir as FirDeclaration) firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
}, },
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
@@ -2793,68 +2792,68 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.USAGE_IS_NOT_INLINABLE) { firDiagnostic -> add(FirErrors.USAGE_IS_NOT_INLINABLE) { firDiagnostic ->
UsageIsNotInlinableImpl( UsageIsNotInlinableImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED) { firDiagnostic -> add(FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED) { firDiagnostic ->
NonLocalReturnNotAllowedImpl( NonLocalReturnNotAllowedImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.RECURSION_IN_INLINE) { firDiagnostic -> add(FirErrors.RECURSION_IN_INLINE) { firDiagnostic ->
RecursionInInlineImpl( RecursionInInlineImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE) { firDiagnostic -> add(FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE) { firDiagnostic ->
NonPublicCallFromPublicInlineImpl( NonPublicCallFromPublicInlineImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE) { firDiagnostic -> add(FirErrors.PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE) { firDiagnostic ->
ProtectedConstructorCallFromPublicInlineImpl( ProtectedConstructorCallFromPublicInlineImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR) { firDiagnostic -> add(FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR) { firDiagnostic ->
ProtectedCallFromPublicInlineErrorImpl( ProtectedCallFromPublicInlineErrorImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE) { firDiagnostic -> add(FirErrors.PROTECTED_CALL_FROM_PUBLIC_INLINE) { firDiagnostic ->
ProtectedCallFromPublicInlineImpl( ProtectedCallFromPublicInlineImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.PRIVATE_CLASS_MEMBER_FROM_INLINE) { firDiagnostic -> add(FirErrors.PRIVATE_CLASS_MEMBER_FROM_INLINE) { firDiagnostic ->
PrivateClassMemberFromInlineImpl( PrivateClassMemberFromInlineImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firSymbolBuilder.buildSymbol(firDiagnostic.b.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE) { firDiagnostic -> add(FirErrors.SUPER_CALL_FROM_PUBLIC_INLINE) { firDiagnostic ->
SuperCallFromPublicInlineImpl( SuperCallFromPublicInlineImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir as FirDeclaration), firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol 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.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol
@@ -278,7 +277,7 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class QualifiedSupertypeExtendedByOtherSupertype : KtFirDiagnostic<KtTypeReference>() { abstract class QualifiedSupertypeExtendedByOtherSupertype : KtFirDiagnostic<KtTypeReference>() {
override val diagnosticClass get() = QualifiedSupertypeExtendedByOtherSupertype::class override val diagnosticClass get() = QualifiedSupertypeExtendedByOtherSupertype::class
abstract val otherSuperType: KtClassLikeSymbol abstract val otherSuperType: KtSymbol
} }
abstract class SupertypeInitializedInInterface : KtFirDiagnostic<KtTypeReference>() { abstract class SupertypeInitializedInInterface : KtFirDiagnostic<KtTypeReference>() {
@@ -1152,7 +1151,7 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class NothingToOverride : KtFirDiagnostic<KtModifierListOwner>() { abstract class NothingToOverride : KtFirDiagnostic<KtModifierListOwner>() {
override val diagnosticClass get() = NothingToOverride::class override val diagnosticClass get() = NothingToOverride::class
abstract val declaration: KtSymbol abstract val declaration: KtCallableSymbol
} }
abstract class CannotOverrideInvisibleMember : KtFirDiagnostic<KtNamedDeclaration>() { abstract class CannotOverrideInvisibleMember : KtFirDiagnostic<KtNamedDeclaration>() {
@@ -1278,26 +1277,26 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class ReturnTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() { abstract class ReturnTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = ReturnTypeMismatchOnOverride::class override val diagnosticClass get() = ReturnTypeMismatchOnOverride::class
abstract val function: KtSymbol abstract val function: KtCallableSymbol
abstract val superFunction: KtSymbol abstract val superFunction: KtCallableSymbol
} }
abstract class PropertyTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() { abstract class PropertyTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = PropertyTypeMismatchOnOverride::class override val diagnosticClass get() = PropertyTypeMismatchOnOverride::class
abstract val property: KtSymbol abstract val property: KtCallableSymbol
abstract val superProperty: KtSymbol abstract val superProperty: KtCallableSymbol
} }
abstract class VarTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() { abstract class VarTypeMismatchOnOverride : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = VarTypeMismatchOnOverride::class override val diagnosticClass get() = VarTypeMismatchOnOverride::class
abstract val variable: KtSymbol abstract val variable: KtCallableSymbol
abstract val superVariable: KtSymbol abstract val superVariable: KtCallableSymbol
} }
abstract class VarOverriddenByVal : KtFirDiagnostic<KtNamedDeclaration>() { abstract class VarOverriddenByVal : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = VarOverriddenByVal::class override val diagnosticClass get() = VarOverriddenByVal::class
abstract val overridingDeclaration: KtSymbol abstract val overridingDeclaration: KtCallableSymbol
abstract val overriddenDeclaration: KtSymbol abstract val overriddenDeclaration: KtCallableSymbol
} }
abstract class NonFinalMemberInFinalClass : KtFirDiagnostic<KtNamedDeclaration>() { abstract class NonFinalMemberInFinalClass : KtFirDiagnostic<KtNamedDeclaration>() {
@@ -1310,8 +1309,8 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class VirtualMemberHidden : KtFirDiagnostic<KtNamedDeclaration>() { abstract class VirtualMemberHidden : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = VirtualMemberHidden::class override val diagnosticClass get() = VirtualMemberHidden::class
abstract val declared: KtSymbol abstract val declared: KtCallableSymbol
abstract val overriddenContainer: KtNamedClassOrObjectSymbol abstract val overriddenContainer: KtClassLikeSymbol
} }
abstract class ManyCompanionObjects : KtFirDiagnostic<KtObjectDeclaration>() { abstract class ManyCompanionObjects : KtFirDiagnostic<KtObjectDeclaration>() {
@@ -1344,28 +1343,28 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class AbstractFunctionInNonAbstractClass : KtFirDiagnostic<KtFunction>() { abstract class AbstractFunctionInNonAbstractClass : KtFirDiagnostic<KtFunction>() {
override val diagnosticClass get() = AbstractFunctionInNonAbstractClass::class override val diagnosticClass get() = AbstractFunctionInNonAbstractClass::class
abstract val function: KtSymbol abstract val function: KtCallableSymbol
abstract val containingClass: KtClassLikeSymbol abstract val containingClass: KtClassLikeSymbol
} }
abstract class AbstractFunctionWithBody : KtFirDiagnostic<KtFunction>() { abstract class AbstractFunctionWithBody : KtFirDiagnostic<KtFunction>() {
override val diagnosticClass get() = AbstractFunctionWithBody::class override val diagnosticClass get() = AbstractFunctionWithBody::class
abstract val function: KtSymbol abstract val function: KtCallableSymbol
} }
abstract class NonAbstractFunctionWithNoBody : KtFirDiagnostic<KtFunction>() { abstract class NonAbstractFunctionWithNoBody : KtFirDiagnostic<KtFunction>() {
override val diagnosticClass get() = NonAbstractFunctionWithNoBody::class override val diagnosticClass get() = NonAbstractFunctionWithNoBody::class
abstract val function: KtSymbol abstract val function: KtCallableSymbol
} }
abstract class PrivateFunctionWithNoBody : KtFirDiagnostic<KtFunction>() { abstract class PrivateFunctionWithNoBody : KtFirDiagnostic<KtFunction>() {
override val diagnosticClass get() = PrivateFunctionWithNoBody::class override val diagnosticClass get() = PrivateFunctionWithNoBody::class
abstract val function: KtSymbol abstract val function: KtCallableSymbol
} }
abstract class NonMemberFunctionNoBody : KtFirDiagnostic<KtFunction>() { abstract class NonMemberFunctionNoBody : KtFirDiagnostic<KtFunction>() {
override val diagnosticClass get() = NonMemberFunctionNoBody::class override val diagnosticClass get() = NonMemberFunctionNoBody::class
abstract val function: KtSymbol abstract val function: KtCallableSymbol
} }
abstract class FunctionDeclarationWithNoName : KtFirDiagnostic<KtFunction>() { abstract class FunctionDeclarationWithNoName : KtFirDiagnostic<KtFunction>() {
@@ -1427,7 +1426,7 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() { abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() {
override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class
abstract val property: KtSymbol abstract val property: KtCallableSymbol
abstract val containingClass: KtClassLikeSymbol abstract val containingClass: KtClassLikeSymbol
} }
@@ -1617,12 +1616,12 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class UninitializedParameter : KtFirDiagnostic<KtSimpleNameExpression>() { abstract class UninitializedParameter : KtFirDiagnostic<KtSimpleNameExpression>() {
override val diagnosticClass get() = UninitializedParameter::class override val diagnosticClass get() = UninitializedParameter::class
abstract val parameter: KtVariableLikeSymbol abstract val parameter: KtSymbol
} }
abstract class UninitializedEnumEntry : KtFirDiagnostic<KtSimpleNameExpression>() { abstract class UninitializedEnumEntry : KtFirDiagnostic<KtSimpleNameExpression>() {
override val diagnosticClass get() = UninitializedEnumEntry::class override val diagnosticClass get() = UninitializedEnumEntry::class
abstract val enumEntry: KtVariableLikeSymbol abstract val enumEntry: KtSymbol
} }
abstract class UninitializedEnumCompanion : KtFirDiagnostic<KtSimpleNameExpression>() { abstract class UninitializedEnumCompanion : KtFirDiagnostic<KtSimpleNameExpression>() {
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol 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.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol
@@ -422,7 +421,7 @@ internal class SuperclassNotAccessibleFromInterfaceImpl(
} }
internal class QualifiedSupertypeExtendedByOtherSupertypeImpl( internal class QualifiedSupertypeExtendedByOtherSupertypeImpl(
override val otherSuperType: KtClassLikeSymbol, override val otherSuperType: KtSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.QualifiedSupertypeExtendedByOtherSupertype(), KtAbstractFirDiagnostic<KtTypeReference> { ) : KtFirDiagnostic.QualifiedSupertypeExtendedByOtherSupertype(), KtAbstractFirDiagnostic<KtTypeReference> {
@@ -1854,7 +1853,7 @@ internal class ExpressionOfNullableTypeInClassLiteralLhsImpl(
} }
internal class NothingToOverrideImpl( internal class NothingToOverrideImpl(
override val declaration: KtSymbol, override val declaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.NothingToOverride(), KtAbstractFirDiagnostic<KtModifierListOwner> { ) : KtFirDiagnostic.NothingToOverride(), KtAbstractFirDiagnostic<KtModifierListOwner> {
@@ -2043,8 +2042,8 @@ internal class DelegatedMemberHidesSupertypeOverrideImpl(
} }
internal class ReturnTypeMismatchOnOverrideImpl( internal class ReturnTypeMismatchOnOverrideImpl(
override val function: KtSymbol, override val function: KtCallableSymbol,
override val superFunction: KtSymbol, override val superFunction: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.ReturnTypeMismatchOnOverride(), KtAbstractFirDiagnostic<KtNamedDeclaration> { ) : KtFirDiagnostic.ReturnTypeMismatchOnOverride(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
@@ -2052,8 +2051,8 @@ internal class ReturnTypeMismatchOnOverrideImpl(
} }
internal class PropertyTypeMismatchOnOverrideImpl( internal class PropertyTypeMismatchOnOverrideImpl(
override val property: KtSymbol, override val property: KtCallableSymbol,
override val superProperty: KtSymbol, override val superProperty: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.PropertyTypeMismatchOnOverride(), KtAbstractFirDiagnostic<KtNamedDeclaration> { ) : KtFirDiagnostic.PropertyTypeMismatchOnOverride(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
@@ -2061,8 +2060,8 @@ internal class PropertyTypeMismatchOnOverrideImpl(
} }
internal class VarTypeMismatchOnOverrideImpl( internal class VarTypeMismatchOnOverrideImpl(
override val variable: KtSymbol, override val variable: KtCallableSymbol,
override val superVariable: KtSymbol, override val superVariable: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.VarTypeMismatchOnOverride(), KtAbstractFirDiagnostic<KtNamedDeclaration> { ) : KtFirDiagnostic.VarTypeMismatchOnOverride(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
@@ -2070,8 +2069,8 @@ internal class VarTypeMismatchOnOverrideImpl(
} }
internal class VarOverriddenByValImpl( internal class VarOverriddenByValImpl(
override val overridingDeclaration: KtSymbol, override val overridingDeclaration: KtCallableSymbol,
override val overriddenDeclaration: KtSymbol, override val overriddenDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.VarOverriddenByVal(), KtAbstractFirDiagnostic<KtNamedDeclaration> { ) : KtFirDiagnostic.VarOverriddenByVal(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
@@ -2093,8 +2092,8 @@ internal class NonFinalMemberInObjectImpl(
} }
internal class VirtualMemberHiddenImpl( internal class VirtualMemberHiddenImpl(
override val declared: KtSymbol, override val declared: KtCallableSymbol,
override val overriddenContainer: KtNamedClassOrObjectSymbol, override val overriddenContainer: KtClassLikeSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.VirtualMemberHidden(), KtAbstractFirDiagnostic<KtNamedDeclaration> { ) : KtFirDiagnostic.VirtualMemberHidden(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
@@ -2148,7 +2147,7 @@ internal class LocalInterfaceNotAllowedImpl(
} }
internal class AbstractFunctionInNonAbstractClassImpl( internal class AbstractFunctionInNonAbstractClassImpl(
override val function: KtSymbol, override val function: KtCallableSymbol,
override val containingClass: KtClassLikeSymbol, override val containingClass: KtClassLikeSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
@@ -2157,7 +2156,7 @@ internal class AbstractFunctionInNonAbstractClassImpl(
} }
internal class AbstractFunctionWithBodyImpl( internal class AbstractFunctionWithBodyImpl(
override val function: KtSymbol, override val function: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.AbstractFunctionWithBody(), KtAbstractFirDiagnostic<KtFunction> { ) : KtFirDiagnostic.AbstractFunctionWithBody(), KtAbstractFirDiagnostic<KtFunction> {
@@ -2165,7 +2164,7 @@ internal class AbstractFunctionWithBodyImpl(
} }
internal class NonAbstractFunctionWithNoBodyImpl( internal class NonAbstractFunctionWithNoBodyImpl(
override val function: KtSymbol, override val function: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.NonAbstractFunctionWithNoBody(), KtAbstractFirDiagnostic<KtFunction> { ) : KtFirDiagnostic.NonAbstractFunctionWithNoBody(), KtAbstractFirDiagnostic<KtFunction> {
@@ -2173,7 +2172,7 @@ internal class NonAbstractFunctionWithNoBodyImpl(
} }
internal class PrivateFunctionWithNoBodyImpl( internal class PrivateFunctionWithNoBodyImpl(
override val function: KtSymbol, override val function: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.PrivateFunctionWithNoBody(), KtAbstractFirDiagnostic<KtFunction> { ) : KtFirDiagnostic.PrivateFunctionWithNoBody(), KtAbstractFirDiagnostic<KtFunction> {
@@ -2181,7 +2180,7 @@ internal class PrivateFunctionWithNoBodyImpl(
} }
internal class NonMemberFunctionNoBodyImpl( internal class NonMemberFunctionNoBodyImpl(
override val function: KtSymbol, override val function: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.NonMemberFunctionNoBody(), KtAbstractFirDiagnostic<KtFunction> { ) : KtFirDiagnostic.NonMemberFunctionNoBody(), KtAbstractFirDiagnostic<KtFunction> {
@@ -2288,7 +2287,7 @@ internal class FunInterfaceWithSuspendFunctionImpl(
} }
internal class AbstractPropertyInNonAbstractClassImpl( internal class AbstractPropertyInNonAbstractClassImpl(
override val property: KtSymbol, override val property: KtCallableSymbol,
override val containingClass: KtClassLikeSymbol, override val containingClass: KtClassLikeSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
@@ -2607,7 +2606,7 @@ internal class UninitializedVariableImpl(
} }
internal class UninitializedParameterImpl( internal class UninitializedParameterImpl(
override val parameter: KtVariableLikeSymbol, override val parameter: KtSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.UninitializedParameter(), KtAbstractFirDiagnostic<KtSimpleNameExpression> { ) : KtFirDiagnostic.UninitializedParameter(), KtAbstractFirDiagnostic<KtSimpleNameExpression> {
@@ -2615,7 +2614,7 @@ internal class UninitializedParameterImpl(
} }
internal class UninitializedEnumEntryImpl( internal class UninitializedEnumEntryImpl(
override val enumEntry: KtVariableLikeSymbol, override val enumEntry: KtSymbol,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.UninitializedEnumEntry(), KtAbstractFirDiagnostic<KtSimpleNameExpression> { ) : KtFirDiagnostic.UninitializedEnumEntry(), KtAbstractFirDiagnostic<KtSimpleNameExpression> {
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.components.KtOverrideInfoProvider import org.jetbrains.kotlin.idea.frontend.api.components.KtOverrideInfoProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
@@ -49,8 +50,8 @@ class KtFirOverrideInfoProvider(
return memberSymbol.firRef.withFir { memberFir -> return memberSymbol.firRef.withFir { memberFir ->
if (memberFir !is FirCallableDeclaration) return@withFir null if (memberFir !is FirCallableDeclaration) return@withFir null
parentClassSymbol.firRef.withFir inner@{ parentClassFir -> parentClassSymbol.firRef.withFir inner@{ parentClassFir ->
if (parentClassFir !is FirClass) return@inner null if (parentClassSymbol !is FirClassSymbol<*>) return@inner null
memberFir.getImplementationStatus(SessionHolderImpl(firAnalysisSession.rootModuleSession, ScopeSession()), parentClassFir) memberFir.symbol.getImplementationStatus(SessionHolderImpl(firAnalysisSession.rootModuleSession, ScopeSession()), parentClassSymbol)
} }
} }
} }