All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.backend.common.Mappings.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * 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.backend.common

import org.jetbrains.kotlin.ir.IrAttribute
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.get
import org.jetbrains.kotlin.ir.irAttribute
import org.jetbrains.kotlin.ir.set
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KMutableProperty0
import kotlin.reflect.KProperty

open class Mapping {
    val defaultArgumentsDispatchFunction: DeclarationMapping by AttributeBasedMappingDelegate()
    val defaultArgumentsOriginalFunction: MapBasedMapping = MapBasedMapping()
    val suspendFunctionToCoroutineConstructor: DeclarationMapping by AttributeBasedMappingDelegate()
    val lateInitFieldToNullableField: DeclarationMapping by AttributeBasedMappingDelegate()
    val inlineClassMemberToStatic: DeclarationMapping by AttributeBasedMappingDelegate()
    val capturedFields: DeclarationMapping> by AttributeBasedMappingDelegate()
    val capturedConstructors: MapBasedMapping = MapBasedMapping()
    val reflectedNameAccessor: DeclarationMapping by AttributeBasedMappingDelegate()
    val suspendFunctionsToFunctionWithContinuations: DeclarationMapping by AttributeBasedMappingDelegate()
    val functionWithContinuationsToSuspendFunctions: DeclarationMapping by AttributeBasedMappingDelegate()

    abstract class DeclarationMapping {
        abstract operator fun get(declaration: K): V?
        abstract operator fun set(declaration: K, value: V?)

        operator fun getValue(thisRef: K, desc: KProperty<*>): V? = get(thisRef)

        operator fun setValue(thisRef: K, desc: KProperty<*>, value: V?) {
            set(thisRef, value)
        }
    }

    /**
     * Mapping from K to V backed by a regular MutableMap.
     * Its only use is when the access to [keys] is necessary,
     * otherwise it should be avoided.
     */
    class MapBasedMapping : DeclarationMapping() {
        private val map: MutableMap = ConcurrentHashMap()

        override operator fun get(declaration: K): V? {
            return map[declaration]
        }

        override operator fun set(declaration: K, value: V?) {
            if (value == null) {
                map.remove(declaration)
            } else {
                map[declaration] = value
            }
        }

        val keys: Set
            get() = map.keys
    }

    /**
     * Mapping from K to V backed by [IrAttribute].
     * Usages are to be refactored to use [IrAttribute]s directly - KT-69082.
     */
    protected class AttributeBasedMapping(
        private val attribute: IrAttribute
    ) : DeclarationMapping() {
        override fun get(declaration: K): V? {
            return declaration[attribute]
        }

        override fun set(declaration: K, value: V?) {
            declaration[attribute] = value
        }
    }

    protected class AttributeBasedMappingDelegate () {
        private lateinit var mapping: AttributeBasedMapping

        operator fun provideDelegate(thisRef: Any?, desc: KProperty<*>): AttributeBasedMappingDelegate {
            val attribute = irAttribute(followAttributeOwner = false).provideDelegate(thisRef, desc)
            this.mapping = AttributeBasedMapping(attribute)
            return this
        }

        operator fun getValue(thisRef: Any?, desc: KProperty<*>): AttributeBasedMapping {
            return mapping
        }
    }
}

fun  KMutableProperty0.getOrPut(fn: () -> V) = this.get() ?: fn().also {
    this.set(it)
}

fun  Mapping.DeclarationMapping.getOrPut(key: K, fn: () -> V) = this[key] ?: fn().also {
    this[key] = it
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy