From 44d03bc727e31e9c392953ffca42df18a6c1013e Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 15 Mar 2021 18:33:40 +0300 Subject: [PATCH] [Psi2Ir] Fix generation of property references for synthetic java props - Declare it on use-site - Fix export checker for that case - Fix KT-45297 --- compiler/ir/ir.psi2ir/build.gradle.kts | 1 + .../ReflectionReferencesGenerator.kt | 116 +++++++++++++++--- .../ir/declarations/IrDeclarationOrigin.kt | 2 + .../DescriptorExportCheckerVisitor.kt | 6 +- 4 files changed, 105 insertions(+), 20 deletions(-) diff --git a/compiler/ir/ir.psi2ir/build.gradle.kts b/compiler/ir/ir.psi2ir/build.gradle.kts index babccdc44a5..bda1394c526 100644 --- a/compiler/ir/ir.psi2ir/build.gradle.kts +++ b/compiler/ir/ir.psi2ir/build.gradle.kts @@ -6,6 +6,7 @@ plugins { dependencies { compile(project(":compiler:util")) compile(project(":compiler:frontend")) + compile(project(":compiler:frontend.java")) compile(project(":compiler:backend-common")) compile(project(":compiler:ir.tree")) compileOnly(intellijCoreDep()) { includeJars("intellij-core") } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt index 05b3dac008a..60321f098ac 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt @@ -18,16 +18,12 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction -import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol -import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.util.referenceClassifier @@ -42,6 +38,8 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource +import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.expressions.DoubleColonLHS @@ -428,6 +426,96 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St } } + private class DelegatedPropertySymbols(val propertySymbol: IrPropertySymbol, val getterSymbol: IrSimpleFunctionSymbol?, val setterSymbol: IrSimpleFunctionSymbol?) + + private class IrSyntheticJavaProperty( + @ObsoleteDescriptorBasedAPI + override val descriptor: SyntheticJavaPropertyDescriptor, + override val symbol: IrPropertySymbol, + private val getterSymbol: IrSimpleFunctionSymbol, + private val setterSymbol: IrSimpleFunctionSymbol?, + override val factory: IrFactory + ) : IrProperty() { + + init { + symbol.bind(this) + } + + override val isVar: Boolean + get() = descriptor.isVar + override val isConst: Boolean + get() = descriptor.isConst + override val isLateinit: Boolean + get() = descriptor.isLateInit + override val isDelegated: Boolean + get() = descriptor.isDelegated + override val isExpect: Boolean + get() = descriptor.isExpect + override val isFakeOverride: Boolean + get() = false + override var backingField: IrField? + get() = null + set(_) {} + override var getter: IrSimpleFunction? + get() = getterSymbol.owner.also { it.correspondingPropertySymbol = symbol } + set(_) {} + override var setter: IrSimpleFunction? + get() = setterSymbol?.owner?.also { it.correspondingPropertySymbol = symbol } + set(_) {} + override val startOffset: Int + get() = UNDEFINED_OFFSET + override val endOffset: Int + get() = UNDEFINED_OFFSET + override var origin: IrDeclarationOrigin + get() = IrDeclarationOrigin.SYNTHETIC_JAVA_PROPERTY_DELEGATE + set(_) {} + override var parent: IrDeclarationParent + get() = getterSymbol.owner.parent + set(_) {} + override var annotations: List + get() = emptyList() + set(_) {} + override val isExternal: Boolean + get() = descriptor.isExternal + override val name: Name + get() = descriptor.name + override val modality: Modality + get() = descriptor.modality + override var visibility: DescriptorVisibility + get() = descriptor.visibility + set(_) {} + override var metadata: MetadataSource? = DescriptorMetadataSource.Property(descriptor) + override var attributeOwnerId: IrAttributeContainer + get() = this + set(_) {} + override val containerSource: DeserializedContainerSource? + get() = null + } + + private fun resolvePropertySymbol(descriptor: PropertyDescriptor, mutable: Boolean): DelegatedPropertySymbols { + val symbol = context.symbolTable.referenceProperty(descriptor) + if (descriptor is SyntheticJavaPropertyDescriptor) { + // This is the special case of synthetic java properties when requested property doesn't even exist but IR design + // requires its symbol to be bound so let do that + // see `irText/declarations/provideDelegate/javaDelegate.kt` and KT-45297 + val getterSymbol = context.symbolTable.referenceSimpleFunction(descriptor.getMethod) + val setterSymbol = if (mutable) descriptor.setMethod?.let { + context.symbolTable.referenceSimpleFunction(it) + } else null + if (!symbol.isBound) { + val offset = UNDEFINED_OFFSET + context.symbolTable.declareProperty(offset, offset, IrDeclarationOrigin.SYNTHETIC_JAVA_PROPERTY_DELEGATE, descriptor) { + IrSyntheticJavaProperty(descriptor, it, getterSymbol, setterSymbol, context.irFactory) + } + } + return DelegatedPropertySymbols(symbol, getterSymbol, setterSymbol) + } else { + val getterSymbol = descriptor.getter?.let { context.symbolTable.referenceSimpleFunction(it) } + val setterSymbol = if (mutable) descriptor.setter?.let { context.symbolTable.referenceSimpleFunction(it) } else null + return DelegatedPropertySymbols(symbol, getterSymbol, setterSymbol) + } + } + private fun generatePropertyReference( startOffset: Int, endOffset: Int, @@ -438,17 +526,15 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St mutable: Boolean ): IrPropertyReference { val originalProperty = propertyDescriptor.original - val originalGetter = originalProperty.getter?.original - val originalSetter = if (mutable) originalProperty.setter?.original else null - val originalSymbol = context.symbolTable.referenceProperty(originalProperty) + val symbols = resolvePropertySymbol(originalProperty, mutable) return IrPropertyReferenceImpl( startOffset, endOffset, type.toIrType(), - originalSymbol, + symbols.propertySymbol, if (typeArguments != null) propertyDescriptor.typeParametersCount else 0, getFieldForPropertyReference(originalProperty), - originalGetter?.let { context.symbolTable.referenceSimpleFunction(it) }, - originalSetter?.let { context.symbolTable.referenceSimpleFunction(it) }, + symbols.getterSymbol, + symbols.setterSymbol, origin ).apply { context.callToSubstitutedDescriptorMap[this] = propertyDescriptor @@ -500,4 +586,4 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St arguments.last().type, suspendFunction ) -} +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt index e36da63f7c2..3c947045113 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt @@ -73,6 +73,8 @@ interface IrDeclarationOrigin { object GENERATED_SAM_IMPLEMENTATION : IrDeclarationOriginImpl("GENERATED_SAM_IMPLEMENTATION") object SYNTHETIC_GENERATED_SAM_IMPLEMENTATION : IrDeclarationOriginImpl("SYNTHETIC_GENERATED_SAM_IMPLEMENTATION", isSynthetic = true) + object SYNTHETIC_JAVA_PROPERTY_DELEGATE : IrDeclarationOriginImpl("SYNTHETIC_JAVA_PROPERTY_DELEGATE", isSynthetic = true) + val isSynthetic: Boolean get() = false } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorExportCheckerVisitor.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorExportCheckerVisitor.kt index d022962f565..7ef763e0744 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorExportCheckerVisitor.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorExportCheckerVisitor.kt @@ -19,10 +19,6 @@ abstract class DescriptorExportCheckerVisitor : DeclarationDescriptorVisitor