[IR] Support isAssignable in builders and serialization.

This commit is contained in:
Mads Ager
2020-09-30 14:38:06 +02:00
committed by Alexander Udalov
parent 37145fb055
commit af0999ec6f
12 changed files with 44 additions and 12 deletions
@@ -843,7 +843,7 @@ class Fir2IrDeclarationStorage(
valueParameter.name, index, type, valueParameter.name, index, type,
if (!valueParameter.isVararg) null if (!valueParameter.isVararg) null
else valueParameter.returnTypeRef.coneType.arrayElementType()?.toIrType(typeContext), else valueParameter.returnTypeRef.coneType.arrayElementType()?.toIrType(typeContext),
valueParameter.isCrossinline, valueParameter.isNoinline, false valueParameter.isCrossinline, valueParameter.isNoinline
).apply { ).apply {
descriptor.bind(this) descriptor.bind(this)
if (valueParameter.defaultValue.let { if (valueParameter.defaultValue.let {
@@ -172,7 +172,7 @@ fun IrFunction.copyReceiverParametersFrom(from: IrFunction) {
startOffset, endOffset, origin, startOffset, endOffset, origin,
IrValueParameterSymbolImpl(newDescriptor), IrValueParameterSymbolImpl(newDescriptor),
name, name,
index, type, varargElementType, isCrossinline, isNoinline, false index, type, varargElementType, isCrossinline, isNoinline
).also { parameter -> ).also { parameter ->
parameter.parent = this@copyReceiverParametersFrom parameter.parent = this@copyReceiverParametersFrom
newDescriptor.bind(this) newDescriptor.bind(this)
@@ -422,9 +422,8 @@ fun IrFunction.createDispatchReceiverParameter(origin: IrDeclarationOrigin? = nu
-1, -1,
parentAsClass.defaultType, parentAsClass.defaultType,
null, null,
false, isCrossinline = false,
false, isNoinline = false
false
).apply { ).apply {
parent = this@createDispatchReceiverParameter parent = this@createDispatchReceiverParameter
newDescriptor.bind(this) newDescriptor.bind(this)
@@ -226,7 +226,7 @@ internal fun IrFactory.buildValueParameter(builder: IrValueParameterBuilder, par
return createValueParameter( return createValueParameter(
startOffset, endOffset, origin, startOffset, endOffset, origin,
IrValueParameterSymbolImpl(wrappedDescriptor), IrValueParameterSymbolImpl(wrappedDescriptor),
name, index, type, varargElementType, isCrossInline, isNoinline, isHidden, false name, index, type, varargElementType, isCrossInline, isNoinline, isHidden, isAssignable
).also { ).also {
wrappedDescriptor.bind(it) wrappedDescriptor.bind(it)
it.parent = parent it.parent = parent
@@ -18,6 +18,7 @@ class IrValueParameterBuilder : IrDeclarationBuilder() {
var isCrossInline = false var isCrossInline = false
var isNoinline = false var isNoinline = false
var isHidden = false var isHidden = false
var isAssignable = false
fun updateFrom(from: IrValueParameter) { fun updateFrom(from: IrValueParameter) {
super.updateFrom(from) super.updateFrom(from)
@@ -28,5 +29,6 @@ class IrValueParameterBuilder : IrDeclarationBuilder() {
isCrossInline = from.isCrossinline isCrossInline = from.isCrossinline
isNoinline = from.isNoinline isNoinline = from.isNoinline
isHidden = from.isHidden isHidden = from.isHidden
isAssignable = from.isAssignable
} }
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.expressions.impl package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrSetValue import org.jetbrains.kotlin.ir.expressions.IrSetValue
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
@@ -32,6 +33,24 @@ class IrSetValueImpl(
override var value: IrExpression, override var value: IrExpression,
override val origin: IrStatementOrigin? override val origin: IrStatementOrigin?
) : IrSetValue() { ) : IrSetValue() {
companion object {
private fun isVariableOrAssignable(symbol: IrValueSymbol): Boolean {
val declaration = symbol.owner
return if (declaration is IrValueParameter) {
declaration.isAssignable
} else {
true
}
}
}
init {
assert(isVariableOrAssignable(symbol)) {
"Only IrVariables and assignable IrValueParameters can be set"
}
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R { override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSetValue(this, data) return visitor.visitSetValue(this, data)
} }
@@ -349,7 +349,7 @@ open class DeepCopyIrTreeWithSymbols(
declaration.varargElementType?.remapType(), declaration.varargElementType?.remapType(),
declaration.isCrossinline, declaration.isCrossinline,
declaration.isNoinline, declaration.isNoinline,
false declaration.isAssignable
).apply { ).apply {
transformAnnotations(declaration) transformAnnotations(declaration)
defaultValue = declaration.defaultValue?.transform() defaultValue = declaration.defaultValue?.transform()
@@ -525,6 +525,7 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
"vararg".takeIf { varargElementType != null }, "vararg".takeIf { varargElementType != null },
"crossinline".takeIf { isCrossinline }, "crossinline".takeIf { isCrossinline },
"noinline".takeIf { isNoinline }, "noinline".takeIf { isNoinline },
"assignable".takeIf { isAssignable }
) )
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: Nothing?): String = override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: Nothing?): String =
@@ -1010,7 +1010,7 @@ abstract class IrFileDeserializer(
flags.isCrossInline, flags.isCrossInline,
flags.isNoInline, flags.isNoInline,
flags.isHidden, flags.isHidden,
false flags.isAssignable
).apply { ).apply {
if (proto.hasDefaultValue()) if (proto.hasDefaultValue())
defaultValue = irFactory.createExpressionBody(deserializeExpressionBody(proto.defaultValue)) defaultValue = irFactory.createExpressionBody(deserializeExpressionBody(proto.defaultValue))
@@ -30,6 +30,7 @@ public class IrFlags extends Flags {
// Parameters // Parameters
public static final BooleanFlagField IS_HIDDEN = FlagField.booleanAfter(IS_NOINLINE); public static final BooleanFlagField IS_HIDDEN = FlagField.booleanAfter(IS_NOINLINE);
public static final BooleanFlagField IS_ASSIGNABLE = FlagField.booleanAfter(IS_HIDDEN);
// Local variables // Local variables
public static final BooleanFlagField IS_LOCAL_VAR = FlagField.booleanAfter(HAS_ANNOTATIONS); public static final BooleanFlagField IS_LOCAL_VAR = FlagField.booleanAfter(HAS_ANNOTATIONS);
@@ -88,13 +89,15 @@ public class IrFlags extends Flags {
boolean declaresDefaultValue, boolean declaresDefaultValue,
boolean isCrossinline, boolean isCrossinline,
boolean isNoinline, boolean isNoinline,
boolean isHidden boolean isHidden,
boolean isAssignable
) { ) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations) return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| DECLARES_DEFAULT_VALUE.toFlags(declaresDefaultValue) | DECLARES_DEFAULT_VALUE.toFlags(declaresDefaultValue)
| IS_CROSSINLINE.toFlags(isCrossinline) | IS_CROSSINLINE.toFlags(isCrossinline)
| IS_NOINLINE.toFlags(isNoinline) | IS_NOINLINE.toFlags(isNoinline)
| IS_HIDDEN.toFlags(isHidden) | IS_HIDDEN.toFlags(isHidden)
| IS_ASSIGNABLE.toFlags(isAssignable)
; ;
} }
@@ -143,11 +143,19 @@ inline class ValueParameterFlags(val flags: Long) {
val isCrossInline: Boolean get() = IrFlags.IS_CROSSINLINE.get(flags.toInt()) val isCrossInline: Boolean get() = IrFlags.IS_CROSSINLINE.get(flags.toInt())
val isNoInline: Boolean get() = IrFlags.IS_NOINLINE.get(flags.toInt()) val isNoInline: Boolean get() = IrFlags.IS_NOINLINE.get(flags.toInt())
val isHidden: Boolean get() = IrFlags.IS_HIDDEN.get(flags.toInt()) val isHidden: Boolean get() = IrFlags.IS_HIDDEN.get(flags.toInt())
val isAssignable: Boolean get() = IrFlags.IS_ASSIGNABLE.get(flags.toInt())
companion object { companion object {
fun encode(param: IrValueParameter): Long { fun encode(param: IrValueParameter): Long {
return param.run { return param.run {
IrFlags.getValueParameterFlags(annotations.isNotEmpty(), defaultValue != null, isCrossinline, isNoinline, isHidden).toLong() IrFlags.getValueParameterFlags(
annotations.isNotEmpty(),
defaultValue != null,
isCrossinline,
isNoinline,
isHidden,
isAssignable
).toLong()
} }
} }
@@ -320,7 +320,7 @@ class IrSparseArrayParcelSerializer(
} }
val dec = context.irBuiltIns.intClass.getSimpleFunction("dec")!! val dec = context.irBuiltIns.intClass.getSimpleFunction("dec")!!
+irSetVar(remainingSizeTemporary.symbol, irCall(dec).apply { +irSet(remainingSizeTemporary.symbol, irCall(dec).apply {
dispatchReceiver = irGet(remainingSizeTemporary) dispatchReceiver = irGet(remainingSizeTemporary)
}) })
} }
@@ -140,7 +140,7 @@ inline fun IrBlockBuilder.forUntil(upperBound: IrExpression, loopBody: IrBlockBu
body = irBlock { body = irBlock {
loopBody(indexTemporary) loopBody(indexTemporary)
val inc = context.irBuiltIns.intClass.getSimpleFunction("inc")!! val inc = context.irBuiltIns.intClass.getSimpleFunction("inc")!!
+irSetVar(indexTemporary.symbol, irCall(inc).apply { +irSet(indexTemporary.symbol, irCall(inc).apply {
dispatchReceiver = irGet(indexTemporary) dispatchReceiver = irGet(indexTemporary)
}) })
} }