[FIR] Implement early calculation of "not SAM" flag for classes

This commit is contained in:
Mikhail Glukhikh
2020-01-24 13:47:21 +03:00
parent 279adae3e4
commit dc4f332c08
10 changed files with 50 additions and 13 deletions
@@ -35,6 +35,7 @@ interface FirDeclarationStatus : FirElement {
val isData: Boolean
val isSuspend: Boolean
val isStatic: Boolean
val isNotSAM: Boolean
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitDeclarationStatus(this, data)
}
@@ -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 <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedDeclarationStatus(this, data)
}
@@ -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<ModuleInfo> = 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<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
}
}
}
}
@@ -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 <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
@@ -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"
)
}