in compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt [1842:1998]
override fun visitClassOrObject(classOrObject: KtClassOrObject, data: FirElement?): FirElement {
val isLocalWithinParent = classOrObject.parent !is KtClassBody && classOrObject.isLocal
val classIsExpect = classOrObject.hasExpectModifier() || context.containerIsExpect
val sourceElement = classOrObject.toFirSourceElement()
return withChildClassName(
classOrObject.nameAsSafeName,
isExpect = classIsExpect,
forceLocalContext = isLocalWithinParent,
) {
val classSymbol = FirRegularClassSymbol(context.currentClassId)
withContainerSymbol(classSymbol) {
val isLocal = context.inLocalContext
val classKind = when (classOrObject) {
is KtObjectDeclaration -> ClassKind.OBJECT
is KtClass -> when {
classOrObject.isInterface() -> ClassKind.INTERFACE
classOrObject.isEnum() -> ClassKind.ENUM_CLASS
classOrObject.isAnnotation() -> ClassKind.ANNOTATION_CLASS
else -> ClassKind.CLASS
}
else -> throw AssertionError("Unexpected class or object: ${classOrObject.text}")
}
val status = FirDeclarationStatusImpl(
if (isLocal) Visibilities.Local else classOrObject.getVisibility(publicByDefault = true),
classOrObject.modality,
).apply {
isExpect = classIsExpect
isActual = classOrObject.hasActualModifier()
isInner = classOrObject.hasInnerModifier() && classOrObject.parent.parent !is KtScript
isCompanion = (classOrObject as? KtObjectDeclaration)?.isCompanion() == true
isData = classOrObject.hasModifier(DATA_KEYWORD)
isInline = classOrObject.hasModifier(INLINE_KEYWORD)
isValue = classOrObject.hasModifier(VALUE_KEYWORD)
isFun = classOrObject.hasModifier(FUN_KEYWORD)
isExternal = classOrObject.hasModifier(EXTERNAL_KEYWORD)
}
val firTypeParameters = classOrObject.convertTypeParameters(classSymbol)
withCapturedTypeParameters(
status = status.isInner || isLocal,
declarationSource = sourceElement,
currentFirTypeParameters = firTypeParameters,
) {
var delegatedFieldsMap: Map<Int, FirFieldSymbol>?
buildRegularClass {
source = sourceElement
moduleData = baseModuleData
origin = FirDeclarationOrigin.Source
name = classOrObject.nameAsSafeName
this.status = status
this.classKind = classKind
scopeProvider = baseScopeProvider
symbol = classSymbol
typeParameters += firTypeParameters
classOrObject.extractAnnotationsTo(this)
context.appendOuterTypeParameters(ignoreLastLevel = true, typeParameters)
val delegatedSelfType = classOrObject.toDelegatedSelfType(this)
registerSelfType(delegatedSelfType)
val (delegatedSuperType, extractedDelegatedFieldsMap) = classOrObject.extractSuperTypeListEntriesTo(
this,
delegatedSelfType,
null,
classKind,
typeParameters,
containingClassIsExpectClass = classIsExpect
)
delegatedFieldsMap = extractedDelegatedFieldsMap
val primaryConstructor = classOrObject.primaryConstructor
val firPrimaryConstructor = declarations.firstOrNull { it is FirConstructor } as? FirConstructor
if (primaryConstructor != null && firPrimaryConstructor != null) {
primaryConstructor.valueParameters.zip(
firPrimaryConstructor.valueParameters
).forEach { (ktParameter, firParameter) ->
if (ktParameter.hasValOrVar()) {
addDeclaration(ktParameter.toFirProperty(firParameter))
}
}
}
for (declaration in classOrObject.declarations) {
addDeclaration(
declaration.toFirDeclaration(
delegatedSuperType,
delegatedSelfType,
classOrObject,
this,
typeParameters
)
)
}
for (danglingModifier in classOrObject.body?.danglingModifierLists ?: emptyList()) {
addDeclaration(
buildErrorNonLocalDeclarationForDanglingModifierList(danglingModifier).apply {
containingClassAttr = currentDispatchReceiverType()?.lookupTag
}
)
}
if (classOrObject.hasModifier(DATA_KEYWORD) && firPrimaryConstructor != null) {
val zippedParameters =
classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() } zip declarations.filterIsInstance<FirProperty>()
DataClassMembersGenerator(
classOrObject.primaryConstructor ?: classOrObject,
this,
firPrimaryConstructor,
zippedParameters,
context.packageFqName,
context.className,
addValueParameterAnnotations = {
withContainerSymbol(symbol) {
addAnnotationsFrom(
it as KtParameter,
isFromPrimaryConstructor = true,
)
}
},
).generate()
}
if (classOrObject.hasModifier(ENUM_KEYWORD)) {
generateValuesFunction(
baseModuleData,
context.packageFqName,
context.className,
classIsExpect
)
generateValueOfFunction(
baseModuleData, context.packageFqName, context.className,
classIsExpect
)
generateEntriesGetter(
baseModuleData, context.packageFqName, context.className,
classIsExpect
)
}
initCompanionObjectSymbolAttr()
contextParameters.addContextParameters(classOrObject.modifierList?.contextParameterLists.orEmpty(), classSymbol)
}.also {
it.delegateFieldsMap = delegatedFieldsMap
}
}.also {
classOrObject.fillDanglingConstraintsTo(it)
}
}
}.also {
if (classOrObject.parent is KtClassBody) {
it.initContainingClassForLocalAttr()
}
it.initContainingScriptOrReplAttr()
}
}