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

org.jetbrains.kotlin.load.kotlin.JvmPackagePartProviderBase.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.load.kotlin

import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.metadata.jvm.deserialization.PackageParts
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider

abstract class JvmPackagePartProviderBase : PackagePartProvider, MetadataPartProvider {

    protected data class ModuleMappingInfo(val key: MappingsKey, val mapping: ModuleMapping, val name: String)

    protected abstract val loadedModules: MutableList>

    override fun findPackageParts(packageFqName: String): List {
        val rootToPackageParts: Collection = getPackageParts(packageFqName)
        if (rootToPackageParts.isEmpty()) return emptyList()

        val result = linkedSetOf()
        val visitedMultifileFacades = linkedSetOf()
        for (packageParts in rootToPackageParts) {
            for (name in packageParts.parts) {
                val facadeName = packageParts.getMultifileFacadeName(name)
                if (facadeName == null || facadeName !in visitedMultifileFacades) {
                    result.add(name)
                }
            }
            packageParts.parts.mapNotNullTo(visitedMultifileFacades, packageParts::getMultifileFacadeName)
        }
        return result.toList()
    }

    override fun findMetadataPackageParts(packageFqName: String): List =
        getPackageParts(packageFqName).flatMap(PackageParts::metadataParts).distinct()

    private fun getPackageParts(packageFqName: String): Collection {
        val result = mutableMapOf()
        for ((root, mapping) in loadedModules) {
            val newParts = mapping.findPackageParts(packageFqName) ?: continue
            result[root]?.let { parts -> parts += newParts } ?: result.put(root, newParts)
        }
        return result.values
    }

    override fun getAnnotationsOnBinaryModule(moduleName: String): List {
        return loadedModules.mapNotNull { (_, mapping, name) ->
            if (name == moduleName) mapping.moduleData.annotations.map(ClassId::fromString) else null
        }.flatten()
    }

    override fun getAllOptionalAnnotationClasses(): List =
        loadedModules.flatMap { module ->
            getAllOptionalAnnotationClasses(module.mapping)
        }

    companion object {
        fun getAllOptionalAnnotationClasses(module: ModuleMapping): List {
            val data = module.moduleData
            return data.optionalAnnotations.map { proto ->
                ClassData(data.nameResolver, proto, module.version, SourceElement.NO_SOURCE)
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy