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

org.jetbrains.kotlin.ir.backend.js.lower.MoveOpenClassesToSeparateFiles.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2019 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.ir.backend.js.lower

import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
import org.jetbrains.kotlin.ir.util.transformFlat

fun moveOpenClassesToSeparateFiles(moduleFragment: IrModuleFragment) {
    fun createFile(file: IrFile, klass: IrClass): IrFile =
        IrFileImpl(fileEntry = file.fileEntry, fqName = file.fqName, symbol = IrFileSymbolImpl(), module = file.module).also {
            it.annotations += file.annotations
            it.declarations += klass
            klass.parent = it
        }

    moduleFragment.files.transformFlat { file ->
        // We don't have to split declarations with a single class
        if (file.declarations.size <= 1)
            return@transformFlat null

        val openClasses = mutableListOf()
        fun removeAndCollectOpenClasses(container: IrDeclarationContainer) {
            container.transformDeclarationsFlat { declaration ->
                if (declaration is IrDeclarationContainer) {
                    removeAndCollectOpenClasses(declaration)
                }
                if (
                    declaration is IrClass &&
                    (declaration.modality == Modality.OPEN || declaration.modality == Modality.ABSTRACT) &&
                    declaration.kind == ClassKind.CLASS &&
                    declaration.visibility != DescriptorVisibilities.PRIVATE &&
                    declaration.visibility != DescriptorVisibilities.LOCAL
                ) {
                    openClasses += declaration
                    emptyList()
                } else {
                    null
                }
            }
        }
        removeAndCollectOpenClasses(file)

        return@transformFlat if (openClasses.isEmpty())
            null
        else
            listOf(file) + openClasses.map { createFile(file, it) }
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy