~~ Measure lazy IR expansion
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSymbolsMappingForLazyClasses.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSymbolsMappingForLazyClasses.kt
index 6b22362..64995b9 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSymbolsMappingForLazyClasses.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrSymbolsMappingForLazyClasses.kt
@@ -5,11 +5,13 @@
 
 package org.jetbrains.kotlin.fir.backend
 
+import org.jetbrains.kotlin.builtins.StandardNames.FqNames.map
 import org.jetbrains.kotlin.ir.IrLock
 import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
 import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
 import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
 import org.jetbrains.kotlin.ir.util.SymbolRemapper
+import kotlin.properties.PropertyDelegateProvider
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KProperty
 
@@ -60,8 +62,9 @@
     initializer: () -> T,
     val map: Fir2IrSymbolsMappingForLazyClasses,
     val mapperFun: Fir2IrSymbolsMappingForLazyClasses.(T) -> T
-) : ReadWriteProperty<Any?, T> {
-    private val lazy = lazyVar(lock, initializer)
+) : ReadWriteProperty<Any?, T>, PropertyDelegateProvider<Any, ReadWriteProperty<Any?, T>> {
+    @Suppress("UNCHECKED_CAST")
+    private val lazy = lazyVar(lock, initializer) as ReadWriteProperty<Any?, T>
 
     @Volatile
     private var lastSeenGeneration: Int = -1
@@ -85,26 +88,32 @@
             lastSeenGeneration = map.generation
         }
     }
+
+    override fun provideDelegate(thisRef: Any, property: KProperty<*>): ReadWriteProperty<Any?, T> {
+        @Suppress("UNCHECKED_CAST")
+        (lazy as PropertyDelegateProvider<Any, *>).provideDelegate(thisRef, property)
+        return this
+    }
 }
 
 fun <T> Fir2IrSymbolsMappingForLazyClasses.lazyMappedVar(
     lock: IrLock,
     initializer: () -> T,
     mapFunction: Fir2IrSymbolsMappingForLazyClasses.(T) -> T
-): ReadWriteProperty<Any?, T> {
+): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, T>> {
     return MappedLazyVar(lock, initializer, this, mapFunction)
 }
 
 fun Fir2IrSymbolsMappingForLazyClasses.lazyMappedFunctionListVar(
     lock: IrLock,
     initializer: () -> List<IrSimpleFunctionSymbol>
-): ReadWriteProperty<Any?, List<IrSimpleFunctionSymbol>> = lazyMappedVar(lock, initializer) { list ->
+): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, List<IrSimpleFunctionSymbol>>> = lazyMappedVar(lock, initializer) { list ->
     list.map { remapFunctionSymbol(it) }
 }
 
 fun Fir2IrSymbolsMappingForLazyClasses.lazyMappedPropertyListVar(
     lock: IrLock,
     initializer: () -> List<IrPropertySymbol>
-): ReadWriteProperty<Any?, List<IrPropertySymbol>> = lazyMappedVar(lock, initializer) { list ->
+): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, List<IrPropertySymbol>>> = lazyMappedVar(lock, initializer) { list ->
     list.map { remapPropertySymbol(it) }
 }
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyDeclaration.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyDeclaration.kt
index d7a47a2..7460b09 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyDeclaration.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyDeclaration.kt
@@ -15,6 +15,7 @@
 import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
 import org.jetbrains.kotlin.ir.util.TypeTranslator
 import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
+import kotlin.properties.PropertyDelegateProvider
 import kotlin.properties.ReadWriteProperty
 
 interface AbstractFir2IrLazyDeclaration<F> :
@@ -25,7 +26,7 @@
     override val factory: IrFactory
         get() = irFactory
 
-    override fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(lock) {
+    override fun createLazyAnnotations(): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, List<IrConstructorCall>>> = lazyVar(lock) {
         fir.annotations.mapNotNull {
             callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
         }
@@ -35,6 +36,10 @@
         get() = shouldNotBeCalled()
     override val typeTranslator: TypeTranslator
         get() = shouldNotBeCalled()
+
+    fun created() {
+        println("!!! created ${this.javaClass.simpleName}")
+    }
 }
 
 internal fun mutationNotSupported(): Nothing =
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyFunction.kt
index 126b83d..44c6c15 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyFunction.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/AbstractFir2IrLazyFunction.kt
@@ -28,6 +28,7 @@
 import org.jetbrains.kotlin.ir.util.isFacadeClass
 import org.jetbrains.kotlin.ir.util.isObject
 import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
+import kotlin.properties.PropertyDelegateProvider
 import kotlin.properties.ReadWriteProperty
 
 abstract class AbstractFir2IrLazyFunction<F : FirCallableDeclaration>(
@@ -123,7 +124,7 @@
     override val factory: IrFactory
         get() = super<AbstractFir2IrLazyDeclaration>.factory
 
-    override fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> {
+    override fun createLazyAnnotations(): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, List<IrConstructorCall>>> {
         return super<AbstractFir2IrLazyDeclaration>.createLazyAnnotations()
     }
 
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt
index d7c4305..356f275 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt
@@ -46,6 +46,7 @@
 ) : IrClass(), AbstractFir2IrLazyDeclaration<FirRegularClass>, Fir2IrTypeParametersContainer,
     IrMaybeDeserializedClass, Fir2IrComponents by c {
     init {
+        created()
         this.parent = parent
         symbol.bind(this)
         classifierStorage.preCacheTypeParameters(fir)
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt
index 5aeb169..93b1b55 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt
@@ -42,6 +42,7 @@
 ) : IrConstructor(), AbstractFir2IrLazyDeclaration<FirConstructor>, Fir2IrTypeParametersContainer,
     Fir2IrComponents by c {
     init {
+        created()
         this.parent = parent
         symbol.bind(this)
         classifierStorage.preCacheTypeParameters(fir)
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyField.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyField.kt
index 384402dd6..b5910bb 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyField.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyField.kt
@@ -43,6 +43,7 @@
     correspondingPropertySymbol: IrPropertySymbol?
 ) : IrField(), AbstractFir2IrLazyDeclaration<FirField>, Fir2IrComponents by c {
     init {
+        created()
         symbol.bind(this)
     }
 
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt
index 9df6d24..71c3862 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt
@@ -56,6 +56,7 @@
         set(_) = shouldNotBeCalled()
 
     init {
+        created()
         this.parent = parent
         symbol.bind(this)
         classifierStorage.preCacheTypeParameters(fir)
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt
index e560764..04b80cf 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt
@@ -41,6 +41,7 @@
     override var correspondingPropertySymbol: IrPropertySymbol?
 ) : AbstractFir2IrLazyFunction<FirCallableDeclaration>(c, startOffset, endOffset, origin, symbol, parent, isFakeOverride) {
     init {
+        created()
         symbol.bind(this)
     }
 
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt
index c5f9613..58dfa60 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt
@@ -36,6 +36,7 @@
     isFakeOverride: Boolean
 ) : AbstractFir2IrLazyFunction<FirSimpleFunction>(c, startOffset, endOffset, origin, symbol, parent, isFakeOverride) {
     init {
+        created()
         symbol.bind(this)
         classifierStorage.preCacheTypeParameters(fir)
     }
diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyTypeAlias.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyTypeAlias.kt
index aaa81b1..5b1cbfa 100644
--- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyTypeAlias.kt
+++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyTypeAlias.kt
@@ -33,6 +33,7 @@
     parent: IrDeclarationParent,
 ) : IrTypeAlias(), AbstractFir2IrLazyDeclaration<FirTypeAlias>, Fir2IrTypeParametersContainer, Fir2IrComponents by c {
     init {
+        created()
         this.parent = parent
         symbol.bind(this)
         classifierStorage.preCacheTypeParameters(fir)
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyDeclarationBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyDeclarationBase.kt
index 338b372..3a9a6c2 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyDeclarationBase.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyDeclarationBase.kt
@@ -16,6 +16,7 @@
 import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
 import org.jetbrains.kotlin.ir.util.TypeTranslator
 import org.jetbrains.kotlin.types.KotlinType
+import kotlin.properties.PropertyDelegateProvider
 import kotlin.properties.ReadWriteProperty
 
 @OptIn(ObsoleteDescriptorBasedAPI::class)
@@ -45,7 +46,7 @@
             isHidden = false,
         )
 
-    fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(stubGenerator.lock) {
+    fun createLazyAnnotations(): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, List<IrConstructorCall>>> = lazyVar(stubGenerator.lock) {
         descriptor.annotations.mapNotNull(typeTranslator.constantValueGenerator::generateAnnotationConstructorCall).toMutableList()
     }
 }
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt
index d88e2a0..b9f30bb 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt
@@ -6,12 +6,15 @@
 package org.jetbrains.kotlin.ir.declarations.lazy
 
 import org.jetbrains.kotlin.ir.IrLock
+import kotlin.properties.PropertyDelegateProvider
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KProperty
 
-fun <T> lazyVar(lock: IrLock, initializer: () -> T): ReadWriteProperty<Any?, T> = SynchronizedLazyVar(lock, initializer)
+fun <T> lazyVar(lock: IrLock, initializer: () -> T): PropertyDelegateProvider<Any, ReadWriteProperty<Any?, T>> =
+    SynchronizedLazyVar(lock, initializer)
 
-private class SynchronizedLazyVar<T>(val lock: IrLock, initializer: () -> T) : ReadWriteProperty<Any?, T> {
+private class SynchronizedLazyVar<T>(val lock: IrLock, initializer: () -> T) :
+    ReadWriteProperty<Any?, T>, PropertyDelegateProvider<Any?, SynchronizedLazyVar<T>> {
     @Volatile
     private var isInitialized = false
 
@@ -26,6 +29,8 @@
             if (isInitialized) return _value as T
             synchronized(lock) {
                 if (!isInitialized) {
+                    println("!!! initialized $name")
+
                     _value = initializer!!()
                     isInitialized = true
                     initializer = null
@@ -41,8 +46,20 @@
 
     override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
         synchronized(lock) {
+            if (!isInitialized) {
+                println("!!! set $name")
+            }
+
             this._value = value
             isInitialized = true
         }
     }
+
+
+    private lateinit var name: String
+
+    override fun provideDelegate(thisRef: Any?, property: KProperty<*>): SynchronizedLazyVar<T> {
+        name = thisRef!!.javaClass.simpleName + "." + property.name
+        return this
+    }
 }