diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 6809b088572..e5c8b8fa188 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -11,29 +11,22 @@ import com.intellij.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl import org.jetbrains.kotlin.fir.declarations.visibility -import org.jetbrains.kotlin.fir.generateValueOfFunction -import org.jetbrains.kotlin.fir.generateValuesFunction import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod -import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope -import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope -import org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.toFirSourceElement -import org.jetbrains.kotlin.fir.types.ConeClassErrorType import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.load.java.JavaClassFinder @@ -257,6 +250,7 @@ class JavaSymbolProvider( generateValuesFunction(session, classId.packageFqName, classId.relativeClassName) generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName) } + calculateSAM() } } } diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 2973120ef06..56f5790ffd6 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -456,6 +456,7 @@ class DeclarationsConverter( firClass.generateValuesFunction(session, context.packageFqName, context.className) firClass.generateValueOfFunction(session, context.packageFqName, context.className) } + firClass.calculateSAM() return@withChildClassName firClass } diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 80cd4428520..87cd59584bd 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -618,6 +618,7 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va firClass.generateValuesFunction(session, context.packageFqName, context.className) firClass.generateValueOfFunction(session, context.packageFqName, context.className) } + firClass.calculateSAM() firClass } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 8e976644cfa..f9d72769d56 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.fir.deserialization -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.calculateSAM import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.addDeclarations import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl import org.jetbrains.kotlin.fir.declarations.impl.FirSealedClassImpl import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider -import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl @@ -150,4 +149,5 @@ fun deserializeClassToSymbol( } } } + firClass.calculateSAM() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index 1181009d929..e380655336e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -244,6 +244,8 @@ private fun FirRegularClass.findSingleAbstractMethodByNames( scopeSession: ScopeSession, samCandidateNames: Set ): FirSimpleFunction? { + if (status.isNotSAM) return null + var resultMethod: FirSimpleFunction? = null var metIncorrectMember = false diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt index 81b48585fbf..1b3d21703e7 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt @@ -35,6 +35,7 @@ interface FirDeclarationStatus : FirElement { val isData: Boolean val isSuspend: Boolean val isStatic: Boolean + val isNotSAM: Boolean override fun accept(visitor: FirVisitor, data: D): R = visitor.visitDeclarationStatus(this, data) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt index 44c45a4c243..b1bbe1bfd37 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt @@ -34,6 +34,7 @@ interface FirResolvedDeclarationStatus : FirDeclarationStatus { override val isData: Boolean override val isSuspend: Boolean override val isStatic: Boolean + override val isNotSAM: Boolean override fun accept(visitor: FirVisitor, data: D): R = visitor.visitResolvedDeclarationStatus(this, data) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt index 819d1535f21..64cb1333ecc 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt @@ -6,11 +6,17 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.analyzer.ModuleInfo +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass +import org.jetbrains.kotlin.fir.declarations.modality import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression -import org.jetbrains.kotlin.fir.visitors.FirTransformer fun ModuleInfo.dependenciesWithoutSelf(): Sequence = dependencies().asSequence().filter { it != this } @@ -30,4 +36,27 @@ tailrec fun FirElement.unwrapSmartcast(): FirElement = if (this is FirExpression originalExpression.unwrapSmartcast() } else { this +} + +private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString") + +fun FirModifiableClass.calculateSAM() { + val status = symbol.fir.status as FirDeclarationStatusImpl + var counter = 0 + for (declaration in declarations) { + if (declaration is FirProperty && declaration.modality == Modality.ABSTRACT) { + status.isNotSAM = true + return + } + if (declaration is FirSimpleFunction) { + if (declaration.modality != Modality.ABSTRACT || declaration.name.asString() in PUBLIC_METHOD_NAMES_IN_OBJECT) { + continue + } + counter++ + if (counter > 1) { + status.isNotSAM = true + return + } + } + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt index 082ca04e221..23c4b2d7a5b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt @@ -121,6 +121,12 @@ open class FirDeclarationStatusImpl( this[STATIC] = value } + override var isNotSAM: Boolean + get() = this[NOT_SAM] + set(value) { + this[NOT_SAM] = value + } + private enum class Modifier(val mask: Int) { EXPECT(0x1), ACTUAL(0x2), @@ -136,7 +142,8 @@ open class FirDeclarationStatusImpl( COMPANION(0x800), DATA(0x1000), SUSPEND(0x2000), - STATIC(0x4000) + STATIC(0x4000), + NOT_SAM(0x8000) } override fun acceptChildren(visitor: FirVisitor, data: D) {} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index ce6c1054d48..ba5b16f5599 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -302,7 +302,8 @@ object NodeConfigurator : AbstractFieldConfigurator() { +modality generateBooleanFields( "expect", "actual", "override", "operator", "infix", "inline", "tailRec", - "external", "const", "lateInit", "inner", "companion", "data", "suspend", "static" + "external", "const", "lateInit", "inner", "companion", "data", "suspend", + "static", "notSAM" ) }