FIR2IR: fix handling constructors & their symbols (related also to local classes)
This commit is contained in:
+19
-15
@@ -423,22 +423,26 @@ class Fir2IrDeclarationStorage(
|
||||
irParent: IrDeclarationParent? = null,
|
||||
shouldLeaveScope: Boolean = false
|
||||
): IrConstructor {
|
||||
return constructorCache.getOrPut(constructor) {
|
||||
val descriptor = WrappedClassConstructorDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val isPrimary = constructor.isPrimary
|
||||
return constructor.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareConstructor(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||
IrConstructorImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
constructor.name, constructor.visibility,
|
||||
constructor.returnTypeRef.toIrType(session, this),
|
||||
isInline = false, isExternal = false, isPrimary = isPrimary, isExpect = false
|
||||
).bindAndDeclareParameters(constructor, descriptor, irParent, isStatic = true, shouldLeaveScope = shouldLeaveScope)
|
||||
}
|
||||
}
|
||||
|
||||
val cached = constructorCache[constructor]
|
||||
if (cached != null) {
|
||||
return if (shouldLeaveScope) cached else cached.enterLocalScope(constructor)
|
||||
}
|
||||
|
||||
val descriptor = WrappedClassConstructorDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val isPrimary = constructor.isPrimary
|
||||
val created = constructor.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareConstructor(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||
IrConstructorImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
constructor.name, constructor.visibility,
|
||||
constructor.returnTypeRef.toIrType(session, this),
|
||||
isInline = false, isExternal = false, isPrimary = isPrimary, isExpect = false
|
||||
).bindAndDeclareParameters(constructor, descriptor, irParent, isStatic = true, shouldLeaveScope = shouldLeaveScope)
|
||||
}
|
||||
}
|
||||
constructorCache[constructor] = created
|
||||
return created
|
||||
}
|
||||
|
||||
private fun createIrPropertyAccessor(
|
||||
|
||||
@@ -360,31 +360,17 @@ class Fir2IrVisitor(
|
||||
overriddenSymbols += overriddenSymbol
|
||||
}
|
||||
}
|
||||
body = firFunction?.body?.convertToIrBlockBody()
|
||||
if (this !is IrConstructor) {
|
||||
// Scope for primary constructor should be left after class declaration
|
||||
// Scope for secondary constructor should be left after delegating call
|
||||
declarationStorage.leaveScope(descriptor)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement {
|
||||
val irConstructor = declarationStorage.getIrConstructor(
|
||||
constructor, irParent = parentStack.last() as? IrClass
|
||||
)
|
||||
return irConstructor.setParentByParentStack().withFunction {
|
||||
setFunctionContent(irConstructor.descriptor, constructor)
|
||||
}.withParent {
|
||||
if (!parentAsClass.isAnnotationClass) {
|
||||
val body = this.body as IrBlockBody? ?: IrBlockBodyImpl(startOffset, endOffset)
|
||||
val delegatedConstructor = constructor.delegatedConstructor
|
||||
var body = firFunction?.body?.convertToIrBlockBody()
|
||||
if (firFunction is FirConstructor && this is IrConstructor && !parentAsClass.isAnnotationClass) {
|
||||
if (body == null) {
|
||||
body = IrBlockBodyImpl(startOffset, endOffset)
|
||||
}
|
||||
val delegatedConstructor = firFunction.delegatedConstructor
|
||||
if (delegatedConstructor != null) {
|
||||
val irDelegatingConstructorCall = delegatedConstructor.toIrDelegatingConstructorCall()
|
||||
body.statements += irDelegatingConstructorCall ?: delegatedConstructor.convertWithOffsets { startOffset, endOffset ->
|
||||
IrErrorCallExpressionImpl(
|
||||
startOffset, endOffset, irConstructor.returnType, "Cannot find delegated constructor call"
|
||||
startOffset, endOffset, returnType, "Cannot find delegated constructor call"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -397,11 +383,24 @@ class Fir2IrVisitor(
|
||||
if (body.statements.isNotEmpty()) {
|
||||
this.body = body
|
||||
}
|
||||
} else if (this !is IrConstructor) {
|
||||
this.body = body
|
||||
}
|
||||
if (!constructor.isPrimary) {
|
||||
declarationStorage.leaveScope(irConstructor.descriptor)
|
||||
if (this !is IrConstructor || !this.isPrimary) {
|
||||
// Scope for primary constructor should be left after class declaration
|
||||
declarationStorage.leaveScope(descriptor)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement {
|
||||
val irConstructor = declarationStorage.getIrConstructor(
|
||||
constructor, irParent = parentStack.last() as? IrClass
|
||||
)
|
||||
return irConstructor.setParentByParentStack().withFunction {
|
||||
setFunctionContent(irConstructor.descriptor, constructor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Any?): IrElement {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
FILE fqName:<root> fileName:/localClasses.kt
|
||||
FUN name:outer visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
CLASS CLASS name:LocalClass modality:FINAL visibility:local superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.outer.LocalClass
|
||||
CONSTRUCTOR visibility:public <> () returnType:IrErrorType [primary]
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:LocalClass modality:FINAL visibility:local superTypes:[kotlin.Any]'
|
||||
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.outer.LocalClass) returnType:kotlin.Unit
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.outer.LocalClass
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: foo>#' type=IrErrorType
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun outer() {
|
||||
class LocalClass {
|
||||
fun foo() {}
|
||||
|
||||
Reference in New Issue
Block a user