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

org.jetbrains.kotlin.resolve.calls.DslMarkerUtils.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2000-2018 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.resolve.calls

import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.getAbbreviation
import org.jetbrains.kotlin.utils.addToStdlib.safeAs

object DslMarkerUtils {

    object FunctionTypeAnnotationsKey : CallableDescriptor.UserDataKey

    data class DslMarkersFromReceiver(
        val common: Set,
        val fromContainingFunctionType: Set
    ) {
        fun all() = common + fromContainingFunctionType
    }

    fun extractDslMarkerFqNames(receiver: ReceiverValue): DslMarkersFromReceiver {
        val errorLevel = extractDslMarkerFqNames(receiver.type)

        val deprecationLevel =
            receiver.safeAs()
                ?.declarationDescriptor
                ?.safeAs()
                ?.getUserData(FunctionTypeAnnotationsKey)
                ?.let(Annotations::extractDslMarkerFqNames)
                ?.toSet() ?: emptySet()

        return DslMarkersFromReceiver(errorLevel, deprecationLevel)
    }

    fun extractDslMarkerFqNames(kotlinType: KotlinType): Set {
        val result = mutableSetOf()

        result.addAll(kotlinType.annotations.extractDslMarkerFqNames())

        kotlinType.getAbbreviation()?.constructor?.declarationDescriptor?.run {
            result.addAll(annotations.extractDslMarkerFqNames())
            safeAs()?.run {
                result.addAll(extractDslMarkerFqNames(this.underlyingType))
            }
        }

        kotlinType.constructor.declarationDescriptor?.getAllSuperClassifiers()?.asIterable()
            ?.flatMapTo(result) { it.annotations.extractDslMarkerFqNames() }

        return result
    }

    val DSL_MARKER_FQ_NAME = FqName("kotlin.DslMarker")
}


private fun Annotations.extractDslMarkerFqNames() =
    filter(AnnotationDescriptor::isDslMarker).mapNotNull { it.fqName }

private fun AnnotationDescriptor.isDslMarker(): Boolean {
    val classDescriptor = annotationClass ?: return false
    return classDescriptor.annotations.hasAnnotation(DslMarkerUtils.DSL_MARKER_FQ_NAME)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy