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.ir.UNDEFINED_OFFSET
|
||||
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.lazy.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
@@ -83,25 +82,14 @@ class DeclarationStubGenerator(
|
||||
internal fun generatePropertyStub(
|
||||
descriptor: PropertyDescriptor,
|
||||
bindingContext: BindingContext? = null
|
||||
): IrProperty =
|
||||
IrPropertyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor).also { irProperty ->
|
||||
if (descriptor.hasBackingField(bindingContext)) {
|
||||
irProperty.backingField = generateFieldStub(descriptor)
|
||||
}
|
||||
): IrProperty = symbolTable.referenceProperty(descriptor) {
|
||||
IrLazyProperty(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor,
|
||||
this, typeTranslator, bindingContext
|
||||
)
|
||||
}
|
||||
|
||||
irProperty.getter = descriptor.getter?.let { generateFunctionStub(it, createPropertyIfNeeded = false) }?.apply {
|
||||
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 {
|
||||
fun generateFieldStub(descriptor: PropertyDescriptor, bindingContext: BindingContext? = null): IrField {
|
||||
val referenced = symbolTable.referenceField(descriptor)
|
||||
if (referenced.isBound) {
|
||||
return referenced.owner
|
||||
@@ -119,6 +107,7 @@ class DeclarationStubGenerator(
|
||||
descriptor.original,
|
||||
descriptor.type.toIrType()
|
||||
).apply {
|
||||
correspondingProperty = generatePropertyStub(descriptor, bindingContext)
|
||||
initializer = descriptor.compileTimeInitializer?.let {
|
||||
IrExpressionBodyImpl(
|
||||
constantValueGenerator.generateConstantValueAsExpression(
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ class ExternalDependenciesGenerator(
|
||||
stubGenerator.generateEnumEntryStub(it.descriptor)
|
||||
}
|
||||
ArrayList(symbolTable.unboundFields).forEach {
|
||||
stubGenerator.generatePropertyStub(it.descriptor, bindingContext)
|
||||
stubGenerator.generateFieldStub(it.descriptor, bindingContext)
|
||||
}
|
||||
ArrayList(symbolTable.unboundSimpleFunctions).forEach {
|
||||
stubGenerator.generateFunctionStub(it.descriptor)
|
||||
|
||||
@@ -39,6 +39,7 @@ interface ReferenceSymbolTable {
|
||||
|
||||
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol
|
||||
fun referenceField(descriptor: PropertyDescriptor): IrFieldSymbol
|
||||
fun referenceProperty(descriptor: PropertyDescriptor, generate: () -> IrProperty): IrProperty
|
||||
|
||||
fun referenceSimpleFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
|
||||
fun referenceDeclaredFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol
|
||||
@@ -296,6 +297,10 @@ open class SymbolTable : ReferenceSymbolTable {
|
||||
|
||||
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(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
|
||||
Reference in New Issue
Block a user