org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.lightTree.fir.modifier
import com.intellij.lang.LighterASTNode
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.types.Variance
open class Modifier(var modifiers: Long = ModifierFlag.NONE.value) {
val annotations: MutableList = mutableListOf()
fun addModifier(modifier: LighterASTNode, isInClass: Boolean = false) {
when (val tokenType = modifier.tokenType) {
KtTokens.CONST_KEYWORD -> {
// Specific case because CONST may exist both on parameter and property
setFlag(ModifierFlag.PROPERTY_CONST)
setFlag(ModifierFlag.PARAMETER_CONST)
}
KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD -> {
setFlag(if (isInClass) ModifierFlag.CLASS_INLINE else ModifierFlag.FUNCTION_INLINE)
}
else -> {
setFlag(ModifierFlag.ElementTypeToModifierFlagMap[tokenType])
}
}
}
fun isEnum(): Boolean = hasFlag(ModifierFlag.CLASS_ENUM)
fun isAnnotation(): Boolean = hasFlag(ModifierFlag.CLASS_ANNOTATION)
fun isDataClass(): Boolean = hasFlag(ModifierFlag.CLASS_DATA)
fun isInlineClass(): Boolean = hasFlag(ModifierFlag.CLASS_INLINE)
fun isInner(): Boolean = hasFlag(ModifierFlag.CLASS_INNER)
fun isCompanion(): Boolean = hasFlag(ModifierFlag.CLASS_COMPANION)
fun isFunctionalInterface(): Boolean = hasFlag(ModifierFlag.CLASS_FUN)
fun hasOverride(): Boolean = hasFlag(ModifierFlag.MEMBER_OVERRIDE)
fun hasLateinit(): Boolean = hasFlag(ModifierFlag.MEMBER_LATEINIT)
fun getVisibility(): Visibility {
return when {
hasFlag(ModifierFlag.VISIBILITY_PRIVATE) -> Visibilities.Private
hasFlag(ModifierFlag.VISIBILITY_PUBLIC) -> Visibilities.Public
hasFlag(ModifierFlag.VISIBILITY_PROTECTED) -> Visibilities.Protected
hasFlag(ModifierFlag.VISIBILITY_INTERNAL) -> Visibilities.Internal
else -> Visibilities.Unknown
}
}
fun hasTailrec(): Boolean = hasFlag(ModifierFlag.FUNCTION_TAILREC)
fun hasOperator(): Boolean = hasFlag(ModifierFlag.FUNCTION_OPERATOR)
fun hasInfix(): Boolean = hasFlag(ModifierFlag.FUNCTION_INFIX)
fun hasInline(): Boolean = hasFlag(ModifierFlag.FUNCTION_INLINE)
fun hasExternal(): Boolean = hasFlag(ModifierFlag.FUNCTION_EXTERNAL)
fun hasSuspend(): Boolean = hasFlag(ModifierFlag.FUNCTION_SUSPEND)
fun isConst(): Boolean = hasFlag(ModifierFlag.PROPERTY_CONST)
fun hasModality(modality: Modality): Boolean {
return when {
modality == Modality.FINAL && hasFlag(ModifierFlag.INHERITANCE_FINAL) -> true
modality == Modality.SEALED && hasFlag(ModifierFlag.INHERITANCE_SEALED) -> true
modality == Modality.ABSTRACT && hasFlag(ModifierFlag.INHERITANCE_ABSTRACT) -> true
modality == Modality.OPEN && hasFlag(ModifierFlag.INHERITANCE_OPEN) -> true
else -> false
}
}
fun getModality(isClassOrObject: Boolean): Modality? {
return when {
hasFlag(ModifierFlag.INHERITANCE_FINAL) -> Modality.FINAL
hasFlag(ModifierFlag.INHERITANCE_SEALED) -> if (isClassOrObject) Modality.SEALED else null
hasFlag(ModifierFlag.INHERITANCE_ABSTRACT) -> Modality.ABSTRACT
hasFlag(ModifierFlag.INHERITANCE_OPEN) -> Modality.OPEN
else -> null
}
}
fun getVariance(): Variance {
return when {
hasFlag(ModifierFlag.VARIANCE_IN) -> Variance.IN_VARIANCE
hasFlag(ModifierFlag.VARIANCE_OUT) -> Variance.OUT_VARIANCE
else -> Variance.INVARIANT
}
}
fun hasVararg(): Boolean = hasFlag(ModifierFlag.PARAMETER_VARARG)
fun hasNoinline(): Boolean = hasFlag(ModifierFlag.PARAMETER_NOINLINE)
fun hasCrossinline(): Boolean = hasFlag(ModifierFlag.PARAMETER_CROSSINLINE)
fun hasExpect(): Boolean = hasFlag(ModifierFlag.PLATFORM_EXPECT) || hasFlag(ModifierFlag.PLATFORM_HEADER)
fun hasActual(): Boolean = hasFlag(ModifierFlag.PLATFORM_ACTUAL) || hasFlag(ModifierFlag.PLATFORM_IMPL)
fun hasConst(): Boolean = hasFlag(ModifierFlag.PARAMETER_CONST)
protected fun hasFlag(flag: ModifierFlag) = (modifiers and flag.value) == flag.value
protected fun setFlag(flag: ModifierFlag?) {
if (flag != null) {
modifiers = modifiers or flag.value
}
}
override fun toString(): String {
val result = StringBuilder()
var firstAppend = true
for (value in ModifierFlag.Values) {
if (hasFlag(value) && value != ModifierFlag.NONE) {
if (firstAppend) {
firstAppend = false
} else {
result.append(" ")
}
result.append(value.name)
}
}
return result.toString()
}
}