[Commonizer] Use CirConstantValue class to represent constant values
This commit is contained in:
+1
-2
@@ -6,10 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.descriptors.commonizer.cir
|
package org.jetbrains.kotlin.descriptors.commonizer.cir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
|
|
||||||
interface CirAnnotation {
|
interface CirAnnotation {
|
||||||
val type: CirClassType
|
val type: CirClassType
|
||||||
val constantValueArguments: Map<Name, ConstantValue<*>>
|
val constantValueArguments: Map<Name, CirConstantValue<*>>
|
||||||
val annotationValueArguments: Map<Name, CirAnnotation>
|
val annotationValueArguments: Map<Name, CirAnnotation>
|
||||||
}
|
}
|
||||||
|
|||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.descriptors.commonizer.cir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
sealed class CirConstantValue<out T> {
|
||||||
|
abstract val value: T
|
||||||
|
|
||||||
|
data class StringValue(override val value: String) : CirConstantValue<String>()
|
||||||
|
data class CharValue(override val value: Char) : CirConstantValue<Char>()
|
||||||
|
|
||||||
|
data class ByteValue(override val value: Byte) : CirConstantValue<Byte>()
|
||||||
|
data class ShortValue(override val value: Short) : CirConstantValue<Short>()
|
||||||
|
data class IntValue(override val value: Int) : CirConstantValue<Int>()
|
||||||
|
data class LongValue(override val value: Long) : CirConstantValue<Long>()
|
||||||
|
|
||||||
|
data class UByteValue(override val value: Byte) : CirConstantValue<Byte>()
|
||||||
|
data class UShortValue(override val value: Short) : CirConstantValue<Short>()
|
||||||
|
data class UIntValue(override val value: Int) : CirConstantValue<Int>()
|
||||||
|
data class ULongValue(override val value: Long) : CirConstantValue<Long>()
|
||||||
|
|
||||||
|
data class FloatValue(override val value: Float) : CirConstantValue<Float>()
|
||||||
|
data class DoubleValue(override val value: Double) : CirConstantValue<Double>()
|
||||||
|
data class BooleanValue(override val value: Boolean) : CirConstantValue<Boolean>()
|
||||||
|
|
||||||
|
data class EnumValue(val enumClassId: ClassId, val enumEntryName: Name) : CirConstantValue<String>() {
|
||||||
|
override val value: String = "${enumClassId.asString()}.${enumEntryName.asString()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ArrayValue(override val value: List<CirConstantValue<*>>) : CirConstantValue<List<CirConstantValue<*>>>()
|
||||||
|
|
||||||
|
object NullValue : CirConstantValue<Void?>() {
|
||||||
|
override val value: Void? get() = null
|
||||||
|
override fun toString() = "NullValue(value=null)"
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-3
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer.cir
|
package org.jetbrains.kotlin.descriptors.commonizer.cir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
|
|
||||||
interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
|
interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
|
||||||
val isExternal: Boolean
|
val isExternal: Boolean
|
||||||
val isVar: Boolean
|
val isVar: Boolean
|
||||||
@@ -17,5 +15,5 @@ interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration {
|
|||||||
val setter: CirPropertySetter?
|
val setter: CirPropertySetter?
|
||||||
val backingFieldAnnotations: List<CirAnnotation>? // null assumes no backing field
|
val backingFieldAnnotations: List<CirAnnotation>? // null assumes no backing field
|
||||||
val delegateFieldAnnotations: List<CirAnnotation>? // null assumes no backing field
|
val delegateFieldAnnotations: List<CirAnnotation>? // null assumes no backing field
|
||||||
val compileTimeInitializer: ConstantValue<*>?
|
val compileTimeInitializer: CirConstantValue<*>?
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-11
@@ -9,9 +9,9 @@ import gnu.trove.THashMap
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirAnnotationImpl
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirAnnotationImpl
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.checkConstantSupportedInCommonization
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.compact
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.compact
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -28,21 +28,18 @@ object CirAnnotationFactory {
|
|||||||
if (allValueArguments.isEmpty())
|
if (allValueArguments.isEmpty())
|
||||||
return create(type = type, constantValueArguments = emptyMap(), annotationValueArguments = emptyMap())
|
return create(type = type, constantValueArguments = emptyMap(), annotationValueArguments = emptyMap())
|
||||||
|
|
||||||
val constantValueArguments: MutableMap<Name, ConstantValue<*>> = THashMap(allValueArguments.size)
|
val constantValueArguments: MutableMap<Name, CirConstantValue<*>> = THashMap(allValueArguments.size)
|
||||||
val annotationValueArguments: MutableMap<Name, CirAnnotation> = THashMap(allValueArguments.size)
|
val annotationValueArguments: MutableMap<Name, CirAnnotation> = THashMap(allValueArguments.size)
|
||||||
|
|
||||||
allValueArguments.forEach { (name, constantValue) ->
|
allValueArguments.forEach { (name, constantValue) ->
|
||||||
checkConstantSupportedInCommonization(
|
|
||||||
constantValue = constantValue,
|
|
||||||
constantName = name,
|
|
||||||
owner = source,
|
|
||||||
allowAnnotationValues = true
|
|
||||||
)
|
|
||||||
|
|
||||||
if (constantValue is AnnotationValue)
|
if (constantValue is AnnotationValue)
|
||||||
annotationValueArguments[name.intern()] = create(source = constantValue.value)
|
annotationValueArguments[name.intern()] = create(source = constantValue.value)
|
||||||
else
|
else
|
||||||
constantValueArguments[name.intern()] = constantValue
|
constantValueArguments[name.intern()] = CirConstantValueFactory.createSafely(
|
||||||
|
constantValue = constantValue,
|
||||||
|
constantName = name,
|
||||||
|
owner = source,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return create(
|
return create(
|
||||||
@@ -54,7 +51,7 @@ object CirAnnotationFactory {
|
|||||||
|
|
||||||
fun create(
|
fun create(
|
||||||
type: CirClassType,
|
type: CirClassType,
|
||||||
constantValueArguments: Map<Name, ConstantValue<*>>,
|
constantValueArguments: Map<Name, CirConstantValue<*>>,
|
||||||
annotationValueArguments: Map<Name, CirAnnotation>
|
annotationValueArguments: Map<Name, CirAnnotation>
|
||||||
): CirAnnotation {
|
): CirAnnotation {
|
||||||
return interner.intern(
|
return interner.intern(
|
||||||
|
|||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.descriptors.commonizer.cir.factory
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapIndexed
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.*
|
||||||
|
|
||||||
|
object CirConstantValueFactory {
|
||||||
|
fun createSafely(
|
||||||
|
constantValue: ConstantValue<*>,
|
||||||
|
constantName: Name? = null,
|
||||||
|
owner: Any,
|
||||||
|
): CirConstantValue<*> = createSafely(
|
||||||
|
constantValue = constantValue,
|
||||||
|
location = { "${owner::class.java}, $owner" + constantName?.asString()?.let { "[$it]" } }
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun createSafely(
|
||||||
|
constantValue: ConstantValue<*>,
|
||||||
|
location: () -> String
|
||||||
|
): CirConstantValue<*> = when (constantValue) {
|
||||||
|
is StringValue -> CirConstantValue.StringValue(constantValue.value)
|
||||||
|
is CharValue -> CirConstantValue.CharValue(constantValue.value)
|
||||||
|
|
||||||
|
is ByteValue -> CirConstantValue.ByteValue(constantValue.value)
|
||||||
|
is ShortValue -> CirConstantValue.ShortValue(constantValue.value)
|
||||||
|
is IntValue -> CirConstantValue.IntValue(constantValue.value)
|
||||||
|
is LongValue -> CirConstantValue.LongValue(constantValue.value)
|
||||||
|
|
||||||
|
is UByteValue -> CirConstantValue.UByteValue(constantValue.value)
|
||||||
|
is UShortValue -> CirConstantValue.UShortValue(constantValue.value)
|
||||||
|
is UIntValue -> CirConstantValue.UIntValue(constantValue.value)
|
||||||
|
is ULongValue -> CirConstantValue.ULongValue(constantValue.value)
|
||||||
|
|
||||||
|
is FloatValue -> CirConstantValue.FloatValue(constantValue.value)
|
||||||
|
is DoubleValue -> CirConstantValue.DoubleValue(constantValue.value)
|
||||||
|
is BooleanValue -> CirConstantValue.BooleanValue(constantValue.value)
|
||||||
|
|
||||||
|
is EnumValue -> CirConstantValue.EnumValue(constantValue.enumClassId.intern(), constantValue.enumEntryName.intern())
|
||||||
|
is NullValue -> CirConstantValue.NullValue
|
||||||
|
|
||||||
|
is ArrayValue -> CirConstantValue.ArrayValue(
|
||||||
|
constantValue.value.compactMapIndexed { index, innerConstantValue ->
|
||||||
|
createSafely(
|
||||||
|
constantValue = innerConstantValue,
|
||||||
|
location = { "${location()}[$index]" }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
else -> error("Unsupported const value type: ${constantValue::class.java}, $constantValue at ${location()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-9
@@ -11,20 +11,16 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirPropertyImpl
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirPropertyImpl
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.checkConstantSupportedInCommonization
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
|
|
||||||
object CirPropertyFactory {
|
object CirPropertyFactory {
|
||||||
fun create(source: PropertyDescriptor, containingClass: CirContainingClass?): CirProperty {
|
fun create(source: PropertyDescriptor, containingClass: CirContainingClass?): CirProperty {
|
||||||
val compileTimeInitializer: ConstantValue<*>? = source.compileTimeInitializer
|
val compileTimeInitializer = source.compileTimeInitializer?.let { constantValue ->
|
||||||
if (compileTimeInitializer != null) {
|
CirConstantValueFactory.createSafely(
|
||||||
checkConstantSupportedInCommonization(
|
constantValue = constantValue,
|
||||||
constantValue = compileTimeInitializer,
|
|
||||||
owner = source,
|
owner = source,
|
||||||
allowAnnotationValues = false
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +43,7 @@ object CirPropertyFactory {
|
|||||||
setter = source.setter?.let(CirPropertySetterFactory::create),
|
setter = source.setter?.let(CirPropertySetterFactory::create),
|
||||||
backingFieldAnnotations = source.backingField?.annotations?.compactMap(CirAnnotationFactory::create),
|
backingFieldAnnotations = source.backingField?.annotations?.compactMap(CirAnnotationFactory::create),
|
||||||
delegateFieldAnnotations = source.delegateField?.annotations?.compactMap(CirAnnotationFactory::create),
|
delegateFieldAnnotations = source.delegateField?.annotations?.compactMap(CirAnnotationFactory::create),
|
||||||
compileTimeInitializer = source.compileTimeInitializer
|
compileTimeInitializer = compileTimeInitializer
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +67,7 @@ object CirPropertyFactory {
|
|||||||
setter: CirPropertySetter?,
|
setter: CirPropertySetter?,
|
||||||
backingFieldAnnotations: List<CirAnnotation>?,
|
backingFieldAnnotations: List<CirAnnotation>?,
|
||||||
delegateFieldAnnotations: List<CirAnnotation>?,
|
delegateFieldAnnotations: List<CirAnnotation>?,
|
||||||
compileTimeInitializer: ConstantValue<*>?
|
compileTimeInitializer: CirConstantValue<*>?
|
||||||
): CirProperty {
|
): CirProperty {
|
||||||
return CirPropertyImpl(
|
return CirPropertyImpl(
|
||||||
annotations = annotations,
|
annotations = annotations,
|
||||||
|
|||||||
+2
-2
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
|
|
||||||
data class CirAnnotationImpl(
|
data class CirAnnotationImpl(
|
||||||
override val type: CirClassType,
|
override val type: CirClassType,
|
||||||
override val constantValueArguments: Map<Name, ConstantValue<*>>,
|
override val constantValueArguments: Map<Name, CirConstantValue<*>>,
|
||||||
override val annotationValueArguments: Map<Name, CirAnnotation>
|
override val annotationValueArguments: Map<Name, CirAnnotation>
|
||||||
) : CirAnnotation {
|
) : CirAnnotation {
|
||||||
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
|
// See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode
|
||||||
|
|||||||
+1
-2
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
|
|
||||||
data class CirPropertyImpl(
|
data class CirPropertyImpl(
|
||||||
override val annotations: List<CirAnnotation>,
|
override val annotations: List<CirAnnotation>,
|
||||||
@@ -31,7 +30,7 @@ data class CirPropertyImpl(
|
|||||||
override val setter: CirPropertySetter?,
|
override val setter: CirPropertySetter?,
|
||||||
override val backingFieldAnnotations: List<CirAnnotation>?,
|
override val backingFieldAnnotations: List<CirAnnotation>?,
|
||||||
override val delegateFieldAnnotations: List<CirAnnotation>?,
|
override val delegateFieldAnnotations: List<CirAnnotation>?,
|
||||||
override val compileTimeInitializer: ConstantValue<*>?
|
override val compileTimeInitializer: CirConstantValue<*>?
|
||||||
) : CirProperty {
|
) : CirProperty {
|
||||||
// const property in "common" fragment is already lifted up
|
// const property in "common" fragment is already lifted up
|
||||||
override val isLiftedUp get() = isConst
|
override val isLiftedUp get() = isConst
|
||||||
|
|||||||
+9
-18
@@ -7,21 +7,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE
|
import org.jetbrains.kotlin.descriptors.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.DEPRECATED_ANNOTATION_CLASS_ID
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapOf
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.intern
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
|
||||||
import kotlin.DeprecationLevel.WARNING
|
import kotlin.DeprecationLevel.WARNING
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +56,7 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
|
|||||||
val level: DeprecationLevel = level ?: failInEmptyState()
|
val level: DeprecationLevel = level ?: failInEmptyState()
|
||||||
val messageValue: StringValue = message.toDeprecationMessageValue()
|
val messageValue: StringValue = message.toDeprecationMessageValue()
|
||||||
|
|
||||||
val constantValueArguments: Map<Name, ConstantValue<*>> = if (level == WARNING) {
|
val constantValueArguments: Map<Name, CirConstantValue<*>> = if (level == WARNING) {
|
||||||
// don't populate with the default level value
|
// don't populate with the default level value
|
||||||
compactMapOf(PROPERTY_NAME_MESSAGE, messageValue)
|
compactMapOf(PROPERTY_NAME_MESSAGE, messageValue)
|
||||||
} else
|
} else
|
||||||
@@ -194,17 +188,17 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
|
|||||||
private fun String.toReplaceWithValue(imports: List<String>): CirAnnotation =
|
private fun String.toReplaceWithValue(imports: List<String>): CirAnnotation =
|
||||||
createReplaceWithAnnotation(this, imports)
|
createReplaceWithAnnotation(this, imports)
|
||||||
|
|
||||||
private inline fun Map<Name, ConstantValue<*>>.getString(name: Name): String? =
|
private inline fun Map<Name, CirConstantValue<*>>.getString(name: Name): String? =
|
||||||
(this[name] as? StringValue)?.value
|
(this[name] as? StringValue)?.value
|
||||||
|
|
||||||
private inline fun Map<Name, ConstantValue<*>>.getEnumEntryName(name: Name): String? =
|
private inline fun Map<Name, CirConstantValue<*>>.getEnumEntryName(name: Name): String? =
|
||||||
(this[name] as? EnumValue)?.enumEntryName?.asString()
|
(this[name] as? EnumValue)?.enumEntryName?.asString()
|
||||||
|
|
||||||
private inline fun Map<Name, CirAnnotation>.getAnnotation(name: Name): CirAnnotation? =
|
private inline fun Map<Name, CirAnnotation>.getAnnotation(name: Name): CirAnnotation? =
|
||||||
this[name]
|
this[name]
|
||||||
|
|
||||||
private inline fun Map<Name, ConstantValue<*>>.getStringArray(name: Name): List<String>? {
|
private inline fun Map<Name, CirConstantValue<*>>.getStringArray(name: Name): List<String>? {
|
||||||
val elements: List<ConstantValue<*>> = (this[name] as? ArrayValue)?.value ?: return null
|
val elements: List<CirConstantValue<*>> = (this[name] as? ArrayValue)?.value ?: return null
|
||||||
if (elements.isEmpty()) return emptyList()
|
if (elements.isEmpty()) return emptyList()
|
||||||
|
|
||||||
val result = ArrayList<String>(elements.size)
|
val result = ArrayList<String>(elements.size)
|
||||||
@@ -223,10 +217,7 @@ private class DeprecatedAnnotationCommonizer : Commonizer<CirAnnotation, CirAnno
|
|||||||
type = REPLACE_WITH_ANNOTATION_TYPE,
|
type = REPLACE_WITH_ANNOTATION_TYPE,
|
||||||
constantValueArguments = compactMapOf(
|
constantValueArguments = compactMapOf(
|
||||||
PROPERTY_NAME_EXPRESSION, StringValue(expression),
|
PROPERTY_NAME_EXPRESSION, StringValue(expression),
|
||||||
PROPERTY_NAME_IMPORTS, ArrayValue(
|
PROPERTY_NAME_IMPORTS, ArrayValue(imports.compactMap(::StringValue))
|
||||||
value = imports.compactMap { StringValue(it) },
|
|
||||||
computeType = { it.builtIns.getArrayElementType(it.builtIns.stringType) }
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
annotationValueArguments = emptyMap()
|
annotationValueArguments = emptyMap()
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors.commonizer.core
|
package org.jetbrains.kotlin.descriptors.commonizer.core
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyGetterFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyGetterFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.core.PropertyCommonizer.ConstCommonizationState.*
|
import org.jetbrains.kotlin.descriptors.commonizer.core.PropertyCommonizer.ConstCommonizationState.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
|
|
||||||
class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer<CirProperty>(classifiers) {
|
class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer<CirProperty>(classifiers) {
|
||||||
private val setter = PropertySetterCommonizer()
|
private val setter = PropertySetterCommonizer()
|
||||||
@@ -109,7 +109,7 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP
|
|||||||
val properties: MutableList<CirProperty> = mutableListOf()
|
val properties: MutableList<CirProperty> = mutableListOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConstSameValue(val compileTimeInitializer: ConstantValue<*>) : Const()
|
class ConstSameValue(val compileTimeInitializer: CirConstantValue<*>) : Const()
|
||||||
class ConstMultipleValues(previous: ConstSameValue) : Const() {
|
class ConstMultipleValues(previous: ConstSameValue) : Const() {
|
||||||
init {
|
init {
|
||||||
properties += previous.properties
|
properties += previous.properties
|
||||||
|
|||||||
+23
-20
@@ -15,10 +15,10 @@ import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType
|
|||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.metadata.TypeAliasExpansion.*
|
import org.jetbrains.kotlin.descriptors.commonizer.metadata.TypeAliasExpansion.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.DEFAULT_SETTER_VALUE_NAME
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.DEFAULT_SETTER_VALUE_NAME
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.strip
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.strip
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
internal fun CirModule.buildModule(
|
internal fun CirModule.buildModule(
|
||||||
@@ -156,7 +156,7 @@ internal fun CirProperty.buildProperty(
|
|||||||
annotations.mapTo(property.annotations) { it.buildAnnotation() }
|
annotations.mapTo(property.annotations) { it.buildAnnotation() }
|
||||||
getter?.annotations?.mapTo(property.getterAnnotations) { it.buildAnnotation() }
|
getter?.annotations?.mapTo(property.getterAnnotations) { it.buildAnnotation() }
|
||||||
setter?.annotations?.mapTo(property.setterAnnotations) { it.buildAnnotation() }
|
setter?.annotations?.mapTo(property.setterAnnotations) { it.buildAnnotation() }
|
||||||
property.compileTimeValue = compileTimeInitializer?.takeIf { it !is NullValue }?.buildAnnotationArgument()
|
property.compileTimeValue = compileTimeInitializer?.takeIf { it !is CirConstantValue.NullValue }?.buildAnnotationArgument()
|
||||||
typeParameters.buildTypeParameters(context, output = property.typeParameters)
|
typeParameters.buildTypeParameters(context, output = property.typeParameters)
|
||||||
extensionReceiver?.let { receiver ->
|
extensionReceiver?.let { receiver ->
|
||||||
// TODO nowhere to write receiver annotations, see KT-42490
|
// TODO nowhere to write receiver annotations, see KT-42490
|
||||||
@@ -195,8 +195,9 @@ internal fun CirFunction.buildFunction(
|
|||||||
private fun CirAnnotation.buildAnnotation(): KmAnnotation {
|
private fun CirAnnotation.buildAnnotation(): KmAnnotation {
|
||||||
val arguments = LinkedHashMap<String, KmAnnotationArgument<*>>(constantValueArguments.size + annotationValueArguments.size, 1F)
|
val arguments = LinkedHashMap<String, KmAnnotationArgument<*>>(constantValueArguments.size + annotationValueArguments.size, 1F)
|
||||||
|
|
||||||
constantValueArguments.forEach { (name: Name, value: ConstantValue<*>) ->
|
constantValueArguments.forEach { (name: Name, value: CirConstantValue<*>) ->
|
||||||
arguments[name.asString()] = value.buildAnnotationArgument()
|
arguments[name.asString()] = value.buildAnnotationArgument()
|
||||||
|
?: error("Unexpected <null> constant value inside of $this")
|
||||||
}
|
}
|
||||||
|
|
||||||
annotationValueArguments.forEach { (name: Name, nested: CirAnnotation) ->
|
annotationValueArguments.forEach { (name: Name, nested: CirAnnotation) ->
|
||||||
@@ -209,28 +210,30 @@ private fun CirAnnotation.buildAnnotation(): KmAnnotation {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConstantValue<*>.buildAnnotationArgument(): KmAnnotationArgument<*> = when (this) {
|
private fun CirConstantValue<*>.buildAnnotationArgument(): KmAnnotationArgument<*>? = when (this) {
|
||||||
is StringValue -> KmAnnotationArgument.StringValue(value)
|
is CirConstantValue.StringValue -> KmAnnotationArgument.StringValue(value)
|
||||||
is CharValue -> KmAnnotationArgument.CharValue(value)
|
is CirConstantValue.CharValue -> KmAnnotationArgument.CharValue(value)
|
||||||
|
|
||||||
is ByteValue -> KmAnnotationArgument.ByteValue(value)
|
is CirConstantValue.ByteValue -> KmAnnotationArgument.ByteValue(value)
|
||||||
is ShortValue -> KmAnnotationArgument.ShortValue(value)
|
is CirConstantValue.ShortValue -> KmAnnotationArgument.ShortValue(value)
|
||||||
is IntValue -> KmAnnotationArgument.IntValue(value)
|
is CirConstantValue.IntValue -> KmAnnotationArgument.IntValue(value)
|
||||||
is LongValue -> KmAnnotationArgument.LongValue(value)
|
is CirConstantValue.LongValue -> KmAnnotationArgument.LongValue(value)
|
||||||
|
|
||||||
is UByteValue -> KmAnnotationArgument.UByteValue(value)
|
is CirConstantValue.UByteValue -> KmAnnotationArgument.UByteValue(value)
|
||||||
is UShortValue -> KmAnnotationArgument.UShortValue(value)
|
is CirConstantValue.UShortValue -> KmAnnotationArgument.UShortValue(value)
|
||||||
is UIntValue -> KmAnnotationArgument.UIntValue(value)
|
is CirConstantValue.UIntValue -> KmAnnotationArgument.UIntValue(value)
|
||||||
is ULongValue -> KmAnnotationArgument.ULongValue(value)
|
is CirConstantValue.ULongValue -> KmAnnotationArgument.ULongValue(value)
|
||||||
|
|
||||||
is FloatValue -> KmAnnotationArgument.FloatValue(value)
|
is CirConstantValue.FloatValue -> KmAnnotationArgument.FloatValue(value)
|
||||||
is DoubleValue -> KmAnnotationArgument.DoubleValue(value)
|
is CirConstantValue.DoubleValue -> KmAnnotationArgument.DoubleValue(value)
|
||||||
is BooleanValue -> KmAnnotationArgument.BooleanValue(value)
|
is CirConstantValue.BooleanValue -> KmAnnotationArgument.BooleanValue(value)
|
||||||
|
|
||||||
is EnumValue -> KmAnnotationArgument.EnumValue(enumClassId.asString(), enumEntryName.asString())
|
is CirConstantValue.EnumValue -> KmAnnotationArgument.EnumValue(enumClassId.asString(), enumEntryName.asString())
|
||||||
is ArrayValue -> KmAnnotationArgument.ArrayValue(value.map { it.buildAnnotationArgument() })
|
is CirConstantValue.NullValue -> null
|
||||||
|
|
||||||
else -> error("Unsupported annotation argument type: ${this::class.java}, $this")
|
is CirConstantValue.ArrayValue -> KmAnnotationArgument.ArrayValue(value.compactMap { element ->
|
||||||
|
element.buildAnnotationArgument() ?: error("Unexpected <null> constant value inside of $this")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CirValueParameter.buildValueParameter(
|
private fun CirValueParameter.buildValueParameter(
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.resolve.constants.NullValue
|
|
||||||
|
|
||||||
internal const val NO_FLAGS: Flags = 0
|
internal const val NO_FLAGS: Flags = 0
|
||||||
|
|
||||||
@@ -172,7 +171,7 @@ private inline val CirProperty.modifiersFlags: Flags
|
|||||||
get() = flagsOfNotNull(
|
get() = flagsOfNotNull(
|
||||||
Flag.Property.IS_VAR.takeIf { isVar },
|
Flag.Property.IS_VAR.takeIf { isVar },
|
||||||
Flag.Property.IS_CONST.takeIf { isConst },
|
Flag.Property.IS_CONST.takeIf { isConst },
|
||||||
Flag.Property.HAS_CONSTANT.takeIf { compileTimeInitializer.takeIf { it !is NullValue } != null },
|
Flag.Property.HAS_CONSTANT.takeIf { compileTimeInitializer.takeIf { it !is CirConstantValue.NullValue } != null },
|
||||||
Flag.Property.IS_LATEINIT.takeIf { isLateInit },
|
Flag.Property.IS_LATEINIT.takeIf { isLateInit },
|
||||||
Flag.Property.IS_EXTERNAL.takeIf { isExternal }
|
Flag.Property.IS_EXTERNAL.takeIf { isExternal }
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.descriptors.commonizer.utils
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
|
||||||
|
|
||||||
internal fun checkConstantSupportedInCommonization(
|
|
||||||
constantValue: ConstantValue<*>,
|
|
||||||
constantName: Name? = null,
|
|
||||||
owner: Any,
|
|
||||||
allowAnnotationValues: Boolean,
|
|
||||||
onError: (String) -> Nothing = ::error
|
|
||||||
) {
|
|
||||||
checkConstantSupportedInCommonization(
|
|
||||||
constantValue = constantValue,
|
|
||||||
location = { "${owner::class.java}, $owner" + constantName?.asString()?.let { "[$it]" } },
|
|
||||||
allowAnnotationValues = allowAnnotationValues,
|
|
||||||
onError = onError
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkConstantSupportedInCommonization(
|
|
||||||
constantValue: ConstantValue<*>,
|
|
||||||
location: () -> String,
|
|
||||||
allowAnnotationValues: Boolean,
|
|
||||||
onError: (String) -> Nothing
|
|
||||||
) {
|
|
||||||
@Suppress("TrailingComma")
|
|
||||||
when (constantValue) {
|
|
||||||
is StringValue,
|
|
||||||
is IntegerValueConstant<*>,
|
|
||||||
is UnsignedValueConstant<*>,
|
|
||||||
is BooleanValue,
|
|
||||||
is NullValue,
|
|
||||||
is DoubleValue,
|
|
||||||
is FloatValue,
|
|
||||||
is EnumValue -> {
|
|
||||||
return // OK
|
|
||||||
}
|
|
||||||
is AnnotationValue -> {
|
|
||||||
if (allowAnnotationValues) {
|
|
||||||
return // OK
|
|
||||||
} // else fail (see below)
|
|
||||||
}
|
|
||||||
is ArrayValue -> {
|
|
||||||
constantValue.value.forEachIndexed { index, innerConstantValue ->
|
|
||||||
checkConstantSupportedInCommonization(
|
|
||||||
constantValue = innerConstantValue,
|
|
||||||
location = { "${location()}[$index]" },
|
|
||||||
allowAnnotationValues = allowAnnotationValues,
|
|
||||||
onError = onError
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return // OK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onError("Unsupported const value type: ${constantValue::class.java}, $constantValue at ${location()}")
|
|
||||||
}
|
|
||||||
|
|
||||||
+1
-3
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
|
|
||||||
internal fun FqName.intern(): FqName = fqNameInterner.intern(this)
|
internal fun FqName.intern(): FqName = fqNameInterner.intern(this)
|
||||||
internal fun Name.intern(): Name = nameInterner.intern(this)
|
internal fun Name.intern(): Name = nameInterner.intern(this)
|
||||||
|
internal fun ClassId.intern(): ClassId = classIdInterner.intern(this)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
internal inline fun internedClassId(topLevelFqName: FqName): ClassId {
|
internal inline fun internedClassId(topLevelFqName: FqName): ClassId {
|
||||||
@@ -29,9 +30,6 @@ internal fun internedClassId(ownerClassId: ClassId, nestedClassName: Name): Clas
|
|||||||
return ClassId(ownerClassId.packageFqName, relativeClassName, ownerClassId.isLocal).intern()
|
return ClassId(ownerClassId.packageFqName, relativeClassName, ownerClassId.isLocal).intern()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
private inline fun ClassId.intern(): ClassId = classIdInterner.intern(this)
|
|
||||||
|
|
||||||
private val fqNameInterner = Interner<FqName>()
|
private val fqNameInterner = Interner<FqName>()
|
||||||
private val nameInterner = Interner<Name>()
|
private val nameInterner = Interner<Name>()
|
||||||
private val classIdInterner = Interner<ClassId>()
|
private val classIdInterner = Interner<ClassId>()
|
||||||
|
|||||||
+5
-9
@@ -7,16 +7,14 @@ package org.jetbrains.kotlin.descriptors.commonizer.core
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue
|
||||||
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
|
import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.DeprecationLevel.*
|
import kotlin.DeprecationLevel.*
|
||||||
|
|
||||||
@@ -287,7 +285,7 @@ class AnnotationsCommonizerTest : AbstractCommonizerTest<List<CirAnnotation>, Li
|
|||||||
|
|
||||||
private fun mockAnnotation(
|
private fun mockAnnotation(
|
||||||
fqName: String,
|
fqName: String,
|
||||||
constantValueArguments: Map<Name, ConstantValue<*>> = emptyMap(),
|
constantValueArguments: Map<Name, CirConstantValue<*>> = emptyMap(),
|
||||||
annotationValueArguments: Map<Name, CirAnnotation> = emptyMap()
|
annotationValueArguments: Map<Name, CirAnnotation> = emptyMap()
|
||||||
): CirAnnotation = CirAnnotationFactory.create(
|
): CirAnnotation = CirAnnotationFactory.create(
|
||||||
type = CirTypeFactory.create(mockClassType(fqName)) as CirClassType,
|
type = CirTypeFactory.create(mockClassType(fqName)) as CirClassType,
|
||||||
@@ -306,9 +304,7 @@ private fun mockDeprecated(
|
|||||||
fqName = "kotlin.ReplaceWith",
|
fqName = "kotlin.ReplaceWith",
|
||||||
constantValueArguments = mapOf(
|
constantValueArguments = mapOf(
|
||||||
Name.identifier("expression") to StringValue(replaceWithExpression),
|
Name.identifier("expression") to StringValue(replaceWithExpression),
|
||||||
Name.identifier("imports") to ArrayValue(replaceWithImports.map(::StringValue)) {
|
Name.identifier("imports") to ArrayValue(replaceWithImports.map(::StringValue))
|
||||||
it.builtIns.getArrayElementType(it.builtIns.stringType)
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
annotationValueArguments = emptyMap()
|
annotationValueArguments = emptyMap()
|
||||||
)
|
)
|
||||||
@@ -316,7 +312,7 @@ private fun mockDeprecated(
|
|||||||
|
|
||||||
return mockAnnotation(
|
return mockAnnotation(
|
||||||
fqName = "kotlin.Deprecated",
|
fqName = "kotlin.Deprecated",
|
||||||
constantValueArguments = HashMap<Name, ConstantValue<*>>().apply {
|
constantValueArguments = HashMap<Name, CirConstantValue<*>>().apply {
|
||||||
this[Name.identifier("message")] = StringValue(message)
|
this[Name.identifier("message")] = StringValue(message)
|
||||||
|
|
||||||
if (level != WARNING)
|
if (level != WARNING)
|
||||||
|
|||||||
Reference in New Issue
Block a user