FIR: Serialize members originated from delegation
This commit is contained in:
+43
-12
@@ -11,8 +11,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.deserialization.CONTINUATION_INTERFACE_CLASS_ID
|
||||
@@ -23,18 +22,19 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.varargElementType
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.suspendFunctionTypeToFunctionTypeWithContinuation
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.processAllFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.processAllProperties
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.EnumValue
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.IntValue
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.StringValue
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
|
||||
@@ -55,6 +55,7 @@ import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
|
||||
class FirElementSerializer private constructor(
|
||||
private val session: FirSession,
|
||||
private val scopeSession: ScopeSession,
|
||||
private val containingDeclaration: FirDeclaration?,
|
||||
private val typeParameters: Interner<FirTypeParameter>,
|
||||
private val extension: FirSerializerExtension,
|
||||
@@ -139,7 +140,7 @@ class FirElementSerializer private constructor(
|
||||
|
||||
val callableMembers =
|
||||
extension.customClassMembersProducer?.getCallableMembers(klass)
|
||||
?: klass.declarations.filterIsInstance<FirCallableMemberDeclaration<*>>()
|
||||
?: klass.declarations()
|
||||
.sortedWith(FirCallableMemberDeclarationComparator)
|
||||
|
||||
for (declaration in callableMembers) {
|
||||
@@ -197,6 +198,32 @@ class FirElementSerializer private constructor(
|
||||
return builder
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun FirClass<*>.declarations(): List<FirCallableMemberDeclaration<*>> = buildList {
|
||||
val memberScope =
|
||||
defaultType().scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
?: error("Null scope for $this")
|
||||
|
||||
fun addDeclarationIfNeeded(symbol: FirCallableSymbol<*>) {
|
||||
val declaration = symbol.fir as? FirCallableMemberDeclaration<*> ?: return
|
||||
if (declaration.isSubstitutionOrIntersectionOverride) return
|
||||
|
||||
// non-intersection or substitution fake override
|
||||
if (!declaration.isStatic && declaration.dispatchReceiverClassOrNull() != this@declarations.symbol.toLookupTag()) return
|
||||
|
||||
add(declaration)
|
||||
}
|
||||
|
||||
memberScope.processAllFunctions(::addDeclarationIfNeeded)
|
||||
memberScope.processAllProperties(::addDeclarationIfNeeded)
|
||||
|
||||
for (declaration in declarations) {
|
||||
if (declaration is FirCallableMemberDeclaration<*> && declaration.isStatic) {
|
||||
add(declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirPropertyAccessor.nonSourceAnnotations(session: FirSession, property: FirProperty): List<FirAnnotationCall> =
|
||||
(this as FirAnnotationContainer).nonSourceAnnotations(session) + property.nonSourceAnnotations(session).filter {
|
||||
val useSiteTarget = it.useSiteTarget
|
||||
@@ -747,7 +774,7 @@ class FirElementSerializer private constructor(
|
||||
|
||||
private fun createChildSerializer(declaration: FirDeclaration): FirElementSerializer =
|
||||
FirElementSerializer(
|
||||
session, declaration, Interner(typeParameters), extension,
|
||||
session, scopeSession, declaration, Interner(typeParameters), extension,
|
||||
typeTable, versionRequirementTable, serializeTypeTableToFunction = false,
|
||||
typeApproximator
|
||||
)
|
||||
@@ -876,11 +903,12 @@ class FirElementSerializer private constructor(
|
||||
@JvmStatic
|
||||
fun createTopLevel(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
extension: FirSerializerExtension,
|
||||
typeApproximator: AbstractTypeApproximator,
|
||||
): FirElementSerializer =
|
||||
FirElementSerializer(
|
||||
session, null,
|
||||
session, scopeSession, null,
|
||||
Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||
serializeTypeTableToFunction = false,
|
||||
typeApproximator
|
||||
@@ -889,11 +917,12 @@ class FirElementSerializer private constructor(
|
||||
@JvmStatic
|
||||
fun createForLambda(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
extension: FirSerializerExtension,
|
||||
typeApproximator: AbstractTypeApproximator,
|
||||
): FirElementSerializer =
|
||||
FirElementSerializer(
|
||||
session, null,
|
||||
session, scopeSession, null,
|
||||
Interner(), extension, MutableTypeTable(),
|
||||
versionRequirementTable = null, serializeTypeTableToFunction = true,
|
||||
typeApproximator
|
||||
@@ -901,6 +930,7 @@ class FirElementSerializer private constructor(
|
||||
|
||||
@JvmStatic
|
||||
fun create(
|
||||
scopeSession: ScopeSession,
|
||||
klass: FirClass<*>,
|
||||
extension: FirSerializerExtension,
|
||||
parentSerializer: FirElementSerializer?,
|
||||
@@ -909,9 +939,9 @@ class FirElementSerializer private constructor(
|
||||
val parentClassId = klass.symbol.classId.outerClassId
|
||||
val parent = if (parentClassId != null && !parentClassId.isLocal) {
|
||||
val parentClass = klass.session.symbolProvider.getClassLikeSymbolByFqName(parentClassId)!!.fir as FirRegularClass
|
||||
parentSerializer ?: create(parentClass, extension, null, typeApproximator)
|
||||
parentSerializer ?: create(scopeSession, parentClass, extension, null, typeApproximator)
|
||||
} else {
|
||||
createTopLevel(klass.session, extension, typeApproximator)
|
||||
createTopLevel(klass.session, scopeSession, extension, typeApproximator)
|
||||
}
|
||||
|
||||
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
|
||||
@@ -919,6 +949,7 @@ class FirElementSerializer private constructor(
|
||||
// Otherwise our interner can get wrong ids because we may serialize classes in any order.
|
||||
val serializer = FirElementSerializer(
|
||||
klass.session,
|
||||
scopeSession,
|
||||
klass,
|
||||
Interner(parent.typeParameters),
|
||||
extension,
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ class FirJvmSerializerExtension(
|
||||
private val localDelegatedProperties: List<FirProperty>,
|
||||
private val approximator: AbstractTypeApproximator,
|
||||
typeMapper: IrTypeMapper,
|
||||
components: Fir2IrComponents
|
||||
private val components: Fir2IrComponents
|
||||
) : FirSerializerExtension() {
|
||||
private val globalBindings = state.globalSerializationBindings
|
||||
override val stringTable = FirJvmElementAwareStringTable(typeMapper, components)
|
||||
@@ -137,7 +137,7 @@ class FirJvmSerializerExtension(
|
||||
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Property>>
|
||||
) {
|
||||
for (localVariable in localDelegatedProperties) {
|
||||
val serializer = FirElementSerializer.createForLambda(session, this, approximator)
|
||||
val serializer = FirElementSerializer.createForLambda(session, components.scopeSession,this, approximator)
|
||||
proto.addExtension(extension, serializer.propertyProto(localVariable)?.build() ?: continue)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -154,10 +154,21 @@ class FirMetadataSerializer(
|
||||
private val serializer: FirElementSerializer? =
|
||||
when (val metadata = irClass.metadata) {
|
||||
is FirMetadataSource.Class -> FirElementSerializer.create(
|
||||
components.scopeSession,
|
||||
metadata.fir, serializerExtension, (parent as? FirMetadataSerializer)?.serializer, approximator
|
||||
)
|
||||
is FirMetadataSource.File -> FirElementSerializer.createTopLevel(metadata.session, serializerExtension, approximator)
|
||||
is FirMetadataSource.Function -> FirElementSerializer.createForLambda(metadata.session, serializerExtension, approximator)
|
||||
is FirMetadataSource.File -> FirElementSerializer.createTopLevel(
|
||||
metadata.session,
|
||||
components.scopeSession,
|
||||
serializerExtension,
|
||||
approximator
|
||||
)
|
||||
is FirMetadataSource.Function -> FirElementSerializer.createForLambda(
|
||||
metadata.session,
|
||||
components.scopeSession,
|
||||
serializerExtension,
|
||||
approximator
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -13320,6 +13320,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegationToMap.kt")
|
||||
public void testDelegationToMap() throws Exception {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
interface A {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
abstract class B(a: A) : A by a
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
class AImpl : A {
|
||||
override fun foo(): String = "OK"
|
||||
}
|
||||
class C : B(AImpl())
|
||||
|
||||
fun box(): String = C().foo()
|
||||
+6
@@ -13320,6 +13320,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegationToMap.kt")
|
||||
public void testDelegationToMap() throws Exception {
|
||||
|
||||
+6
@@ -13320,6 +13320,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("delegationToMap.kt")
|
||||
public void testDelegationToMap() throws Exception {
|
||||
|
||||
+5
@@ -10848,6 +10848,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegationToMap.kt")
|
||||
public void testDelegationToMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationToMap.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -9717,6 +9717,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||
}
|
||||
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegationWithPrivateConstructor.kt")
|
||||
public void testDelegationWithPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt");
|
||||
|
||||
Generated
+5
@@ -9138,6 +9138,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegationWithPrivateConstructor.kt")
|
||||
public void testDelegationWithPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt");
|
||||
|
||||
Generated
+5
@@ -9138,6 +9138,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegationWithPrivateConstructor.kt")
|
||||
public void testDelegationWithPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -4282,6 +4282,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("delegationDifferentModule.kt")
|
||||
public void testDelegationDifferentModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("delegationWithPrivateConstructor.kt")
|
||||
public void testDelegationWithPrivateConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt");
|
||||
|
||||
Reference in New Issue
Block a user