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

org.jetbrains.kotlin.ir.util.transform.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * Copyright 2010-2016 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.kotlin.ir.util

import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer

inline fun  MutableList.transformInPlace(transformation: (T) -> IrElement) {
    for (i in 0 until size) {
        set(i, transformation(get(i)) as T)
    }
}

fun  MutableList.transformInPlace(transformer: IrElementTransformer, data: D) {
    for (i in 0 until size) {
        // Cast to IrElementBase to avoid casting to interface and invokeinterface, both of which are slow.
        @Suppress("UNCHECKED_CAST")
        set(i, (get(i) as IrElementBase).transform(transformer, data) as T)
    }
}

fun  Array.transformInPlace(transformer: IrElementTransformer, data: D) {
    for (i in indices) {
        // Cast to IrElementBase to avoid casting to interface and invokeinterface, both of which are slow.
        val element = get(i) as IrElementBase?
        if (element != null) {
            @Suppress("UNCHECKED_CAST")
            set(i, element.transform(transformer, data) as T)
        }
    }
}

/**
 * Transforms a mutable list in place.
 * Each element `it` is replaced with a result of `transformation(it)`,
 * `null` means "keep existing element" (to avoid creating excessive singleton lists).
 */
inline fun  MutableList.transformFlat(transformation: (T) -> List?) {
    var i = 0
    while (i < size) {
        val item = get(i)

        i = replaceInPlace(transformation(item), i)
    }
}

/**
 * Transforms a subset of a mutable list in place.
 * Each element `it` that has a type S is replaced with a result of `transformation(it)`,
 * `null` means "keep existing element" (to avoid creating excessive singleton lists).
 */
inline fun  MutableList.transformSubsetFlat(transformation: (S) -> List?) {
    var i = 0
    while (i < size) {
        val item = get(i)

        if (item !is S) {
            i++
            continue
        }

        i = replaceInPlace(transformation(item), i)
    }
}

@PublishedApi internal fun  MutableList.replaceInPlace(transformed: List?, atIndex: Int): Int {
    var i = atIndex
    when (transformed?.size) {
        null -> i++
        0 -> removeAt(i)
        1 -> set(i++, transformed[0])
        else -> {
            addAll(i, transformed)
            i += transformed.size
            removeAt(i)
        }
    }
    return i
}

/**
 * Transforms declarations in declaration container.
 * Behaves similar to like MutableList.transformFlat but also updates
 * parent property for transformed declarations.
 */
fun IrDeclarationContainer.transformDeclarationsFlat(transformation: (IrDeclaration) -> List?) {
    declarations.transformFlat { declaration ->
        val transformed = transformation(declaration)
        transformed?.forEach { it.parent = this }
        transformed
    }
}

/**
 * Transforms the list of elements with the given transformer. Return the same List instance if no element instances have changed.
 */
fun  List.transformIfNeeded(transformer: IrElementTransformer, data: D): List {
    var result: ArrayList? = null
    for ((i, item) in withIndex()) {
        @Suppress("UNCHECKED_CAST")
        val transformed = item.transform(transformer, data) as T
        if (transformed !== item && result == null) {
            result = ArrayList(this)
        }
        result?.set(i, transformed)
    }
    return result ?: this
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy