diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index 6d9e64d9668..22567451448 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -80,7 +80,12 @@ class StatementGenerator( genStmt().assertCast() override fun visitExpression(expression: KtExpression, data: Nothing?): IrStatement = - createDummyExpression(expression, expression::class.java.simpleName) + IrErrorExpressionImpl( + expression.startOffset, + expression.endOffset, + context.irBuiltIns.nothingType, + expression::class.java.simpleName + ) override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement { val variableDescriptor = getOrFail(BindingContext.VARIABLE, property) @@ -110,7 +115,7 @@ class StatementGenerator( override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement { val irBlock = IrCompositeImpl( multiDeclaration.startOffset, multiDeclaration.endOffset, - context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION + context.irBuiltIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION ) val ktInitializer = multiDeclaration.initializer!! val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container") @@ -166,11 +171,11 @@ class StatementGenerator( override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement { val returnTarget = getReturnExpressionTarget(expression) val irReturnedExpression = expression.returnedExpression?.genExpr() ?: IrGetObjectValueImpl( - expression.startOffset, expression.endOffset, context.builtIns.unitType, + expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, context.symbolTable.referenceClass(context.builtIns.unit) ) return IrReturnImpl( - expression.startOffset, expression.endOffset, context.builtIns.nothingType, + expression.startOffset, expression.endOffset, context.irBuiltIns.nothingType, context.symbolTable.referenceFunction(returnTarget), irReturnedExpression ) } @@ -202,7 +207,7 @@ class StatementGenerator( return IrThrowImpl( expression.startOffset, expression.endOffset, - context.builtIns.nothingType, + context.irBuiltIns.nothingType, expression.thrownExpression!!.genExpr() ) } @@ -223,7 +228,7 @@ class StatementGenerator( override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement { val entries = expression.entries - val resultType = getInferredTypeWithImplicitCastsOrFail(expression) + val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType() return when (entries.size) { 1 -> { val irArg = entries[0].genExpr() @@ -240,10 +245,10 @@ class StatementGenerator( } override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement = - IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text) + IrConstImpl.string(entry.startOffset, entry.endOffset, context.irBuiltIns.stringType, entry.text) override fun visitEscapeStringTemplateEntry(entry: KtEscapeStringTemplateEntry, data: Nothing?): IrStatement = - IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.unescapedValue) + IrConstImpl.string(entry.startOffset, entry.endOffset, context.irBuiltIns.stringType, entry.unescapedValue) override fun visitStringTemplateEntryWithExpression(entry: KtStringTemplateEntryWithExpression, data: Nothing?): IrStatement = entry.expression!!.genExpr() @@ -309,15 +314,22 @@ class StatementGenerator( override fun visitThisExpression(expression: KtThisExpression, data: Nothing?): IrExpression { val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" } return when (referenceTarget) { - is ClassDescriptor -> + is ClassDescriptor -> { + val thisAsReceiverParameter = referenceTarget.thisAsReceiverParameter + val thisType = thisAsReceiverParameter.type.toIrType() IrGetValueImpl( expression.startOffset, expression.endOffset, - context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter) + thisType, + context.symbolTable.referenceValueParameter(thisAsReceiverParameter) ) + } + is CallableDescriptor -> { val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget") + val extensionReceiverType = extensionReceiver.type.toIrType() IrGetValueImpl( expression.startOffset, expression.endOffset, + extensionReceiverType, context.symbolTable.referenceValueParameter(extensionReceiver) ) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt index 8fbe55e4ac0..aa5d3113eec 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt @@ -26,8 +26,10 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl +import org.jetbrains.kotlin.ir.types.withHasQuestionMark import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType @@ -36,11 +38,21 @@ import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.makeNullable -class IrBuiltIns(val builtIns: KotlinBuiltIns) { - private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule, KOTLIN_INTERNAL_IR_FQN) +class IrBuiltIns(val builtIns: KotlinBuiltIns, outerSymbolTable: SymbolTable?) { + + constructor(builtIns: KotlinBuiltIns) : this(builtIns, null) + + private val builtInsModule = builtIns.builtInsModule + + private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN) val irBuiltInsExternalPackageFragment = IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(packageFragment)) - private val stubBuilder = DeclarationStubGenerator(SymbolTable(), IrDeclarationOrigin.IR_BUILTINS_STUB) + private val symbolTable = outerSymbolTable ?: SymbolTable() + private val stubBuilder = DeclarationStubGenerator(builtInsModule, symbolTable, IrDeclarationOrigin.IR_BUILTINS_STUB) + private val typeTranslator = TypeTranslator(builtInsModule, symbolTable) + + private fun ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this) + private fun KotlinType.toIrType() = typeTranslator.translateType(this) fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List): IrSimpleFunction { val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType) @@ -68,19 +80,57 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) { private fun List.defineComparisonOperatorForEachType(name: String) = associate { it to defineComparisonOperator(name, it) } - val bool = builtIns.booleanType val any = builtIns.anyType val anyN = builtIns.nullableAnyType + val anyType = any.toIrType() + val anyClass = builtIns.any.toIrSymbol() + val anyNType = anyType.withHasQuestionMark(true) + + val bool = builtIns.booleanType + val boolType = bool.toIrType() + val boolClass = builtIns.boolean.toIrSymbol() + val char = builtIns.charType + val charType = char.toIrType() + val charClass = builtIns.char.toIrSymbol() + val byte = builtIns.byteType + val byteType = byte.toIrType() + val byteClass = builtIns.byte.toIrSymbol() + val short = builtIns.shortType + val shortType = short.toIrType() + val shortClass = builtIns.short.toIrSymbol() + val int = builtIns.intType + val intType = int.toIrType() + val intClass = builtIns.int.toIrSymbol() + val long = builtIns.longType + val longType = long.toIrType() + val longClass = builtIns.long.toIrSymbol() + val float = builtIns.floatType + val floatType = float.toIrType() + val floatClass = builtIns.float.toIrSymbol() + val double = builtIns.doubleType + val doubleType = double.toIrType() + val doubleClass = builtIns.double.toIrSymbol() + val nothing = builtIns.nothingType + val nothingN = builtIns.nullableNothingType + val nothingType = nothing.toIrType() + val nothingClass = builtIns.nothing.toIrSymbol() + val nothingNType = nothingType.withHasQuestionMark(true) + val unit = builtIns.unitType + val unitType = unit.toIrType() + val unitClass = builtIns.unit.toIrSymbol() + val string = builtIns.stringType + val stringType = string.toIrType() + val stringClass = builtIns.string.toIrSymbol() val primitiveTypes = listOf(bool, char, byte, short, int, long, float, double) val primitiveTypesWithComparisons = listOf(int, long, float, double) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt new file mode 100644 index 00000000000..91e36a2a530 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.ir.types + +import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.kotlin.utils.addToStdlib.safeAs + +fun IrType.withHasQuestionMark(hasQuestionMark: Boolean): IrType = + when (this) { + is IrSimpleType -> + if (this.hasQuestionMark == hasQuestionMark) + this + else + IrSimpleTypeImpl(classifier, hasQuestionMark, arguments, annotations) + else -> this + } + +val IrType.classifierOrFail: IrClassifierSymbol + get() = cast().classifier + +val IrType.classifierOrNull: IrClassifierSymbol? + get() = safeAs()?.classifier