FIR2IR: introduce conversion scope, remove dispatch receiver for lambdas
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
|
||||
class Fir2IrConversionScope {
|
||||
private val parentStack = mutableListOf<IrDeclarationParent>()
|
||||
|
||||
fun <T : IrDeclarationParent?> withParent(parent: T, f: T.() -> Unit): T {
|
||||
if (parent == null) return parent
|
||||
parentStack += parent
|
||||
parent.f()
|
||||
parentStack.removeAt(parentStack.size - 1)
|
||||
return parent
|
||||
}
|
||||
|
||||
fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T {
|
||||
declaration.parent = parentStack.last()
|
||||
return declaration
|
||||
}
|
||||
|
||||
private val functionStack = mutableListOf<IrFunction>()
|
||||
|
||||
fun <T : IrFunction> withFunction(function: T, f: T.() -> Unit): T {
|
||||
functionStack += function
|
||||
function.f()
|
||||
functionStack.removeAt(functionStack.size - 1)
|
||||
return function
|
||||
}
|
||||
|
||||
private val propertyStack = mutableListOf<IrProperty>()
|
||||
|
||||
fun withProperty(property: IrProperty, f: IrProperty.() -> Unit): IrProperty {
|
||||
propertyStack += property
|
||||
property.f()
|
||||
propertyStack.removeAt(propertyStack.size - 1)
|
||||
return property
|
||||
}
|
||||
|
||||
private val classStack = mutableListOf<IrClass>()
|
||||
|
||||
fun withClass(klass: IrClass, f: IrClass.() -> Unit): IrClass {
|
||||
classStack += klass
|
||||
klass.f()
|
||||
classStack.removeAt(classStack.size - 1)
|
||||
return klass
|
||||
}
|
||||
|
||||
private val subjectVariableStack = mutableListOf<IrVariable>()
|
||||
|
||||
fun <T> withSubject(subject: IrVariable?, f: () -> T): T {
|
||||
if (subject != null) subjectVariableStack += subject
|
||||
val result = f()
|
||||
if (subject != null) subjectVariableStack.removeAt(subjectVariableStack.size - 1)
|
||||
return result
|
||||
}
|
||||
|
||||
fun returnTarget(expression: FirReturnExpression): IrFunction {
|
||||
val firTarget = expression.target.labeledElement
|
||||
for (potentialTarget in functionStack.asReversed()) {
|
||||
// TODO: remove comparison by name
|
||||
if (potentialTarget.name == (firTarget as? FirSimpleFunction)?.name) {
|
||||
return potentialTarget
|
||||
}
|
||||
}
|
||||
return functionStack.last()
|
||||
}
|
||||
|
||||
fun parent(): IrDeclarationParent? = parentStack.lastOrNull()
|
||||
|
||||
fun lastDispatchReceiverParameter(): IrValueParameter? {
|
||||
val dispatchReceiver = functionStack.lastOrNull()?.dispatchReceiverParameter
|
||||
return if (dispatchReceiver != null) {
|
||||
// Use the dispatch receiver of the containing function
|
||||
dispatchReceiver
|
||||
} else {
|
||||
val lastClassSymbol = classStack.lastOrNull()?.symbol
|
||||
// Use the dispatch receiver of the containing class
|
||||
lastClassSymbol?.owner?.thisReceiver
|
||||
}
|
||||
}
|
||||
|
||||
fun lastClass(): IrClass? = classStack.lastOrNull()
|
||||
|
||||
fun lastSubject(): IrVariable = subjectVariableStack.last()
|
||||
}
|
||||
+11
-4
@@ -484,7 +484,7 @@ class Fir2IrDeclarationStorage(
|
||||
)
|
||||
}
|
||||
}
|
||||
if (containingClass != null && !isStatic) {
|
||||
if (function !is FirAnonymousFunction && containingClass != null && !isStatic) {
|
||||
dispatchReceiverParameter = declareThisReceiverParameter(
|
||||
parent,
|
||||
thisType = containingClass.thisReceiver!!.type,
|
||||
@@ -502,6 +502,9 @@ class Fir2IrDeclarationStorage(
|
||||
shouldLeaveScope: Boolean,
|
||||
parentPropertyReceiverType: FirTypeRef? = null
|
||||
): T {
|
||||
if (irParent != null) {
|
||||
parent = irParent
|
||||
}
|
||||
descriptor.bind(this)
|
||||
enterScope(descriptor)
|
||||
declareParameters(function, irParent as? IrClass, isStatic, parentPropertyReceiverType)
|
||||
@@ -729,7 +732,7 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
fun getIrProperty(
|
||||
property: FirProperty,
|
||||
irParent: IrDeclarationParent? = null,
|
||||
irParent: IrDeclarationParent?,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
||||
): IrProperty {
|
||||
return propertyCache.getOrPut(property) {
|
||||
@@ -755,6 +758,9 @@ class Fir2IrDeclarationStorage(
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
if (irParent != null) {
|
||||
parent = irParent
|
||||
}
|
||||
val type = property.returnTypeRef.toIrType()
|
||||
getter = createIrPropertyAccessor(
|
||||
property.getter, property, this, type, irParent, false,
|
||||
@@ -962,8 +968,9 @@ class Fir2IrDeclarationStorage(
|
||||
fun getIrBackingFieldSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol {
|
||||
return when (val fir = firVariableSymbol.fir) {
|
||||
is FirProperty -> {
|
||||
val irProperty = getIrProperty(fir).apply {
|
||||
setAndModifyParent(findIrParent(fir))
|
||||
val irParent = findIrParent(fir)
|
||||
val irProperty = getIrProperty(fir, irParent).apply {
|
||||
setAndModifyParent(irParent)
|
||||
}
|
||||
irSymbolTable.referenceField(irProperty.backingField!!.descriptor)
|
||||
}
|
||||
|
||||
@@ -75,84 +75,25 @@ class Fir2IrVisitor(
|
||||
it.initBuiltinTypes()
|
||||
}
|
||||
|
||||
private fun ModuleDescriptor.findPackageFragmentForFile(file: FirFile): PackageFragmentDescriptor =
|
||||
getPackage(file.packageFqName).fragments.first()
|
||||
|
||||
private val parentStack = mutableListOf<IrDeclarationParent>()
|
||||
|
||||
private fun <T : IrDeclarationParent> T.withParent(f: T.() -> Unit): T {
|
||||
parentStack += this
|
||||
f()
|
||||
parentStack.removeAt(parentStack.size - 1)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun <T : IrDeclaration> T.setParentByParentStack(): T {
|
||||
this.parent = parentStack.last()
|
||||
return this
|
||||
}
|
||||
|
||||
private val functionStack = mutableListOf<IrFunction>()
|
||||
|
||||
private fun <T : IrFunction> T.withFunction(f: T.() -> Unit): T {
|
||||
functionStack += this
|
||||
f()
|
||||
functionStack.removeAt(functionStack.size - 1)
|
||||
return this
|
||||
}
|
||||
|
||||
private val propertyStack = mutableListOf<IrProperty>()
|
||||
|
||||
private fun IrProperty.withProperty(f: IrProperty.() -> Unit): IrProperty {
|
||||
propertyStack += this
|
||||
f()
|
||||
propertyStack.removeAt(propertyStack.size - 1)
|
||||
return this
|
||||
}
|
||||
|
||||
private val classStack = mutableListOf<IrClass>()
|
||||
|
||||
private fun IrClass.withClass(f: IrClass.() -> Unit): IrClass {
|
||||
classStack += this
|
||||
f()
|
||||
classStack.removeAt(classStack.size - 1)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun lastDispatchReceiverParameter(): IrValueParameter? {
|
||||
val dispatchReceiver = functionStack.lastOrNull()?.dispatchReceiverParameter
|
||||
return if (dispatchReceiver != null) {
|
||||
// Use the dispatch receiver of the containing function
|
||||
dispatchReceiver
|
||||
} else {
|
||||
val lastClassSymbol = classStack.lastOrNull()?.symbol
|
||||
// Use the dispatch receiver of the containing class
|
||||
lastClassSymbol?.owner?.thisReceiver
|
||||
}
|
||||
}
|
||||
|
||||
private val subjectVariableStack = mutableListOf<IrVariable>()
|
||||
|
||||
private fun <T> IrVariable?.withSubject(f: () -> T): T {
|
||||
if (this != null) subjectVariableStack += this
|
||||
val result = f()
|
||||
if (this != null) subjectVariableStack.removeAt(subjectVariableStack.size - 1)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
|
||||
private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
|
||||
private val conversionScope = Fir2IrConversionScope()
|
||||
|
||||
private fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T = conversionScope.applyParentFromStackTo(declaration)
|
||||
|
||||
override fun visitElement(element: FirElement, data: Any?): IrElement {
|
||||
TODO("Should not be here: ${element.render()}")
|
||||
}
|
||||
|
||||
override fun visitFile(file: FirFile, data: Any?): IrFile {
|
||||
return IrFileImpl(
|
||||
sourceManager.getOrCreateFileEntry(file.psi as KtFile),
|
||||
moduleDescriptor.findPackageFragmentForFile(file)
|
||||
).withParent {
|
||||
return conversionScope.withParent(
|
||||
IrFileImpl(
|
||||
sourceManager.getOrCreateFileEntry(file.psi as KtFile),
|
||||
moduleDescriptor.getPackage(file.packageFqName).fragments.first()
|
||||
)
|
||||
) {
|
||||
declarationStorage.registerFile(file, this)
|
||||
file.declarations.forEach {
|
||||
val irDeclaration = it.toIrDeclaration() ?: return@forEach
|
||||
@@ -171,12 +112,12 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement {
|
||||
val irEnumEntry = declarationStorage.getIrEnumEntry(enumEntry, irParent = parentStack.last() as IrClass)
|
||||
irEnumEntry.correspondingClass?.withParent {
|
||||
setClassContent(enumEntry.initializer as FirAnonymousObject)
|
||||
val irEnumEntry = declarationStorage.getIrEnumEntry(enumEntry, irParent = conversionScope.lastClass())
|
||||
conversionScope.withParent(irEnumEntry.correspondingClass) {
|
||||
this?.setClassContent(enumEntry.initializer as FirAnonymousObject)
|
||||
}
|
||||
//irEnumEntry.initializerExpression = IrEnumConstructorCallImpl()
|
||||
return irEnumEntry.setParentByParentStack()
|
||||
return irEnumEntry
|
||||
}
|
||||
|
||||
private fun FirClass<*>.getPrimaryConstructorIfAny(): FirConstructor? =
|
||||
@@ -199,7 +140,10 @@ class Fir2IrVisitor(
|
||||
originalFunction, declarationStorage.findIrParent(originalFunction), origin = origin
|
||||
)
|
||||
val baseSymbol = functionSymbol.overriddenSymbol
|
||||
declarations += irFunction.setParentByParentStack().withFunction {
|
||||
// In fake overrides, parent logic is a bit specific, because
|
||||
// parent of *original* function (base class) is used for dispatch receiver,
|
||||
// but fake override itself uses parent from its containing (derived) class
|
||||
declarations += conversionScope.withFunction(applyParentFromStackTo(irFunction)) {
|
||||
setFunctionContent(irFunction.descriptor, originalFunction, firOverriddenSymbol = baseSymbol)
|
||||
}
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalFunction.visibility != Visibilities.PRIVATE) {
|
||||
@@ -211,7 +155,7 @@ class Fir2IrVisitor(
|
||||
val irFunction = declarationStorage.getIrFunction(
|
||||
fakeOverrideFunction, declarationStorage.findIrParent(originalFunction), origin = origin
|
||||
)
|
||||
declarations += irFunction.setParentByParentStack().withFunction {
|
||||
declarations += conversionScope.withFunction(applyParentFromStackTo(irFunction)) {
|
||||
setFunctionContent(irFunction.descriptor, fakeOverrideFunction, firOverriddenSymbol = functionSymbol)
|
||||
}
|
||||
}
|
||||
@@ -227,7 +171,7 @@ class Fir2IrVisitor(
|
||||
originalProperty, declarationStorage.findIrParent(originalProperty), origin = origin
|
||||
)
|
||||
val baseSymbol = propertySymbol.overriddenSymbol
|
||||
declarations += irProperty.setParentByParentStack().withProperty {
|
||||
declarations += conversionScope.withProperty(applyParentFromStackTo(irProperty)) {
|
||||
setPropertyContent(irProperty.descriptor, originalProperty, firOverriddenSymbol = baseSymbol)
|
||||
}
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalProperty.visibility != Visibilities.PRIVATE) {
|
||||
@@ -239,7 +183,7 @@ class Fir2IrVisitor(
|
||||
val irProperty = declarationStorage.getIrProperty(
|
||||
fakeOverrideProperty, declarationStorage.findIrParent(originalProperty), origin = origin
|
||||
)
|
||||
declarations += irProperty.setParentByParentStack().withProperty {
|
||||
declarations += conversionScope.withProperty(applyParentFromStackTo(irProperty)) {
|
||||
setPropertyContent(irProperty.descriptor, fakeOverrideProperty, firOverriddenSymbol = propertySymbol)
|
||||
}
|
||||
}
|
||||
@@ -250,9 +194,9 @@ class Fir2IrVisitor(
|
||||
|
||||
private fun IrClass.setClassContent(klass: FirClass<*>) {
|
||||
declarationStorage.enterScope(descriptor)
|
||||
val primaryConstructor = klass.getPrimaryConstructorIfAny()
|
||||
val irPrimaryConstructor = primaryConstructor?.accept(this@Fir2IrVisitor, null) as IrConstructor?
|
||||
withClass {
|
||||
conversionScope.withClass(this) {
|
||||
val primaryConstructor = klass.getPrimaryConstructorIfAny()
|
||||
val irPrimaryConstructor = primaryConstructor?.accept(this@Fir2IrVisitor, null) as IrConstructor?
|
||||
if (irPrimaryConstructor != null) {
|
||||
declarations += irPrimaryConstructor
|
||||
}
|
||||
@@ -271,19 +215,19 @@ class Fir2IrVisitor(
|
||||
annotations = klass.annotations.mapNotNull {
|
||||
it.accept(this@Fir2IrVisitor, null) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
if (irPrimaryConstructor != null) {
|
||||
declarationStorage.leaveScope(irPrimaryConstructor.descriptor)
|
||||
if (irPrimaryConstructor != null) {
|
||||
declarationStorage.leaveScope(irPrimaryConstructor.descriptor)
|
||||
}
|
||||
}
|
||||
declarationStorage.leaveScope(descriptor)
|
||||
}
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement {
|
||||
return declarationStorage.getIrClass(regularClass, setParentAndContent = false)
|
||||
.setParentByParentStack()
|
||||
.withParent {
|
||||
setClassContent(regularClass)
|
||||
}
|
||||
return conversionScope.withParent(
|
||||
applyParentFromStackTo(declarationStorage.getIrClass(regularClass, setParentAndContent = false))
|
||||
) {
|
||||
setClassContent(regularClass)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrFunction.addDispatchReceiverParameter(containingClass: IrClass) {
|
||||
@@ -294,11 +238,13 @@ class Fir2IrVisitor(
|
||||
startOffset, endOffset, thisOrigin, descriptor,
|
||||
thisType
|
||||
) { symbol ->
|
||||
IrValueParameterImpl(
|
||||
startOffset, endOffset, thisOrigin, symbol,
|
||||
Name.special("<this>"), -1, thisType,
|
||||
varargElementType = null, isCrossinline = false, isNoinline = false
|
||||
).setParentByParentStack()
|
||||
conversionScope.applyParentFromStackTo(
|
||||
IrValueParameterImpl(
|
||||
startOffset, endOffset, thisOrigin, symbol,
|
||||
Name.special("<this>"), -1, thisType,
|
||||
varargElementType = null, isCrossinline = false, isNoinline = false
|
||||
)
|
||||
)
|
||||
}.also { descriptor.bind(it) }
|
||||
}
|
||||
|
||||
@@ -307,10 +253,9 @@ class Fir2IrVisitor(
|
||||
firFunction: FirFunction<*>?,
|
||||
firOverriddenSymbol: FirNamedFunctionSymbol? = null
|
||||
): T {
|
||||
setParentByParentStack()
|
||||
withParent {
|
||||
conversionScope.withParent(this) {
|
||||
val firFunctionSymbol = (firFunction as? FirSimpleFunction)?.symbol
|
||||
val lastClass = classStack.lastOrNull()
|
||||
val lastClass = conversionScope.lastClass()
|
||||
val containingClass = if (firOverriddenSymbol == null || firFunctionSymbol == null) {
|
||||
lastClass
|
||||
} else {
|
||||
@@ -328,7 +273,7 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firFunction !is FirConstructor && containingClass != null) {
|
||||
if (firFunction !is FirConstructor && firFunction !is FirAnonymousFunction && containingClass != null) {
|
||||
addDispatchReceiverParameter(containingClass)
|
||||
}
|
||||
if (firFunction != null) {
|
||||
@@ -378,21 +323,21 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement {
|
||||
val irConstructor = declarationStorage.getIrConstructor(
|
||||
constructor, irParent = parentStack.last() as? IrClass
|
||||
constructor, irParent = conversionScope.lastClass()
|
||||
)
|
||||
return irConstructor.setParentByParentStack().withFunction {
|
||||
return conversionScope.withFunction(irConstructor) {
|
||||
setFunctionContent(irConstructor.descriptor, constructor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Any?): IrElement {
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val parent = parentStack.last() as IrClass
|
||||
val parent = conversionScope.lastClass()!!
|
||||
return anonymousInitializer.convertWithOffsets { startOffset, endOffset ->
|
||||
symbolTable.declareAnonymousInitializer(
|
||||
startOffset, endOffset, origin, parent.descriptor
|
||||
).apply {
|
||||
setParentByParentStack()
|
||||
this.parent = parent
|
||||
declarationStorage.enterScope(descriptor)
|
||||
body = anonymousInitializer.body!!.convertToIrBlockBody()
|
||||
declarationStorage.leaveScope(descriptor)
|
||||
@@ -435,17 +380,17 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement {
|
||||
val irFunction = declarationStorage.getIrFunction(
|
||||
simpleFunction, irParent = parentStack.last() as? IrClass
|
||||
simpleFunction, irParent = conversionScope.parent()
|
||||
)
|
||||
return irFunction.setParentByParentStack().withFunction {
|
||||
return conversionScope.withFunction(irFunction) {
|
||||
setFunctionContent(irFunction.descriptor, simpleFunction)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: Any?): IrElement {
|
||||
return anonymousFunction.convertWithOffsets { startOffset, endOffset ->
|
||||
val irFunction = declarationStorage.getIrLocalFunction(anonymousFunction)
|
||||
irFunction.setParentByParentStack().withFunction {
|
||||
val irFunction = declarationStorage.getIrLocalFunction(anonymousFunction, conversionScope.parent())
|
||||
conversionScope.withFunction(irFunction) {
|
||||
setFunctionContent(irFunction.descriptor, anonymousFunction)
|
||||
}
|
||||
|
||||
@@ -471,7 +416,7 @@ class Fir2IrVisitor(
|
||||
val irVariable = declarationStorage.createAndSaveIrVariable(
|
||||
variable, if (isNextVariable) IrDeclarationOrigin.FOR_LOOP_VARIABLE else null
|
||||
)
|
||||
return irVariable.setParentByParentStack().apply {
|
||||
return applyParentFromStackTo(irVariable).apply {
|
||||
if (initializer != null) {
|
||||
this.initializer = initializer.toIrExpression()
|
||||
}
|
||||
@@ -489,7 +434,7 @@ class Fir2IrVisitor(
|
||||
type: IrType? = null
|
||||
): IrField {
|
||||
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType()
|
||||
return symbolTable.declareField(
|
||||
val irField = symbolTable.declareField(
|
||||
startOffset, endOffset, origin, descriptor, inferredType
|
||||
) { symbol ->
|
||||
IrFieldImpl(
|
||||
@@ -499,7 +444,8 @@ class Fir2IrVisitor(
|
||||
isStatic = property.isStatic || parent !is IrClass,
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||
)
|
||||
}.setParentByParentStack().withParent {
|
||||
}
|
||||
return conversionScope.withParent(applyParentFromStackTo(irField)) {
|
||||
declarationStorage.enterScope(descriptor)
|
||||
val initializerExpression = firInitializerExpression?.toIrExpression()
|
||||
initializer = initializerExpression?.let { IrExpressionBodyImpl(it) }
|
||||
@@ -566,8 +512,8 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitProperty(property: FirProperty, data: Any?): IrElement {
|
||||
if (property.isLocal) return visitLocalVariable(property)
|
||||
val irProperty = declarationStorage.getIrProperty(property, irParent = parentStack.last() as? IrClass)
|
||||
return irProperty.setParentByParentStack().withProperty { setPropertyContent(irProperty.descriptor, property) }
|
||||
val irProperty = declarationStorage.getIrProperty(property, irParent = conversionScope.parent())
|
||||
return conversionScope.withProperty(irProperty) { setPropertyContent(irProperty.descriptor, property) }
|
||||
}
|
||||
|
||||
private fun IrFieldAccessExpression.setReceiver(declaration: IrDeclaration): IrFieldAccessExpression {
|
||||
@@ -587,15 +533,16 @@ class Fir2IrVisitor(
|
||||
isDefault: Boolean,
|
||||
isFakeOverride: Boolean
|
||||
) {
|
||||
withFunction {
|
||||
conversionScope.withFunction(this) {
|
||||
if (propertyAccessor != null) {
|
||||
with(declarationStorage) { this@setPropertyAccessorContent.enterLocalScope(propertyAccessor) }
|
||||
} else {
|
||||
declarationStorage.enterScope(descriptor)
|
||||
}
|
||||
applyParentFromStackTo(this)
|
||||
setFunctionContent(descriptor, propertyAccessor)
|
||||
if (isDefault || isFakeOverride) {
|
||||
withParent {
|
||||
conversionScope.withParent(this) {
|
||||
declarationStorage.enterScope(descriptor)
|
||||
val backingField = correspondingProperty.backingField
|
||||
val fieldSymbol = symbolTable.referenceField(correspondingProperty.descriptor)
|
||||
@@ -626,15 +573,7 @@ class Fir2IrVisitor(
|
||||
|
||||
|
||||
override fun visitReturnExpression(returnExpression: FirReturnExpression, data: Any?): IrElement {
|
||||
val firTarget = returnExpression.target.labeledElement
|
||||
var irTarget = functionStack.last()
|
||||
for (potentialTarget in functionStack.asReversed()) {
|
||||
// TODO: remove comparison by name
|
||||
if (potentialTarget.name == (firTarget as? FirSimpleFunction)?.name) {
|
||||
irTarget = potentialTarget
|
||||
break
|
||||
}
|
||||
}
|
||||
val irTarget = conversionScope.returnTarget(returnExpression)
|
||||
return returnExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
val result = returnExpression.result
|
||||
val descriptor = irTarget.descriptor
|
||||
@@ -690,7 +629,7 @@ class Fir2IrVisitor(
|
||||
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
||||
if (calleeReference is FirSuperReference) {
|
||||
if (typeRef !is FirComposedSuperTypeRef) {
|
||||
val dispatchReceiver = lastDispatchReceiverParameter()
|
||||
val dispatchReceiver = conversionScope.lastDispatchReceiverParameter()
|
||||
if (dispatchReceiver != null) {
|
||||
return@convertWithOffsets IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
||||
}
|
||||
@@ -910,14 +849,14 @@ class Fir2IrVisitor(
|
||||
}
|
||||
if (firObject != null) {
|
||||
val irObject = declarationStorage.getIrClass(firObject, setParentAndContent = false)
|
||||
if (irObject != classStack.lastOrNull()) {
|
||||
if (irObject != conversionScope.lastClass()) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dispatchReceiver = lastDispatchReceiverParameter()
|
||||
val dispatchReceiver = conversionScope.lastDispatchReceiverParameter()
|
||||
if (dispatchReceiver != null) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
||||
@@ -1046,7 +985,8 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): IrElement {
|
||||
val anonymousClass = declarationStorage.getIrAnonymousObject(anonymousObject).setParentByParentStack().withParent {
|
||||
val anonymousClass = declarationStorage.getIrAnonymousObject(anonymousObject)
|
||||
conversionScope.withParent(applyParentFromStackTo(anonymousClass)) {
|
||||
setClassContent(anonymousObject)
|
||||
}
|
||||
val anonymousClassType = anonymousClass.thisReceiver!!.type
|
||||
@@ -1159,8 +1099,7 @@ class Fir2IrVisitor(
|
||||
return when {
|
||||
subjectVariable != null -> subjectVariable.accept(this, null) as IrVariable
|
||||
subjectExpression != null -> {
|
||||
val irSubject = declarationStorage.declareTemporaryVariable(subjectExpression.toIrExpression(), "subject")
|
||||
irSubject.setParentByParentStack()
|
||||
applyParentFromStackTo(declarationStorage.declareTemporaryVariable(subjectExpression.toIrExpression(), "subject"))
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
@@ -1180,7 +1119,7 @@ class Fir2IrVisitor(
|
||||
is KtUnaryExpression -> IrStatementOrigin.EXCLEXCL
|
||||
else -> null
|
||||
}
|
||||
return subjectVariable.withSubject {
|
||||
return conversionScope.withSubject(subjectVariable) {
|
||||
whenExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
val irWhen = IrWhenImpl(
|
||||
startOffset, endOffset,
|
||||
@@ -1215,7 +1154,7 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitWhenSubjectExpression(whenSubjectExpression: FirWhenSubjectExpression, data: Any?): IrElement {
|
||||
val lastSubjectVariable = subjectVariableStack.last()
|
||||
val lastSubjectVariable = conversionScope.lastSubject()
|
||||
return whenSubjectExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetValueImpl(startOffset, endOffset, lastSubjectVariable.type, lastSubjectVariable.symbol)
|
||||
}
|
||||
@@ -1300,7 +1239,7 @@ class Fir2IrVisitor(
|
||||
override fun visitCatch(catch: FirCatch, data: Any?): IrElement {
|
||||
return catch.convertWithOffsets { startOffset, endOffset ->
|
||||
val catchParameter = declarationStorage.createAndSaveIrVariable(catch.parameter)
|
||||
IrCatchImpl(startOffset, endOffset, catchParameter.setParentByParentStack()).apply {
|
||||
IrCatchImpl(startOffset, endOffset, applyParentFromStackTo(catchParameter)).apply {
|
||||
result = catch.block.convertToIrExpressionOrBlock()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun box(): String {
|
||||
return Foo().doBar("OK")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class A {
|
||||
public val f : ()->String = {"OK"}
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Outer(val fn: (() -> String)?) {
|
||||
companion object {
|
||||
val ok = "Fail: Companion.ok"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
//KT-1061 Can't call function defined as a val
|
||||
|
||||
object X {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface A {
|
||||
val method : (() -> Unit)?
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface A {
|
||||
val method : () -> Unit?
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class A() {
|
||||
var x : Int = 0
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun foo(f: (Int) -> Int) = f(0)
|
||||
|
||||
class Outer {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !JVM_DEFAULT_MODE: enable
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: accessFromInlineLambda.kt
|
||||
import c.C
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: fromInlineLambdaInNestedClass.kt
|
||||
import b.*
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: inheritedProtectedCompanionAndOwnPrivateCompanion.kt
|
||||
import b.B
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: twoInheritedProtectedCompanions.kt
|
||||
import c.C
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: lambdaInPropertyInitializer.kt
|
||||
import c.C
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: twoInheritedProtectedCompanions.kt
|
||||
import c.C
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline fun <T> run(fn: () -> T) = fn()
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
class Outer {
|
||||
private companion object {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface T
|
||||
|
||||
object Foo {
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
object Test {
|
||||
fun ok() = "OK"
|
||||
val x = run { Test.ok() }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// !LANGUAGE: +NewInference
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
var global = 0
|
||||
|
||||
fun sideEffect() = global++
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
class A(val f: () -> Int) {
|
||||
constructor() : this({ 23 })
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class C(s: Int) {
|
||||
fun test() {
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: A.kt
|
||||
|
||||
package first
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -21,12 +21,11 @@ FILE fqName:<root> fileName:/initValInLambda.kt
|
||||
<R>: kotlin.Nothing
|
||||
$receiver: CONST Int type=kotlin.Int value=1
|
||||
block: FUN_EXPR type=kotlin.Function1<kotlin.Int, kotlin.Nothing> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($this:<root>.TestInitValInLambdaCalledOnce, $receiver:kotlin.Int) returnType:kotlin.Nothing
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestInitValInLambdaCalledOnce
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:kotlin.Int) returnType:kotlin.Nothing
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Unit origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestInitValInLambdaCalledOnce declared in <root>.TestInitValInLambdaCalledOnce.<anonymous>' type=<root>.TestInitValInLambdaCalledOnce origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestInitValInLambdaCalledOnce declared in <root>.TestInitValInLambdaCalledOnce' type=<root>.TestInitValInLambdaCalledOnce origin=null
|
||||
value: CONST Int type=kotlin.Int value=0
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
|
||||
@@ -88,8 +88,7 @@ FILE fqName:<root> fileName:/classLevelProperties.kt
|
||||
CALL 'public final fun lazy <T> (initializer: kotlin.Function0<T of kotlin.lazy>): kotlin.Lazy<T of kotlin.lazy> declared in kotlin' type=kotlin.Lazy<kotlin.Int> origin=null
|
||||
<T>: kotlin.Int
|
||||
initializer: FUN_EXPR type=kotlin.Function0<kotlin.Int> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($this:<root>.C) returnType:kotlin.Int
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Int declared in <root>.C.test7$delegate'
|
||||
CONST Int type=kotlin.Int value=42
|
||||
|
||||
@@ -42,8 +42,7 @@ FILE fqName:<root> fileName:/delegatedProperties.kt
|
||||
CALL 'public final fun lazy <T> (initializer: kotlin.Function0<T of kotlin.lazy>): kotlin.Lazy<T of kotlin.lazy> declared in kotlin' type=kotlin.Lazy<kotlin.Int> origin=null
|
||||
<T>: kotlin.Int
|
||||
initializer: FUN_EXPR type=kotlin.Function0<kotlin.Int> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($this:<root>.C) returnType:kotlin.Int
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.C
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Int
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Int declared in <root>.C.test2$delegate'
|
||||
CONST Int type=kotlin.Int value=42
|
||||
|
||||
@@ -28,8 +28,7 @@ FILE fqName:<root> fileName:/enumEntryAsReceiver.kt
|
||||
FIELD PROPERTY_BACKING_FIELD name:value type:kotlin.Function0<kotlin.String> visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.String> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($this:<root>.X.B) returnType:kotlin.String
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.X.B
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String declared in <root>.X.B.value'
|
||||
CALL 'public final fun <get-value2> (): kotlin.String declared in <root>.X.B' type=kotlin.String origin=GET_PROPERTY
|
||||
|
||||
+1
-2
@@ -47,8 +47,7 @@ FILE fqName:<root> fileName:/enumEntryReferenceFromEnumEntryClass.kt
|
||||
FIELD PROPERTY_BACKING_FIELD name:aLambda type:kotlin.Function0<kotlin.Unit> visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($this:<root>.MyEnum.Z) returnType:kotlin.Unit
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.MyEnum.Z
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null
|
||||
receiver: GET_VAR '<this>: <uninitialized parent>.<anonymous> declared in <no parent>.<anonymous>' type=<uninitialized parent>.<anonymous> origin=null
|
||||
|
||||
@@ -88,14 +88,13 @@ FILE fqName:<root> fileName:/objectReference.kt
|
||||
FIELD PROPERTY_BACKING_FIELD name:aLambda type:kotlin.Function0<kotlin.Unit> visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($this:<root>.Z) returnType:kotlin.Unit
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Z
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Z declared in <root>.Z.aLambda.<anonymous>' type=<root>.Z origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Z declared in <root>.Z' type=<root>.Z origin=null
|
||||
value: CONST Int type=kotlin.Int value=1
|
||||
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR '<this>: <root>.Z declared in <root>.Z.aLambda.<anonymous>' type=<root>.Z origin=null
|
||||
$this: GET_VAR '<this>: <root>.Z declared in <root>.Z' type=<root>.Z origin=null
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null
|
||||
receiver: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
|
||||
value: CONST Int type=kotlin.Int value=1
|
||||
|
||||
Reference in New Issue
Block a user