[Psi2Ir] Fix generation of property references for synthetic java props
- Declare it on use-site - Fix export checker for that case - Fix KT-45297
This commit is contained in:
@@ -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") }
|
||||
|
||||
+101
-15
@@ -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<IrConstructorCall>
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -19,10 +19,6 @@ abstract class DescriptorExportCheckerVisitor : DeclarationDescriptorVisitor<Boo
|
||||
return declaration.accept(this, type)
|
||||
}
|
||||
|
||||
private fun reportUnexpectedDescriptor(descriptor: DeclarationDescriptor): Nothing {
|
||||
error("unexpected descriptor $descriptor")
|
||||
}
|
||||
|
||||
private fun DescriptorVisibility.isPubliclyVisible(): Boolean = isPublicAPI || this === DescriptorVisibilities.INTERNAL
|
||||
|
||||
private fun DeclarationDescriptorNonRoot.isExported(annotations: Annotations, visibility: DescriptorVisibility?): Boolean {
|
||||
@@ -56,7 +52,7 @@ abstract class DescriptorExportCheckerVisitor : DeclarationDescriptorVisitor<Boo
|
||||
else descriptor.run { isExported(annotations, visibility) }
|
||||
|
||||
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: SpecialDeclarationType): Boolean {
|
||||
reportUnexpectedDescriptor(descriptor)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: SpecialDeclarationType): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user