[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 {
|
dependencies {
|
||||||
compile(project(":compiler:util"))
|
compile(project(":compiler:util"))
|
||||||
compile(project(":compiler:frontend"))
|
compile(project(":compiler:frontend"))
|
||||||
|
compile(project(":compiler:frontend.java"))
|
||||||
compile(project(":compiler:backend-common"))
|
compile(project(":compiler:backend-common"))
|
||||||
compile(project(":compiler:ir.tree"))
|
compile(project(":compiler:ir.tree"))
|
||||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||||
|
|||||||
+100
-14
@@ -18,16 +18,12 @@ package org.jetbrains.kotlin.psi2ir.generators
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.*
|
import org.jetbrains.kotlin.builtins.*
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
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.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.util.referenceClassifier
|
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.ImportedFromObjectCallableDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
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.KotlinType
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
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(
|
private fun generatePropertyReference(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -438,17 +526,15 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
|||||||
mutable: Boolean
|
mutable: Boolean
|
||||||
): IrPropertyReference {
|
): IrPropertyReference {
|
||||||
val originalProperty = propertyDescriptor.original
|
val originalProperty = propertyDescriptor.original
|
||||||
val originalGetter = originalProperty.getter?.original
|
val symbols = resolvePropertySymbol(originalProperty, mutable)
|
||||||
val originalSetter = if (mutable) originalProperty.setter?.original else null
|
|
||||||
val originalSymbol = context.symbolTable.referenceProperty(originalProperty)
|
|
||||||
|
|
||||||
return IrPropertyReferenceImpl(
|
return IrPropertyReferenceImpl(
|
||||||
startOffset, endOffset, type.toIrType(),
|
startOffset, endOffset, type.toIrType(),
|
||||||
originalSymbol,
|
symbols.propertySymbol,
|
||||||
if (typeArguments != null) propertyDescriptor.typeParametersCount else 0,
|
if (typeArguments != null) propertyDescriptor.typeParametersCount else 0,
|
||||||
getFieldForPropertyReference(originalProperty),
|
getFieldForPropertyReference(originalProperty),
|
||||||
originalGetter?.let { context.symbolTable.referenceSimpleFunction(it) },
|
symbols.getterSymbol,
|
||||||
originalSetter?.let { context.symbolTable.referenceSimpleFunction(it) },
|
symbols.setterSymbol,
|
||||||
origin
|
origin
|
||||||
).apply {
|
).apply {
|
||||||
context.callToSubstitutedDescriptorMap[this] = propertyDescriptor
|
context.callToSubstitutedDescriptorMap[this] = propertyDescriptor
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ interface IrDeclarationOrigin {
|
|||||||
object GENERATED_SAM_IMPLEMENTATION : IrDeclarationOriginImpl("GENERATED_SAM_IMPLEMENTATION")
|
object GENERATED_SAM_IMPLEMENTATION : IrDeclarationOriginImpl("GENERATED_SAM_IMPLEMENTATION")
|
||||||
object SYNTHETIC_GENERATED_SAM_IMPLEMENTATION : IrDeclarationOriginImpl("SYNTHETIC_GENERATED_SAM_IMPLEMENTATION", isSynthetic = true)
|
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
|
val isSynthetic: Boolean get() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -19,10 +19,6 @@ abstract class DescriptorExportCheckerVisitor : DeclarationDescriptorVisitor<Boo
|
|||||||
return declaration.accept(this, type)
|
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 DescriptorVisibility.isPubliclyVisible(): Boolean = isPublicAPI || this === DescriptorVisibilities.INTERNAL
|
||||||
|
|
||||||
private fun DeclarationDescriptorNonRoot.isExported(annotations: Annotations, visibility: DescriptorVisibility?): Boolean {
|
private fun DeclarationDescriptorNonRoot.isExported(annotations: Annotations, visibility: DescriptorVisibility?): Boolean {
|
||||||
@@ -56,7 +52,7 @@ abstract class DescriptorExportCheckerVisitor : DeclarationDescriptorVisitor<Boo
|
|||||||
else descriptor.run { isExported(annotations, visibility) }
|
else descriptor.run { isExported(annotations, visibility) }
|
||||||
|
|
||||||
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: SpecialDeclarationType): Boolean {
|
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: SpecialDeclarationType): Boolean {
|
||||||
reportUnexpectedDescriptor(descriptor)
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: SpecialDeclarationType): Boolean {
|
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: SpecialDeclarationType): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user