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

org.jetbrains.kotlin.load.java.typeEnhancement.typeEnhancementUtils.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2020 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.java.typeEnhancement

import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker

private fun  Set.select(low: T, high: T, own: T?, isCovariant: Boolean): T? {
    if (isCovariant) {
        val supertypeQualifier = if (low in this) low else if (high in this) high else null
        return if (supertypeQualifier == low && own == high) null else own ?: supertypeQualifier
    }

    // isInvariant
    val effectiveSet = own?.let { (this + own).toSet() } ?: this
    // if this set contains exactly one element, it is the qualifier everybody agrees upon,
    // otherwise (no qualifiers, or multiple qualifiers), there's no single such qualifier
    // and all qualifiers are discarded
    return effectiveSet.singleOrNull()
}

private fun Set.select(own: NullabilityQualifier?, isCovariant: Boolean) =
    if (own == NullabilityQualifier.FORCE_FLEXIBILITY)
        NullabilityQualifier.FORCE_FLEXIBILITY
    else
        select(NullabilityQualifier.NOT_NULL, NullabilityQualifier.NULLABLE, own, isCovariant)

private val JavaTypeQualifiers.nullabilityForErrors: NullabilityQualifier?
    get() = if (isNullabilityQualifierForWarning) null else nullability

fun JavaTypeQualifiers.computeQualifiersForOverride(
    superQualifiers: Collection,
    isCovariant: Boolean,
    isForVarargParameter: Boolean,
    ignoreDeclarationNullabilityAnnotations: Boolean
): JavaTypeQualifiers {
    val newNullabilityForErrors = superQualifiers.mapNotNull { it.nullabilityForErrors }.toSet()
        .select(nullabilityForErrors, isCovariant)
    val newNullability = newNullabilityForErrors ?: superQualifiers.mapNotNull { it.nullability }.toSet()
        .select(nullability, isCovariant)
    val newMutability = superQualifiers.mapNotNull { it.mutability }.toSet()
        .select(MutabilityQualifier.MUTABLE, MutabilityQualifier.READ_ONLY, mutability, isCovariant)
    // Vararg value parameters effectively have non-nullable type in Kotlin
    // and having nullable types in Java may lead to impossibility of overriding them in Kotlin
    val realNullability = newNullability?.takeUnless {
        ignoreDeclarationNullabilityAnnotations || (isForVarargParameter && it == NullabilityQualifier.NULLABLE)
    }
    return JavaTypeQualifiers(
        realNullability, newMutability,
        realNullability == NullabilityQualifier.NOT_NULL && (definitelyNotNull || superQualifiers.any { it.definitelyNotNull }),
        realNullability != null && newNullabilityForErrors != newNullability
    )
}

fun TypeSystemCommonBackendContext.hasEnhancedNullability(type: KotlinTypeMarker): Boolean =
    type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy