Add type operand symbol for type operator expression

This commit is contained in:
Dmitry Petrov
2018-02-22 12:39:04 +03:00
parent e89047d2cc
commit b206bf199f
65 changed files with 442 additions and 61 deletions
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
@@ -168,18 +169,42 @@ fun IrBuilderWithScope.irCallOp(
putValueArgument(0, argument)
}
@Deprecated("Creates unbound symbol")
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument)
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument, typeClassifier)
@Deprecated("Creates unbound symbol")
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.NOT_INSTANCEOF, type, argument)
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(
startOffset, endOffset,
context.builtIns.booleanType,
IrTypeOperator.NOT_INSTANCEOF,
type, argument, typeClassifier
)
@Deprecated("Creates unbound symbol")
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument)
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument, typeClassifier)
@Deprecated("Creates unbound symbol")
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument)
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument, typeClassifier)
fun IrBuilderWithScope.irInt(value: Int) =
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.types.KotlinType
enum class IrTypeOperator {
@@ -33,5 +34,6 @@ interface IrTypeOperatorCall : IrExpression {
val operator: IrTypeOperator
var argument: IrExpression
val typeOperand: KotlinType
val typeOperandClassifier: IrClassifierSymbol
}
@@ -44,7 +44,7 @@ class IrClassReferenceImpl(
type: KotlinType,
descriptor: ClassifierDescriptor,
classType: KotlinType
) : this(startOffset, endOffset, type, createClassifierSymbolForClassReference(descriptor), classType)
) : this(startOffset, endOffset, type, createClassifierSymbol(descriptor), classType)
override val descriptor: ClassifierDescriptor get() = symbol.descriptor
@@ -52,7 +52,7 @@ class IrClassReferenceImpl(
visitor.visitClassReference(this, data)
}
internal fun createClassifierSymbolForClassReference(descriptor: ClassifierDescriptor): IrClassifierSymbol =
internal fun createClassifierSymbol(descriptor: ClassifierDescriptor): IrClassifierSymbol =
when (descriptor) {
is ClassDescriptor -> IrClassSymbolImpl(descriptor)
is TypeParameterDescriptor -> IrTypeParameterSymbolImpl(descriptor)
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -30,6 +31,7 @@ class IrTypeOperatorCallImpl(
override val operator: IrTypeOperator,
override val typeOperand: KotlinType
) : IrExpressionBase(startOffset, endOffset, type), IrTypeOperatorCall {
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
endOffset: Int,
@@ -39,9 +41,28 @@ class IrTypeOperatorCallImpl(
argument: IrExpression
) : this(startOffset, endOffset, type, operator, typeOperand) {
this.argument = argument
val typeOperandDescriptor = typeOperand.constructor.declarationDescriptor
if (typeOperandDescriptor != null) {
this.typeOperandClassifier = createClassifierSymbol(typeOperandDescriptor)
}
}
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
operator: IrTypeOperator,
typeOperand: KotlinType,
argument: IrExpression,
typeOperandClassifier: IrClassifierSymbol
) : this(startOffset, endOffset, type, operator, typeOperand) {
this.argument = argument
this.typeOperandClassifier = typeOperandClassifier
}
override lateinit var argument: IrExpression
override lateinit var typeOperandClassifier: IrClassifierSymbol
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitTypeOperator(this, data)
@@ -506,7 +506,15 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.type,
expression.operator,
expression.typeOperand,
expression.argument.transform()
expression.argument.transform(),
run {
val oldTypeDescriptor = expression.typeOperandClassifier.descriptor
val newTypeDescriptor = mapClassifierReference(oldTypeDescriptor)
if (newTypeDescriptor == oldTypeDescriptor)
expression.typeOperandClassifier
else
createUnboundClassifierSymbol(newTypeDescriptor)
}
)
override fun visitWhen(expression: IrWhen): IrWhen =
@@ -437,7 +437,8 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
expression.type,
expression.operator,
expression.typeOperand,
expression.argument.transform()
expression.argument.transform(),
symbolRemapper.getReferencedClassifier(expression.typeOperandClassifier)
)
override fun visitWhen(expression: IrWhen): IrWhen =
@@ -16,12 +16,10 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -114,11 +112,16 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
private fun IrSymbol.renderDeclarationElementOrDescriptor() {
private fun IrSymbol.renderDeclarationElementOrDescriptor(label: String? = null) {
if (isBound)
owner.render()
else
printer.println("UNBOUND: ", DescriptorRenderer.COMPACT.render(descriptor))
owner.render(label)
else {
if (label != null) {
printer.println("$label: ", "UNBOUND: ", DescriptorRenderer.COMPACT.render(descriptor))
} else {
printer.println("UNBOUND: ", DescriptorRenderer.COMPACT.render(descriptor))
}
}
}
override fun visitConstructor(declaration: IrConstructor, data: String) {
@@ -227,13 +230,25 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
}
}
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: String) {
expression.dumpLabeledElementWith(data) {
expression.typeOperandClassifier.renderDeclarationElementOrDescriptor("typeOperand")
expression.acceptChildren(this, "")
}
}
private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) {
printer.println(accept(elementRenderer, null).withLabel(label))
indented(body)
}
private fun IrElement.render() {
printer.println(accept(elementRenderer, null))
private fun IrElement.render(label: String? = null) {
if (label != null) {
printer.println("$label: ", accept(elementRenderer, null))
} else {
printer.println(accept(elementRenderer, null))
}
}
private fun IrElement.dumpLabeledSubTree(label: String) {
@@ -149,10 +149,10 @@ class SymbolTable {
private val fieldSymbolTable = FlatSymbolTable<PropertyDescriptor, IrField, IrFieldSymbol>()
private val simpleFunctionSymbolTable = FlatSymbolTable<FunctionDescriptor, IrSimpleFunction, IrSimpleFunctionSymbol>()
private val typeParameterSymbolTable = ScopedSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
private val typeParameterSymbolTable = FlatSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
private val valueParameterSymbolTable = ScopedSymbolTable<ParameterDescriptor, IrValueParameter, IrValueParameterSymbol>()
private val variableSymbolTable = ScopedSymbolTable<VariableDescriptor, IrVariable, IrVariableSymbol>()
private val scopedSymbolTables = listOf(typeParameterSymbolTable, valueParameterSymbolTable, variableSymbolTable)
private val scopedSymbolTables = listOf(valueParameterSymbolTable, variableSymbolTable)
fun declareFile(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor): IrFile =
IrFileImpl(fileEntry, IrFileSymbolImpl(packageFragmentDescriptor))
@@ -256,7 +256,7 @@ class SymbolTable {
origin: IrDeclarationOrigin,
descriptor: TypeParameterDescriptor
): IrTypeParameter =
typeParameterSymbolTable.declareLocal(
typeParameterSymbolTable.declare(
descriptor,
{ IrTypeParameterSymbolImpl(descriptor) },
{ IrTypeParameterImpl(startOffset, endOffset, origin, it) }
@@ -342,7 +342,9 @@ class SymbolTable {
fun referenceClassifier(classifier: ClassifierDescriptor): IrClassifierSymbol =
when (classifier) {
is TypeParameterDescriptor ->
typeParameterSymbolTable.referenced(classifier) { throw AssertionError("Undefined type parameter referenced: $classifier") }
typeParameterSymbolTable.referenced(classifier) {
throw AssertionError("Undefined type parameter referenced: $classifier")
}
is ClassDescriptor ->
classSymbolTable.referenced(classifier) { IrClassSymbolImpl(classifier) }
else ->