IR: rename {name,fqName}Safe -> {name,fqName}ForIrSerialization

These properties have a very specific detail in their behavior, in that
the constructor's name is set to be "<init>". While this is OK for the
IR serialization, this may not always be expected in other cases, and
their rather common names (`name`, `fqNameSafe`) suggested that these
properties could be used in generic contexts.

Change all usages outside IR serialization to use
`IrDeclarationWithName.name` and nullable
`IrDeclarationWithName.fqNameWhenAvailable` instead
This commit is contained in:
Alexander Udalov
2019-05-21 18:50:04 +02:00
parent 4e1effd065
commit 8dc34ae7b9
7 changed files with 64 additions and 51 deletions
@@ -6,7 +6,10 @@
package org.jetbrains.kotlin.backend.common.lower package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.descriptors.* import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedFieldDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -14,15 +17,23 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -73,7 +84,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
// Suppress since it is used in native // Suppress since it is used in native
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
protected fun IrCall.isReturnIfSuspendedCall() = protected fun IrCall.isReturnIfSuspendedCall() =
symbol.owner.run { fqNameSafe == context.internalPackageFqn.child(Name.identifier("returnIfSuspended")) } symbol.owner.run { fqNameWhenAvailable == context.internalPackageFqn.child(Name.identifier("returnIfSuspended")) }
private fun tryTransformSuspendFunction(element: IrElement) = private fun tryTransformSuspendFunction(element: IrElement) =
if (element is IrSimpleFunction && element.isSuspend && element.modality != Modality.ABSTRACT) if (element is IrSimpleFunction && element.isSuspend && element.modality != Modality.ABSTRACT)
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameSafe import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -158,5 +158,5 @@ class TestGenerator(val context: JsIrBackendContext) : FileLoweringPass {
get() = hasAnnotation("kotlin.test.AfterTest") get() = hasAnnotation("kotlin.test.AfterTest")
private fun IrAnnotationContainer.hasAnnotation(fqName: String) = private fun IrAnnotationContainer.hasAnnotation(fqName: String) =
annotations.any { it.symbol.owner.parent.fqNameSafe == FqName(fqName) } annotations.any { it.symbol.owner.fqNameWhenAvailable?.parent()?.asString() == fqName }
} }
@@ -9,7 +9,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.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.fqNameSafe import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
@@ -35,6 +35,6 @@ private fun IrTypeArgument.asString(): String = when(this) {
private fun IrClassifierSymbol.asString() = when (this) { private fun IrClassifierSymbol.asString() = when (this) {
is IrTypeParameterSymbol -> this.owner.name.asString() is IrTypeParameterSymbol -> this.owner.name.asString()
is IrClassSymbol -> this.owner.fqNameSafe.asString() is IrClassSymbol -> this.owner.fqNameWhenAvailable!!.asString()
else -> error("Unexpected kind of IrClassifierSymbol: " + javaClass.typeName) else -> error("Unexpected kind of IrClassifierSymbol: " + javaClass.typeName)
} }
@@ -79,7 +79,7 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : ClassLow
// the `irDelegatingConstructorCall` in the constructor below would need to be modified. // the `irDelegatingConstructorCall` in the constructor below would need to be modified.
assert(superClass.kind == ClassKind.INTERFACE) { "SAM conversion to an abstract class not allowed" } assert(superClass.kind == ClassKind.INTERFACE) { "SAM conversion to an abstract class not allowed" }
val superClassName = superClass.fqNameSafe.pathSegments().joinToString("_") { it.toString() } val superClassName = superClass.fqNameWhenAvailable!!.pathSegments().joinToString("_") { it.toString() }
val subclass = buildClass { val subclass = buildClass {
// TODO this is not the name some tests (e.g. kt11519) expect // TODO this is not the name some tests (e.g. kt11519) expect
name = Name.identifier("sam\$$superClassName\$${cachedImplementations.size + localImplementations.size}") name = Name.identifier("sam\$$superClassName\$${cachedImplementations.size + localImplementations.size}")
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.ir.util package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.SourceManager import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.SourceRangeInfo import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -18,42 +17,45 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import java.io.File import java.io.File
val IrConstructor.constructedClass get() = this.parent as IrClass val IrConstructor.constructedClass get() = this.parent as IrClass
val <T : IrDeclaration> T.original get() = this val <T : IrDeclaration> T.original get() = this
val IrDeclarationParent.fqNameSafe: FqName val IrDeclarationParent.fqNameForIrSerialization: FqName
get() = when (this) { get() = when (this) {
is IrPackageFragment -> this.fqName is IrPackageFragment -> this.fqName
is IrDeclaration -> this.parent.fqNameSafe.child(this.name) is IrDeclaration -> this.parent.fqNameForIrSerialization.child(this.nameForIrSerialization)
else -> error(this) else -> error(this)
} }
@Deprecated(
"Use fqNameForIrSerialization instead.",
ReplaceWith("fqNameForIrSerialization", "org.jetbrains.kotlin.ir.util.fqNameForIrSerialization"),
DeprecationLevel.ERROR
)
val IrDeclarationParent.fqNameSafe: FqName
get() = fqNameForIrSerialization
val IrClass.classId: ClassId? val IrClass.classId: ClassId?
get() { get() = when (val parent = this.parent) {
val parent = this.parent is IrClass -> parent.classId?.createNestedClassId(this.name)
return when (parent) { is IrPackageFragment -> ClassId.topLevel(parent.fqName.child(this.name))
is IrClass -> parent.classId?.createNestedClassId(this.name) else -> null
is IrPackageFragment -> ClassId.topLevel(parent.fqName.child(this.name))
else -> null
}
} }
val IrDeclaration.name: Name val IrDeclaration.nameForIrSerialization: Name
get() = when (this) { get() = when (this) {
is IrSimpleFunction -> this.name is IrDeclarationWithName -> this.name
is IrClass -> this.name
is IrEnumEntry -> this.name
is IrProperty -> this.name
is IrLocalDelegatedProperty -> this.name
is IrField -> this.name
is IrVariable -> this.name
is IrConstructor -> SPECIAL_INIT_NAME is IrConstructor -> SPECIAL_INIT_NAME
is IrValueParameter -> this.name
else -> error(this) else -> error(this)
} }
@Deprecated(
"Use nameForIrSerialization instead.",
ReplaceWith("nameForIrSerialization", "org.jetbrains.kotlin.ir.util.nameForIrSerialization"),
DeprecationLevel.ERROR
)
val IrDeclaration.name: Name
get() = nameForIrSerialization
private val SPECIAL_INIT_NAME = Name.special("<init>") private val SPECIAL_INIT_NAME = Name.special("<init>")
@@ -79,10 +81,10 @@ private val IrConstructorCall.annotationClass
get() = this.symbol.owner.constructedClass get() = this.symbol.owner.constructedClass
fun List<IrConstructorCall>.hasAnnotation(fqName: FqName): Boolean = fun List<IrConstructorCall>.hasAnnotation(fqName: FqName): Boolean =
any { it.annotationClass.fqNameSafe == fqName } any { it.annotationClass.fqNameWhenAvailable == fqName }
fun List<IrConstructorCall>.findAnnotation(fqName: FqName): IrConstructorCall? = fun List<IrConstructorCall>.findAnnotation(fqName: FqName): IrConstructorCall? =
firstOrNull { it.annotationClass.fqNameSafe == fqName } firstOrNull { it.annotationClass.fqNameWhenAvailable == fqName }
val IrDeclaration.fileEntry: SourceManager.FileEntry val IrDeclaration.fileEntry: SourceManager.FileEntry
get() = parent.let { get() = parent.let {
@@ -110,7 +110,7 @@ abstract class KotlinManglerImpl: KotlinMangler {
return "#GENERIC${if (type.isMarkedNullable()) "?" else ""}$upperBounds" return "#GENERIC${if (type.isMarkedNullable()) "?" else ""}$upperBounds"
} }
var hashString = type.getClass()?.run { fqNameSafe.asString() } ?: "<dynamic>" var hashString = type.getClass()?.run { fqNameForIrSerialization.asString() } ?: "<dynamic>"
when (type) { when (type) {
is IrSimpleType -> { is IrSimpleType -> {
@@ -185,7 +185,7 @@ abstract class KotlinManglerImpl: KotlinMangler {
val IrField.symbolName: String val IrField.symbolName: String
get() { get() {
val containingDeclarationPart = parent.fqNameSafe.let { val containingDeclarationPart = parent.fqNameForIrSerialization.let {
if (it.isRoot) "" else "$it." if (it.isRoot) "" else "$it."
} }
return "kfield:$containingDeclarationPart$name" return "kfield:$containingDeclarationPart$name"
@@ -195,12 +195,12 @@ abstract class KotlinManglerImpl: KotlinMangler {
val IrClass.typeInfoSymbolName: String val IrClass.typeInfoSymbolName: String
get() { get() {
assert(this.isExported()) assert(this.isExported())
return "ktype:" + this.fqNameSafe.toString() return "ktype:" + this.fqNameForIrSerialization.toString()
} }
val IrTypeParameter.symbolName: String val IrTypeParameter.symbolName: String
get() { get() {
val containingDeclarationPart = parent.fqNameSafe val containingDeclarationPart = parent.fqNameForIrSerialization
return "ktypeparam:$containingDeclarationPart$name" return "ktypeparam:$containingDeclarationPart$name"
} }
@@ -233,14 +233,14 @@ abstract class KotlinManglerImpl: KotlinMangler {
private val IrDeclaration.uniqName: Name private val IrDeclaration.uniqName: Name
get() = when (this) { get() = when (this) {
is IrSimpleFunction -> Name.special("<${this.uniqFunctionName}>") is IrSimpleFunction -> Name.special("<${this.uniqFunctionName}>")
else -> this.name else -> this.nameForIrSerialization
} }
private val IrProperty.symbolName: String private val IrProperty.symbolName: String
get() { get() {
val extensionReceiver: String = getter!!.extensionReceiverParameter?.extensionReceiverNamePart ?: "" val extensionReceiver: String = getter!!.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
val containingDeclarationPart = parent.fqNameSafe.let { val containingDeclarationPart = parent.fqNameForIrSerialization.let {
if (it.isRoot) "" else "$it." if (it.isRoot) "" else "$it."
} }
return "kprop:$containingDeclarationPart$extensionReceiver$name" return "kprop:$containingDeclarationPart$extensionReceiver$name"
@@ -248,7 +248,7 @@ abstract class KotlinManglerImpl: KotlinMangler {
private val IrEnumEntry.symbolName: String private val IrEnumEntry.symbolName: String
get() { get() {
val containingDeclarationPart = parent.fqNameSafe.let { val containingDeclarationPart = parent.fqNameForIrSerialization.let {
if (it.isRoot) "" else "$it." if (it.isRoot) "" else "$it."
} }
return "kenumentry:$containingDeclarationPart$name" return "kenumentry:$containingDeclarationPart$name"
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.fqNameSafe import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.name import org.jetbrains.kotlin.ir.util.nameForIrSerialization
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -33,11 +33,11 @@ internal val BUILT_IN_UNIQ_ID_GAP = 2 * BUILT_IN_FUNCTION_ARITY_COUNT * BUILT_IN
internal val BUILT_IN_UNIQ_ID_CLASS_OFFSET = BUILT_IN_FUNCTION_CLASS_COUNT * BUILT_IN_FUNCTION_ARITY_COUNT internal val BUILT_IN_UNIQ_ID_CLASS_OFFSET = BUILT_IN_FUNCTION_CLASS_COUNT * BUILT_IN_FUNCTION_ARITY_COUNT
internal fun isBuiltInFunction(value: IrDeclaration): Boolean = when (value) { internal fun isBuiltInFunction(value: IrDeclaration): Boolean = when (value) {
is IrSimpleFunction -> value.name.asString() == "invoke" && (value.parent as? IrClass)?.let { isBuiltInFunction(it) } == true is IrSimpleFunction ->
is IrClass -> { value.name.asString() == "invoke" && (value.parent as? IrClass)?.let { isBuiltInFunction(it) } == true
val fqn = value.parent.fqNameSafe is IrClass ->
functionalPackages.any { it == fqn } && value.name.asString().let { functionPattern.matcher(it).find() } value.fqNameWhenAvailable?.parent() in functionalPackages &&
} value.name.asString().let { functionPattern.matcher(it).find() }
else -> false else -> false
} }
@@ -57,7 +57,7 @@ internal fun builtInFunctionId(value: IrDeclaration): Long = when (value) {
value.run { valueParameters.size + builtInOffset(value) * BUILT_IN_FUNCTION_ARITY_COUNT }.toLong() value.run { valueParameters.size + builtInOffset(value) * BUILT_IN_FUNCTION_ARITY_COUNT }.toLong()
} }
is IrClass -> { is IrClass -> {
BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.declarations.first { it.name.asString() == "invoke" }) BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.declarations.first { it.nameForIrSerialization.asString() == "invoke" })
} }
else -> error("Only class or function is expected") else -> error("Only class or function is expected")
} }