[FIR] Implement early calculation of "not SAM" flag for classes
This commit is contained in:
@@ -11,29 +11,22 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
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.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary
|
import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.visibility
|
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.FirJavaClass
|
||||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
|
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
|
||||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
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.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.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
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.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||||
@@ -257,6 +250,7 @@ class JavaSymbolProvider(
|
|||||||
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
|
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||||
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
|
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||||
}
|
}
|
||||||
|
calculateSAM()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -456,6 +456,7 @@ class DeclarationsConverter(
|
|||||||
firClass.generateValuesFunction(session, context.packageFqName, context.className)
|
firClass.generateValuesFunction(session, context.packageFqName, context.className)
|
||||||
firClass.generateValueOfFunction(session, context.packageFqName, context.className)
|
firClass.generateValueOfFunction(session, context.packageFqName, context.className)
|
||||||
}
|
}
|
||||||
|
firClass.calculateSAM()
|
||||||
|
|
||||||
return@withChildClassName firClass
|
return@withChildClassName firClass
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -618,6 +618,7 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va
|
|||||||
firClass.generateValuesFunction(session, context.packageFqName, context.className)
|
firClass.generateValuesFunction(session, context.packageFqName, context.className)
|
||||||
firClass.generateValueOfFunction(session, context.packageFqName, context.className)
|
firClass.generateValueOfFunction(session, context.packageFqName, context.className)
|
||||||
}
|
}
|
||||||
|
firClass.calculateSAM()
|
||||||
|
|
||||||
firClass
|
firClass
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.deserialization
|
package org.jetbrains.kotlin.fir.deserialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
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.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.addDeclarations
|
import org.jetbrains.kotlin.fir.declarations.addDeclarations
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
|
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.FirEnumEntryImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirSealedClassImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirSealedClassImpl
|
||||||
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
|
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.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
@@ -150,4 +149,5 @@ fun deserializeClassToSymbol(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
firClass.calculateSAM()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -244,6 +244,8 @@ private fun FirRegularClass.findSingleAbstractMethodByNames(
|
|||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
samCandidateNames: Set<Name>
|
samCandidateNames: Set<Name>
|
||||||
): FirSimpleFunction? {
|
): FirSimpleFunction? {
|
||||||
|
if (status.isNotSAM) return null
|
||||||
|
|
||||||
var resultMethod: FirSimpleFunction? = null
|
var resultMethod: FirSimpleFunction? = null
|
||||||
var metIncorrectMember = false
|
var metIncorrectMember = false
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ interface FirDeclarationStatus : FirElement {
|
|||||||
val isData: Boolean
|
val isData: Boolean
|
||||||
val isSuspend: Boolean
|
val isSuspend: Boolean
|
||||||
val isStatic: Boolean
|
val isStatic: Boolean
|
||||||
|
val isNotSAM: Boolean
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDeclarationStatus(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDeclarationStatus(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -34,6 +34,7 @@ interface FirResolvedDeclarationStatus : FirDeclarationStatus {
|
|||||||
override val isData: Boolean
|
override val isData: Boolean
|
||||||
override val isSuspend: Boolean
|
override val isSuspend: Boolean
|
||||||
override val isStatic: Boolean
|
override val isStatic: Boolean
|
||||||
|
override val isNotSAM: Boolean
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedDeclarationStatus(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedDeclarationStatus(this, data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,17 @@
|
|||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
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.FirBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
|
||||||
|
|
||||||
fun ModuleInfo.dependenciesWithoutSelf(): Sequence<ModuleInfo> = dependencies().asSequence().filter { it != this }
|
fun ModuleInfo.dependenciesWithoutSelf(): Sequence<ModuleInfo> = dependencies().asSequence().filter { it != this }
|
||||||
|
|
||||||
@@ -30,4 +36,27 @@ tailrec fun FirElement.unwrapSmartcast(): FirElement = if (this is FirExpression
|
|||||||
originalExpression.unwrapSmartcast()
|
originalExpression.unwrapSmartcast()
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
|
||||||
|
|
||||||
|
fun FirModifiableClass<FirRegularClass>.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
-1
@@ -121,6 +121,12 @@ open class FirDeclarationStatusImpl(
|
|||||||
this[STATIC] = value
|
this[STATIC] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var isNotSAM: Boolean
|
||||||
|
get() = this[NOT_SAM]
|
||||||
|
set(value) {
|
||||||
|
this[NOT_SAM] = value
|
||||||
|
}
|
||||||
|
|
||||||
private enum class Modifier(val mask: Int) {
|
private enum class Modifier(val mask: Int) {
|
||||||
EXPECT(0x1),
|
EXPECT(0x1),
|
||||||
ACTUAL(0x2),
|
ACTUAL(0x2),
|
||||||
@@ -136,7 +142,8 @@ open class FirDeclarationStatusImpl(
|
|||||||
COMPANION(0x800),
|
COMPANION(0x800),
|
||||||
DATA(0x1000),
|
DATA(0x1000),
|
||||||
SUSPEND(0x2000),
|
SUSPEND(0x2000),
|
||||||
STATIC(0x4000)
|
STATIC(0x4000),
|
||||||
|
NOT_SAM(0x8000)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||||
|
|||||||
+2
-1
@@ -302,7 +302,8 @@ object NodeConfigurator : AbstractFieldConfigurator() {
|
|||||||
+modality
|
+modality
|
||||||
generateBooleanFields(
|
generateBooleanFields(
|
||||||
"expect", "actual", "override", "operator", "infix", "inline", "tailRec",
|
"expect", "actual", "override", "operator", "infix", "inline", "tailRec",
|
||||||
"external", "const", "lateInit", "inner", "companion", "data", "suspend", "static"
|
"external", "const", "lateInit", "inner", "companion", "data", "suspend",
|
||||||
|
"static", "notSAM"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user