[FIR IR] support FirReceiverParameter

^KT-54417
This commit is contained in:
Dmitrii Gridin
2022-10-18 12:28:08 +02:00
committed by Space Team
parent 07aec4de8f
commit 33281770c7
9 changed files with 27 additions and 133 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 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.
*/
@@ -573,7 +573,8 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
thisOrigin: IrDeclarationOrigin,
startOffset: Int = this.startOffset,
endOffset: Int = this.endOffset,
name: Name = SpecialNames.THIS
name: Name = SpecialNames.THIS,
explicitReceiver: FirAnnotationContainer? = null,
): IrValueParameter {
return symbolTable.irFactory.createValueParameter(
startOffset, endOffset, thisOrigin, IrValueParameterSymbolImpl(),
@@ -582,6 +583,7 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
isHidden = false, isAssignable = false
).apply {
this.parent = this@declareThisReceiverParameter
explicitReceiver?.let { annotationGenerator.generate(this, it) }
}
}
@@ -307,7 +307,7 @@ class Fir2IrDeclarationStorage(
containingClass: IrClass?,
isStatic: Boolean,
// Can be not-null only for property accessors
parentPropertyReceiverType: FirTypeRef?
parentPropertyReceiver: FirReceiverParameter?
) {
val parent = this
if (function is FirSimpleFunction || function is FirConstructor) {
@@ -345,21 +345,22 @@ class Fir2IrDeclarationStorage(
with(classifierStorage) {
val thisOrigin = IrDeclarationOrigin.DEFINED
if (function !is FirConstructor) {
val receiverTypeRef =
if (function !is FirPropertyAccessor && function != null) function.receiverParameter?.type
else parentPropertyReceiverType
if (receiverTypeRef != null) {
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
val receiver: FirReceiverParameter? =
if (function !is FirPropertyAccessor && function != null) function.receiverParameter
else parentPropertyReceiver
if (receiver != null) {
extensionReceiverParameter = receiver.convertWithOffsets { startOffset, endOffset ->
val name = (function as? FirAnonymousFunction)?.label?.name?.let {
val suffix = it.takeIf(Name::isValidIdentifier) ?: "\$receiver"
Name.identifier("\$this\$$suffix")
} ?: SpecialNames.THIS
declareThisReceiverParameter(
thisType = receiverTypeRef.toIrType(typeContext),
thisType = receiver.type.toIrType(typeContext),
thisOrigin = thisOrigin,
startOffset = startOffset,
endOffset = endOffset,
name = name
name = name,
explicitReceiver = receiver,
)
}
}
@@ -401,10 +402,10 @@ class Fir2IrDeclarationStorage(
irParent: IrDeclarationParent?,
thisReceiverOwner: IrClass? = irParent as? IrClass,
isStatic: Boolean,
parentPropertyReceiverType: FirTypeRef? = null
parentPropertyReceiver: FirReceiverParameter? = null
): T {
setAndModifyParent(irParent)
declareParameters(function, thisReceiverOwner, isStatic, parentPropertyReceiverType)
declareParameters(function, thisReceiverOwner, isStatic, parentPropertyReceiver)
return this
}
@@ -729,7 +730,7 @@ class Fir2IrDeclarationStorage(
bindAndDeclareParameters(
propertyAccessor, irParent,
thisReceiverOwner, isStatic = irParent !is IrClass || propertyAccessor?.isStatic == true,
parentPropertyReceiverType = property.receiverParameter?.type
parentPropertyReceiver = property.receiverParameter,
)
leaveScope(this)
if (irParent != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2022 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.
*/
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
@@ -97,9 +98,9 @@ abstract class AbstractFir2IrLazyFunction<F : FirCallableDeclaration>(
(fir as? FirPropertyAccessor)?.propertySymbol?.fir?.hasAnnotation(JVM_STATIC_CLASS_ID) == true
}
protected fun createThisReceiverParameter(thisType: IrType): IrValueParameter {
protected fun createThisReceiverParameter(thisType: IrType, explicitReceiver: FirAnnotationContainer? = null): IrValueParameter {
declarationStorage.enterScope(this)
return declareThisReceiverParameter(thisType, origin).apply {
return declareThisReceiverParameter(thisType, origin, explicitReceiver = explicitReceiver).apply {
declarationStorage.leaveScope(this@AbstractFir2IrLazyFunction)
}
}
@@ -67,8 +67,8 @@ class Fir2IrLazyPropertyAccessor(
}
override var extensionReceiverParameter: IrValueParameter? by lazyVar(lock) {
firParentProperty.receiverParameter?.type?.let {
createThisReceiverParameter(it.toIrType(typeConverter, conversionTypeContext))
firParentProperty.receiverParameter?.let {
createThisReceiverParameter(it.type.toIrType(typeConverter, conversionTypeContext), it)
}
}
@@ -59,8 +59,8 @@ class Fir2IrLazySimpleFunction(
}
override var extensionReceiverParameter: IrValueParameter? by lazyVar(lock) {
fir.receiverParameter?.type?.let {
createThisReceiverParameter(it.toIrType(typeConverter))
fir.receiverParameter?.let {
createThisReceiverParameter(it.type.toIrType(typeConverter), it)
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Copyright 2010-2022 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.ir.util
@@ -1,65 +0,0 @@
FILE fqName:<root> fileName:/receiverParameterWithAnnotations.kt
CLASS ANNOTATION_CLASS name:Ann modality:OPEN visibility:public superTypes:[kotlin.Annotation]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Ann
CONSTRUCTOR visibility:public <> () returnType:<root>.Ann [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:Ann modality:OPEN visibility:public superTypes:[kotlin.Annotation]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String [fake_override] declared in kotlin.Annotation
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.A
CONSTRUCTOR visibility:public <> () returnType:<root>.A [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:f visibility:public modality:FINAL <> ($this:<root>.A, $receiver:@[Ann] kotlin.String) returnType:kotlin.String
$this: VALUE_PARAMETER name:<this> type:<root>.A
$receiver: VALUE_PARAMETER name:<this> type:@[Ann] kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun f (): kotlin.String declared in <root>.A'
CONST String type=kotlin.String value=""
PROPERTY name:p visibility:public modality:FINAL [val]
FUN name:<get-p> visibility:public modality:FINAL <> ($this:<root>.A, $receiver:@[Ann] kotlin.String?) returnType:kotlin.String
correspondingProperty: PROPERTY name:p visibility:public modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.A
$receiver: VALUE_PARAMETER name:<this> type:@[Ann] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-p> (): kotlin.String declared in <root>.A'
CONST String type=kotlin.String value=""
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:topLevelF visibility:public modality:FINAL <> ($receiver:@[Ann] kotlin.String?) returnType:kotlin.String
$receiver: VALUE_PARAMETER name:<this> type:@[Ann] kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun topLevelF (): kotlin.String declared in <root>'
CONST String type=kotlin.String value=""
PROPERTY name:topLevelP visibility:public modality:FINAL [val]
FUN name:<get-topLevelP> visibility:public modality:FINAL <> ($receiver:@[Ann] kotlin.String) returnType:kotlin.String
correspondingProperty: PROPERTY name:topLevelP visibility:public modality:FINAL [val]
$receiver: VALUE_PARAMETER name:<this> type:@[Ann] kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-topLevelP> (): kotlin.String declared in <root>'
CONST String type=kotlin.String value=""
@@ -1,35 +0,0 @@
open annotation class Ann : Annotation {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
}
class A {
constructor() /* primary */ {
super/*Any*/()
/* <init>() */
}
fun @Ann String.f(): String {
return ""
}
val @Ann String?.p: String
get(): String {
return ""
}
}
fun @Ann String?.topLevelF(): String {
return ""
}
val @Ann String.topLevelP: String
get(): String {
return ""
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
annotation class Ann
class A {