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

org.jetbrains.kotlin.descriptors.annotations.Annotations.kt Maven / Gradle / Ivy

/*
 * Copyright 2010-2015 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.descriptors.annotations

import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils

public interface Annotations : Iterable {

    public fun isEmpty(): Boolean

    public fun findAnnotation(fqName: FqName): AnnotationDescriptor?

    public fun findExternalAnnotation(fqName: FqName): AnnotationDescriptor?

    public fun getUseSiteTargetedAnnotations(): List

    // Returns both targeted and annotations without target. Annotation order is preserved.
    public fun getAllAnnotations(): List

    companion object {
        public val EMPTY: Annotations = object : Annotations {
            override fun isEmpty() = true

            override fun findAnnotation(fqName: FqName) = null

            override fun findExternalAnnotation(fqName: FqName) = null

            override fun getUseSiteTargetedAnnotations() = emptyList()

            override fun getAllAnnotations() = emptyList()

            override fun iterator() = emptyList().iterator()

            override fun toString() = "EMPTY"
        }

        public fun findAnyAnnotation(annotations: Annotations, fqName: FqName): AnnotationWithTarget? {
            return annotations.getAllAnnotations().firstOrNull { checkAnnotationName(it.annotation, fqName) }
        }

        public fun findUseSiteTargetedAnnotation(annotations: Annotations, target: AnnotationUseSiteTarget, fqName: FqName): AnnotationDescriptor? {
            return getUseSiteTargetedAnnotations(annotations, target).firstOrNull { checkAnnotationName(it, fqName) }
        }

        private fun getUseSiteTargetedAnnotations(annotations: Annotations, target: AnnotationUseSiteTarget): List {
            return annotations.getUseSiteTargetedAnnotations().fold(arrayListOf()) { list, targeted ->
                if (target == targeted.target) {
                    list.add(targeted.annotation)
                }
                list
            }
        }
    }
}

private fun checkAnnotationName(annotation: AnnotationDescriptor, fqName: FqName): Boolean {
    val descriptor = annotation.type.constructor.declarationDescriptor
    return descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
}

class FilteredAnnotations(
        private val delegate: Annotations,
        private val fqNameFilter: (FqName) -> Boolean
) : Annotations {
    override fun findAnnotation(fqName: FqName) =
            if (fqNameFilter(fqName)) delegate.findAnnotation(fqName)
            else null

    override fun findExternalAnnotation(fqName: FqName) =
            if (fqNameFilter(fqName)) delegate.findExternalAnnotation(fqName)
            else null

    override fun getUseSiteTargetedAnnotations(): List {
        return delegate.getUseSiteTargetedAnnotations().filter { shouldBeReturned(it.annotation) }
    }

    override fun getAllAnnotations(): List {
        return delegate.getAllAnnotations().filter { shouldBeReturned(it.annotation) }
    }

    override fun iterator() = delegate.filter { shouldBeReturned(it) }.iterator()

    private fun shouldBeReturned(annotation: AnnotationDescriptor): Boolean {
        val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor()
        return descriptor != null && DescriptorUtils.getFqName(descriptor).let { fqName ->
            fqName.isSafe() && fqNameFilter(fqName.toSafe())
        }
    }

    override fun isEmpty() = !iterator().hasNext()
}

class CompositeAnnotations(
        private val delegates: List
) : Annotations {
    constructor(vararg delegates: Annotations): this(delegates.toList())

    override fun isEmpty() = delegates.all { it.isEmpty() }

    override fun findAnnotation(fqName: FqName) = delegates.asSequence().map { it.findAnnotation(fqName) }.filterNotNull().firstOrNull()

    override fun findExternalAnnotation(fqName: FqName) = delegates.asSequence().map { it.findExternalAnnotation(fqName) }.filterNotNull().firstOrNull()

    override fun getUseSiteTargetedAnnotations() = delegates.flatMap { it.getUseSiteTargetedAnnotations() }

    override fun getAllAnnotations() = delegates.flatMap { it.getAllAnnotations() }

    override fun iterator() = delegates.asSequence().flatMap { it.asSequence() }.iterator()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy