Introduce IrLazyProperty
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.declarations.lazy
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||||
|
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.resolve.hasBackingField
|
||||||
|
|
||||||
|
class IrLazyProperty(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
origin: IrDeclarationOrigin,
|
||||||
|
override val descriptor: PropertyDescriptor,
|
||||||
|
override val name: Name,
|
||||||
|
override val visibility: Visibility,
|
||||||
|
override val modality: Modality,
|
||||||
|
override val isVar: Boolean,
|
||||||
|
override val isConst: Boolean,
|
||||||
|
override val isLateinit: Boolean,
|
||||||
|
override val isDelegated: Boolean,
|
||||||
|
override val isExternal: Boolean,
|
||||||
|
private val stubGenerator: DeclarationStubGenerator,
|
||||||
|
typeTranslator: TypeTranslator,
|
||||||
|
private val bindingContext: BindingContext? = null
|
||||||
|
) :
|
||||||
|
IrLazyDeclarationBase(startOffset, endOffset, origin, stubGenerator, typeTranslator),
|
||||||
|
IrProperty {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
origin: IrDeclarationOrigin,
|
||||||
|
descriptor: PropertyDescriptor,
|
||||||
|
stubGenerator: DeclarationStubGenerator,
|
||||||
|
typeTranslator: TypeTranslator,
|
||||||
|
bindingContext: BindingContext?
|
||||||
|
) : this(
|
||||||
|
startOffset, endOffset, origin, descriptor,
|
||||||
|
descriptor.name, descriptor.visibility, descriptor.modality,
|
||||||
|
isVar = descriptor.isVar,
|
||||||
|
isConst = descriptor.isConst,
|
||||||
|
isLateinit = descriptor.isLateInit,
|
||||||
|
isDelegated = descriptor.isDelegated,
|
||||||
|
isExternal = descriptor.isEffectivelyExternal(),
|
||||||
|
stubGenerator = stubGenerator,
|
||||||
|
typeTranslator = typeTranslator,
|
||||||
|
bindingContext = bindingContext
|
||||||
|
)
|
||||||
|
|
||||||
|
override var backingField: IrField? by lazyVar {
|
||||||
|
if (descriptor.hasBackingField(bindingContext)) {
|
||||||
|
stubGenerator.generateFieldStub(descriptor, bindingContext).apply {
|
||||||
|
correspondingProperty = this@IrLazyProperty
|
||||||
|
}
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
override var getter: IrSimpleFunction? by lazyVar {
|
||||||
|
descriptor.getter?.let { stubGenerator.generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
|
||||||
|
correspondingProperty = this@IrLazyProperty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override var setter: IrSimpleFunction? by lazyVar {
|
||||||
|
descriptor.setter?.let { stubGenerator.generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
|
||||||
|
correspondingProperty = this@IrLazyProperty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitProperty(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
backingField?.accept(visitor, data)
|
||||||
|
getter?.accept(visitor, data)
|
||||||
|
setter?.accept(visitor, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||||
|
backingField = backingField?.transform(transformer, data) as? IrField
|
||||||
|
getter = getter?.run { transform(transformer, data) as IrSimpleFunction }
|
||||||
|
setter = setter?.run { transform(transformer, data) as IrSimpleFunction }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.lazy.*
|
import org.jetbrains.kotlin.ir.declarations.lazy.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||||
@@ -83,25 +82,14 @@ class DeclarationStubGenerator(
|
|||||||
internal fun generatePropertyStub(
|
internal fun generatePropertyStub(
|
||||||
descriptor: PropertyDescriptor,
|
descriptor: PropertyDescriptor,
|
||||||
bindingContext: BindingContext? = null
|
bindingContext: BindingContext? = null
|
||||||
): IrProperty =
|
): IrProperty = symbolTable.referenceProperty(descriptor) {
|
||||||
IrPropertyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irProperty ->
|
IrLazyProperty(
|
||||||
if (descriptor.hasBackingField(bindingContext)) {
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor,
|
||||||
irProperty.backingField = generateFieldStub(descriptor)
|
this, typeTranslator, bindingContext
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
irProperty.getter = descriptor.getter?.let { generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
|
fun generateFieldStub(descriptor: PropertyDescriptor, bindingContext: BindingContext? = null): IrField {
|
||||||
correspondingProperty = irProperty
|
|
||||||
}
|
|
||||||
irProperty.setter = descriptor.setter?.let { generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
|
|
||||||
correspondingProperty = irProperty
|
|
||||||
}
|
|
||||||
// Do we ever generate stubs for file-level properties?
|
|
||||||
(descriptor.containingDeclaration as? ClassDescriptor)?.let {
|
|
||||||
irProperty.parent = generateClassStub(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateFieldStub(descriptor: PropertyDescriptor): IrField {
|
|
||||||
val referenced = symbolTable.referenceField(descriptor)
|
val referenced = symbolTable.referenceField(descriptor)
|
||||||
if (referenced.isBound) {
|
if (referenced.isBound) {
|
||||||
return referenced.owner
|
return referenced.owner
|
||||||
@@ -119,6 +107,7 @@ class DeclarationStubGenerator(
|
|||||||
descriptor.original,
|
descriptor.original,
|
||||||
descriptor.type.toIrType()
|
descriptor.type.toIrType()
|
||||||
).apply {
|
).apply {
|
||||||
|
correspondingProperty = generatePropertyStub(descriptor, bindingContext)
|
||||||
initializer = descriptor.compileTimeInitializer?.let {
|
initializer = descriptor.compileTimeInitializer?.let {
|
||||||
IrExpressionBodyImpl(
|
IrExpressionBodyImpl(
|
||||||
constantValueGenerator.generateConstantValueAsExpression(
|
constantValueGenerator.generateConstantValueAsExpression(
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ class ExternalDependenciesGenerator(
|
|||||||
stubGenerator.generateEnumEntryStub(it.descriptor)
|
stubGenerator.generateEnumEntryStub(it.descriptor)
|
||||||
}
|
}
|
||||||
ArrayList(symbolTable.unboundFields).forEach {
|
ArrayList(symbolTable.unboundFields).forEach {
|
||||||
stubGenerator.generatePropertyStub(it.descriptor, bindingContext)
|
stubGenerator.generateFieldStub(it.descriptor, bindingContext)
|
||||||
}
|
}
|
||||||
ArrayList(symbolTable.unboundSimpleFunctions).forEach {
|
ArrayList(symbolTable.unboundSimpleFunctions).forEach {
|
||||||
stubGenerator.generateFunctionStub(it.descriptor)
|
stubGenerator.generateFunctionStub(it.descriptor)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ interface ReferenceSymbolTable {
|
|||||||
|
|
||||||
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol
|
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol
|
||||||
fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol
|
fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol
|
||||||
|
fun referenceProperty(descriptor: PropertyDescriptor, generate: () -> IrProperty): IrProperty
|
||||||
|
|
||||||
fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
|
fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
|
||||||
fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
|
fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
|
||||||
@@ -296,6 +297,10 @@ open class SymbolTable : ReferenceSymbolTable {
|
|||||||
|
|
||||||
val unboundFields: Set<IrFieldSymbol> get() = fieldSymbolTable.unboundSymbols
|
val unboundFields: Set<IrFieldSymbol> get() = fieldSymbolTable.unboundSymbols
|
||||||
|
|
||||||
|
val propertyTable = HashMap<PropertyDescriptor, IrProperty>()
|
||||||
|
override fun referenceProperty(descriptor: PropertyDescriptor, generate: () -> IrProperty): IrProperty =
|
||||||
|
propertyTable.getOrPut(descriptor, generate)
|
||||||
|
|
||||||
fun declareSimpleFunction(
|
fun declareSimpleFunction(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
|
|||||||
Reference in New Issue
Block a user