[IR] [Refactoring] Add toString and String::plus to IrBuiltins
Also use `OperatorNameConventions` constants instead of magic strings
This commit is contained in:
@@ -454,15 +454,31 @@ class IrBuiltInsOverFir(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val extensionToString: IrSimpleFunctionSymbol by lazy {
|
override val extensionToString: IrSimpleFunctionSymbol by lazy {
|
||||||
findFunctions(kotlinPackage, Name.identifier("toString")).first { function ->
|
findFunctions(kotlinPackage, OperatorNameConventions.TO_STRING).single { function ->
|
||||||
function.owner.extensionReceiverParameter?.let { receiver -> receiver.type == anyNType } ?: false
|
function.owner.extensionReceiverParameter?.let { receiver -> receiver.type == anyNType } ?: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val stringPlus: IrSimpleFunctionSymbol
|
override val memberToString: IrSimpleFunctionSymbol by lazy {
|
||||||
get() = intClass.functions.single {
|
findBuiltInClassMemberFunctions(anyClass, OperatorNameConventions.TO_STRING).single { function ->
|
||||||
it.owner.name == OperatorNameConventions.PLUS && it.owner.valueParameters[0].type == stringType
|
function.owner.valueParameters.isEmpty()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val extensionStringPlus: IrSimpleFunctionSymbol by lazy {
|
||||||
|
findFunctions(kotlinPackage, OperatorNameConventions.PLUS).single { function ->
|
||||||
|
val isStringExtension =
|
||||||
|
function.owner.extensionReceiverParameter?.let { receiver -> receiver.type == stringType.withHasQuestionMark(true) }
|
||||||
|
?: false
|
||||||
|
isStringExtension && function.owner.valueParameters.size == 1 && function.owner.valueParameters[0].type == anyNType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val memberStringPlus: IrSimpleFunctionSymbol by lazy {
|
||||||
|
findBuiltInClassMemberFunctions(stringClass, OperatorNameConventions.PLUS).single { function ->
|
||||||
|
function.owner.valueParameters.size == 1 && function.owner.valueParameters[0].type == anyNType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class KotlinPackageFuns(
|
private class KotlinPackageFuns(
|
||||||
val arrayOf: IrSimpleFunctionSymbol,
|
val arrayOf: IrSimpleFunctionSymbol,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType
|
|||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
class Fir2IrLazyClass(
|
class Fir2IrLazyClass(
|
||||||
components: Fir2IrComponents,
|
components: Fir2IrComponents,
|
||||||
@@ -214,9 +215,9 @@ class Fir2IrLazyClass(
|
|||||||
private fun FirNamedFunctionSymbol.isAbstractMethodOfAny(): Boolean {
|
private fun FirNamedFunctionSymbol.isAbstractMethodOfAny(): Boolean {
|
||||||
val fir = fir
|
val fir = fir
|
||||||
if (fir.modality != Modality.ABSTRACT) return false
|
if (fir.modality != Modality.ABSTRACT) return false
|
||||||
return when (fir.name.asString()) {
|
return when (fir.name) {
|
||||||
"equals" -> fir.valueParameters.singleOrNull()?.returnTypeRef?.isNullableAny == true
|
OperatorNameConventions.EQUALS -> fir.valueParameters.singleOrNull()?.returnTypeRef?.isNullableAny == true
|
||||||
"hashCode", "toString" -> fir.valueParameters.isEmpty()
|
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> fir.valueParameters.isEmpty()
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
|||||||
|
|
||||||
object FunctionsFromAny {
|
object FunctionsFromAny {
|
||||||
val EQUALS_METHOD_NAME = OperatorNameConventions.EQUALS
|
val EQUALS_METHOD_NAME = OperatorNameConventions.EQUALS
|
||||||
val HASH_CODE_METHOD_NAME = Name.identifier("hashCode")
|
val HASH_CODE_METHOD_NAME = OperatorNameConventions.HASH_CODE
|
||||||
val TO_STRING_METHOD_NAME = Name.identifier("toString")
|
val TO_STRING_METHOD_NAME = OperatorNameConventions.TO_STRING
|
||||||
|
|
||||||
fun addFunctionFromAnyIfNeeded(
|
fun addFunctionFromAnyIfNeeded(
|
||||||
thisDescriptor: ClassDescriptor,
|
thisDescriptor: ClassDescriptor,
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.types.defaultType
|
|
||||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
@@ -187,7 +185,20 @@ open class BuiltinSymbolsBase(val irBuiltIns: IrBuiltIns, private val symbolTabl
|
|||||||
fun kmutableproperty2(): IrClassSymbol = irBuiltIns.kMutableProperty2Class
|
fun kmutableproperty2(): IrClassSymbol = irBuiltIns.kMutableProperty2Class
|
||||||
|
|
||||||
val extensionToString: IrSimpleFunctionSymbol get() = irBuiltIns.extensionToString
|
val extensionToString: IrSimpleFunctionSymbol get() = irBuiltIns.extensionToString
|
||||||
val stringPlus: IrSimpleFunctionSymbol get() = irBuiltIns.stringPlus
|
val memberToString: IrSimpleFunctionSymbol get() = irBuiltIns.memberToString
|
||||||
|
val extensionStringPlus: IrSimpleFunctionSymbol get() = irBuiltIns.extensionStringPlus
|
||||||
|
val memberStringPlus: IrSimpleFunctionSymbol get() = irBuiltIns.memberStringPlus
|
||||||
|
|
||||||
|
fun isStringPlus(functionSymbol: IrFunctionSymbol): Boolean {
|
||||||
|
val plusSymbol = if (functionSymbol.owner.dispatchReceiverParameter?.type?.isString() == true)
|
||||||
|
memberStringPlus
|
||||||
|
else if (functionSymbol.owner.extensionReceiverParameter?.type?.isNullableString() == true)
|
||||||
|
extensionStringPlus
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
|
||||||
|
return functionSymbol == plusSymbol
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some symbols below are used in kotlin-native, so they can't be private
|
// Some symbols below are used in kotlin-native, so they can't be private
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.ir.util.*
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
|
||||||
fun ir2string(ir: IrElement?): String = ir?.render() ?: ""
|
fun ir2string(ir: IrElement?): String = ir?.render() ?: ""
|
||||||
@@ -399,9 +400,9 @@ fun isElseBranch(branch: IrBranch) = branch is IrElseBranch || ((branch.conditio
|
|||||||
|
|
||||||
fun IrFunction.isMethodOfAny(): Boolean =
|
fun IrFunction.isMethodOfAny(): Boolean =
|
||||||
extensionReceiverParameter == null && dispatchReceiverParameter != null &&
|
extensionReceiverParameter == null && dispatchReceiverParameter != null &&
|
||||||
when (name.asString()) {
|
when (name) {
|
||||||
"hashCode", "toString" -> valueParameters.isEmpty()
|
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> valueParameters.isEmpty()
|
||||||
"equals" -> valueParameters.singleOrNull()?.type?.isNullableAny() == true
|
OperatorNameConventions.EQUALS -> valueParameters.singleOrNull()?.type?.isNullableAny() == true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
val flattenStringConcatenationPhase = makeIrFilePhase(
|
val flattenStringConcatenationPhase = makeIrFilePhase(
|
||||||
::FlattenStringConcatenationLowering,
|
::FlattenStringConcatenationLowering,
|
||||||
@@ -86,14 +87,14 @@ class FlattenStringConcatenationLowering(val context: CommonBackendContext) : Fi
|
|||||||
&& receiver.type.isStringClassType()
|
&& receiver.type.isStringClassType()
|
||||||
&& function.returnType.isStringClassType()
|
&& function.returnType.isStringClassType()
|
||||||
&& function.valueParameters.size == 1
|
&& function.valueParameters.size == 1
|
||||||
&& function.name.asString() == "plus"
|
&& function.name == OperatorNameConventions.PLUS
|
||||||
&& function.fqNameWhenAvailable?.parent() in PARENT_NAMES
|
&& function.fqNameWhenAvailable?.parent() in PARENT_NAMES
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return true if the function is Any.toString or an override of Any.toString */
|
/** @return true if the function is Any.toString or an override of Any.toString */
|
||||||
val IrSimpleFunction.isToString: Boolean
|
val IrSimpleFunction.isToString: Boolean
|
||||||
get() {
|
get() {
|
||||||
if (name.asString() != "toString" || valueParameters.size != 0 || !returnType.isString())
|
if (name != OperatorNameConventions.TO_STRING || valueParameters.isNotEmpty() || !returnType.isString())
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return (dispatchReceiverParameter != null && extensionReceiverParameter == null
|
return (dispatchReceiverParameter != null && extensionReceiverParameter == null
|
||||||
@@ -103,7 +104,7 @@ class FlattenStringConcatenationLowering(val context: CommonBackendContext) : Fi
|
|||||||
/** @return true if the function is Any?.toString */
|
/** @return true if the function is Any?.toString */
|
||||||
private val IrSimpleFunction.isNullableToString: Boolean
|
private val IrSimpleFunction.isNullableToString: Boolean
|
||||||
get() {
|
get() {
|
||||||
if (name.asString() != "toString" || valueParameters.size != 0 || !returnType.isString())
|
if (name != OperatorNameConventions.TO_STRING || valueParameters.isNotEmpty() || !returnType.isString())
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return dispatchReceiverParameter == null
|
return dispatchReceiverParameter == null
|
||||||
|
|||||||
+4
-11
@@ -55,10 +55,6 @@ class StringConcatenationLowering(context: CommonBackendContext) : FileLoweringP
|
|||||||
it.valueParameters.isEmpty()
|
it.valueParameters.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val toStringFunction = stringBuilder.functions.single {
|
|
||||||
it.valueParameters.isEmpty() && it.name == OperatorNameConventions.TO_STRING
|
|
||||||
}
|
|
||||||
|
|
||||||
private val defaultAppendFunction = stringBuilder.functions.single {
|
private val defaultAppendFunction = stringBuilder.functions.single {
|
||||||
it.name == nameAppend &&
|
it.name == nameAppend &&
|
||||||
it.valueParameters.size == 1 &&
|
it.valueParameters.size == 1 &&
|
||||||
@@ -90,22 +86,19 @@ class StringConcatenationLowering(context: CommonBackendContext) : FileLoweringP
|
|||||||
builder.irCall(symbols.extensionToString).apply {
|
builder.irCall(symbols.extensionToString).apply {
|
||||||
extensionReceiver = argument
|
extensionReceiver = argument
|
||||||
}
|
}
|
||||||
else builder.irCall(
|
else builder.irCall(symbols.memberToString).apply {
|
||||||
irBuiltIns.anyClass.functions
|
|
||||||
.single { it.owner.name == OperatorNameConventions.TO_STRING }).apply {
|
|
||||||
dispatchReceiver = argument
|
dispatchReceiver = argument
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.size == 2 && arguments[0].type.isStringClassType() ->
|
arguments.size == 2 && arguments[0].type.isStringClassType() ->
|
||||||
if (arguments[0].type.isNullable())
|
if (arguments[0].type.isNullable())
|
||||||
builder.irCall(symbols.stringPlus).apply {
|
builder.irCall(symbols.extensionStringPlus).apply {
|
||||||
extensionReceiver = arguments[0]
|
extensionReceiver = arguments[0]
|
||||||
putValueArgument(0, arguments[1])
|
putValueArgument(0, arguments[1])
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
builder.irCall(symbols.string.functions
|
builder.irCall(symbols.memberStringPlus).apply {
|
||||||
.single { it.owner.name == OperatorNameConventions.PLUS }).apply {
|
|
||||||
dispatchReceiver = arguments[0]
|
dispatchReceiver = arguments[0]
|
||||||
putValueArgument(0, arguments[1])
|
putValueArgument(0, arguments[1])
|
||||||
}
|
}
|
||||||
@@ -119,7 +112,7 @@ class StringConcatenationLowering(context: CommonBackendContext) : FileLoweringP
|
|||||||
putValueArgument(0, arg)
|
putValueArgument(0, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+irCall(toStringFunction).apply {
|
+irCall(symbols.memberToString).apply {
|
||||||
dispatchReceiver = irGet(stringBuilderImpl)
|
dispatchReceiver = irGet(stringBuilderImpl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -142,7 +140,10 @@ abstract class IrBuiltIns {
|
|||||||
abstract val intXorSymbol: IrSimpleFunctionSymbol
|
abstract val intXorSymbol: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
abstract val extensionToString: IrSimpleFunctionSymbol
|
abstract val extensionToString: IrSimpleFunctionSymbol
|
||||||
abstract val stringPlus: IrSimpleFunctionSymbol
|
abstract val memberToString: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
|
abstract val extensionStringPlus: IrSimpleFunctionSymbol
|
||||||
|
abstract val memberStringPlus: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
abstract val arrayOf: IrSimpleFunctionSymbol
|
abstract val arrayOf: IrSimpleFunctionSymbol
|
||||||
abstract val arrayOfNulls: IrSimpleFunctionSymbol
|
abstract val arrayOfNulls: IrSimpleFunctionSymbol
|
||||||
|
|||||||
+22
-3
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
@ObsoleteDescriptorBasedAPI
|
@ObsoleteDescriptorBasedAPI
|
||||||
class IrBuiltInsOverDescriptors(
|
class IrBuiltInsOverDescriptors(
|
||||||
@@ -502,14 +503,22 @@ class IrBuiltInsOverDescriptors(
|
|||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|
||||||
override val extensionToString: IrSimpleFunctionSymbol = findFunctions(Name.identifier("toString"), "kotlin").first {
|
override val extensionToString: IrSimpleFunctionSymbol = findFunctions(OperatorNameConventions.TO_STRING, "kotlin").first {
|
||||||
val descriptor = it.descriptor
|
val descriptor = it.descriptor
|
||||||
descriptor is SimpleFunctionDescriptor && descriptor.dispatchReceiverParameter == null &&
|
descriptor is SimpleFunctionDescriptor && descriptor.dispatchReceiverParameter == null &&
|
||||||
descriptor.extensionReceiverParameter != null &&
|
descriptor.extensionReceiverParameter != null &&
|
||||||
KotlinBuiltIns.isNullableAny(descriptor.extensionReceiverParameter!!.type) && descriptor.valueParameters.size == 0
|
KotlinBuiltIns.isNullableAny(descriptor.extensionReceiverParameter!!.type) && descriptor.valueParameters.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val stringPlus: IrSimpleFunctionSymbol = findFunctions(Name.identifier("plus"), "kotlin").first {
|
override val memberToString: IrSimpleFunctionSymbol = findBuiltInClassMemberFunctions(
|
||||||
|
anyClass,
|
||||||
|
OperatorNameConventions.TO_STRING
|
||||||
|
).single {
|
||||||
|
val descriptor = it.descriptor
|
||||||
|
descriptor is SimpleFunctionDescriptor && descriptor.valueParameters.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val extensionStringPlus: IrSimpleFunctionSymbol = findFunctions(OperatorNameConventions.PLUS, "kotlin").first {
|
||||||
val descriptor = it.descriptor
|
val descriptor = it.descriptor
|
||||||
descriptor is SimpleFunctionDescriptor && descriptor.dispatchReceiverParameter == null &&
|
descriptor is SimpleFunctionDescriptor && descriptor.dispatchReceiverParameter == null &&
|
||||||
descriptor.extensionReceiverParameter != null &&
|
descriptor.extensionReceiverParameter != null &&
|
||||||
@@ -518,6 +527,16 @@ class IrBuiltInsOverDescriptors(
|
|||||||
KotlinBuiltIns.isNullableAny(descriptor.valueParameters.first().type)
|
KotlinBuiltIns.isNullableAny(descriptor.valueParameters.first().type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val memberStringPlus: IrSimpleFunctionSymbol = findBuiltInClassMemberFunctions(
|
||||||
|
stringClass,
|
||||||
|
OperatorNameConventions.PLUS
|
||||||
|
).single {
|
||||||
|
val descriptor = it.descriptor
|
||||||
|
descriptor is SimpleFunctionDescriptor &&
|
||||||
|
descriptor.valueParameters.size == 1 &&
|
||||||
|
KotlinBuiltIns.isNullableAny(descriptor.valueParameters.first().type)
|
||||||
|
}
|
||||||
|
|
||||||
override fun functionN(arity: Int): IrClass = functionFactory.functionN(arity)
|
override fun functionN(arity: Int): IrClass = functionFactory.functionN(arity)
|
||||||
override fun kFunctionN(arity: Int): IrClass = functionFactory.kFunctionN(arity)
|
override fun kFunctionN(arity: Int): IrClass = functionFactory.kFunctionN(arity)
|
||||||
override fun suspendFunctionN(arity: Int): IrClass = functionFactory.suspendFunctionN(arity)
|
override fun suspendFunctionN(arity: Int): IrClass = functionFactory.suspendFunctionN(arity)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ object OperatorNameConventions {
|
|||||||
@JvmField val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
|
@JvmField val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
|
||||||
|
|
||||||
@JvmField val EQUALS = Name.identifier("equals")
|
@JvmField val EQUALS = Name.identifier("equals")
|
||||||
|
@JvmField val HASH_CODE = Name.identifier("hashCode")
|
||||||
@JvmField val COMPARE_TO = Name.identifier("compareTo")
|
@JvmField val COMPARE_TO = Name.identifier("compareTo")
|
||||||
@JvmField val CONTAINS = Name.identifier("contains")
|
@JvmField val CONTAINS = Name.identifier("contains")
|
||||||
@JvmField val INVOKE = Name.identifier("invoke")
|
@JvmField val INVOKE = Name.identifier("invoke")
|
||||||
|
|||||||
Reference in New Issue
Block a user