diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/annotations/firAnnotationUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/annotations/firAnnotationUtils.kt index d18258f0ff9..89882d0de92 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/annotations/firAnnotationUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/annotations/firAnnotationUtils.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.resolved -import org.jetbrains.kotlin.fir.declarations.utils.primaryConstructor +import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType @@ -42,7 +42,7 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSess if (annotation !is FirAnnotationCall) return emptyMap() val annotationCone = annotation.annotationTypeRef.coneType as? ConeClassLikeType ?: return emptyMap() - val annotationPrimaryCtor = (annotationCone.lookupTag.toSymbol(session)?.fir as? FirRegularClass)?.primaryConstructor + val annotationPrimaryCtor = (annotationCone.lookupTag.toSymbol(session)?.fir as? FirRegularClass)?.primaryConstructorIfAny(session)?.fir val annotationCtorParameterNames = annotationPrimaryCtor?.valueParameters?.map { it.name } val resultMap = mutableMapOf() diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt index f03bdedb546..c4e0835e380 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt @@ -75,7 +75,7 @@ object FirJvmRecordChecker : FirRegularClassChecker() { return } - declaration.primaryConstructor?.valueParameters?.let { params -> + declaration.primaryConstructorIfAny(context.session)?.valueParameterSymbols?.let { params -> if (params.isEmpty()) { reporter.reportOn(annotationSource, FirJvmErrors.JVM_RECORD_WITHOUT_PRIMARY_CONSTRUCTOR_PARAMETERS, context) return @@ -107,4 +107,4 @@ object FirJvmRecordChecker : FirRegularClassChecker() { } } } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt index abb7252e645..d757b2b6bce 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.hasValOrVar import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.hasValOrVar import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.utils.isData -import org.jetbrains.kotlin.fir.declarations.utils.primaryConstructor +import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() { override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { @@ -22,14 +22,14 @@ object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() { return } - val primaryConstructor = declaration.primaryConstructor + val primaryConstructor = declaration.primaryConstructorIfAny(context.session) if (primaryConstructor == null || primaryConstructor.source.let { it == null || it.kind is FirFakeSourceElementKind }) { reporter.reportOn(declaration.source, FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, context) return } - val valueParameters = primaryConstructor.valueParameters + val valueParameters = primaryConstructor.valueParameterSymbols if (valueParameters.isEmpty()) { reporter.reportOn(primaryConstructor.source, FirErrors.DATA_CLASS_WITHOUT_PARAMETERS, context) } @@ -37,7 +37,7 @@ object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() { if (parameter.isVararg) { reporter.reportOn(parameter.source, FirErrors.DATA_CLASS_VARARG_PARAMETER, context) } - if (!parameter.hasValOrVar) { + if (parameter.source?.hasValOrVar() != true) { reporter.reportOn(parameter.source, FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt index f94fcc30e96..5b21d928274 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMemberPropertiesChecker.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.cfa.util.PropertyInitializationInfo import org.jetbrains.kotlin.fir.analysis.cfa.util.PropertyInitializationInfoCollector import org.jetbrains.kotlin.fir.analysis.checkers.contains @@ -26,6 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.dfa.cfg.BlockExitNode import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph import org.jetbrains.kotlin.fir.resolve.dfa.cfg.NormalPath import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.lexer.KtTokens @@ -40,7 +42,13 @@ object FirMemberPropertiesChecker : FirClassChecker() { // If all member properties have its own initializer, we don't need to collect property initialization info at all. if (memberPropertySymbols.any { !it.hasInitializer }) { - collectPropertyInitialization(declaration, memberPropertySymbols, initializedInConstructor, initializedInInitOrOtherProperty) + collectPropertyInitialization( + declaration, + context.session, + memberPropertySymbols, + initializedInConstructor, + initializedInInitOrOtherProperty + ) } val deadEnds = declaration.collectDeadEndDeclarations() @@ -60,6 +68,7 @@ object FirMemberPropertiesChecker : FirClassChecker() { private fun collectPropertyInitialization( klass: FirClass, + session: FirSession, memberPropertySymbols: Set, initializedInConstructor: MutableMap, initializedInInitOrOtherProperty: MutableMap @@ -86,13 +95,13 @@ object FirMemberPropertiesChecker : FirClassChecker() { // To handle the delegated constructor call, we need a cache from constructor to (analyzed) property init info. val constructorToData = - mutableMapOf().withDefault { PropertyInitializationInfo.EMPTY } + mutableMapOf().withDefault { PropertyInitializationInfo.EMPTY } fun collectInfoFromGraph( graph: ControlFlowGraph, map: MutableMap, acc: (EventOccurrencesRange, EventOccurrencesRange) -> EventOccurrencesRange, - delegatedConstructor: FirConstructor? = null, + delegatedConstructor: FirConstructorSymbol? = null, ) { val delegatedInfo = delegatedConstructor?.let { constructorToData.getValue(it) } ?: PropertyInitializationInfo.EMPTY @@ -104,7 +113,7 @@ object FirMemberPropertiesChecker : FirClassChecker() { val info = delegatedInfo.plus(infoAtExitNode) if (graph.declaration is FirConstructor) { - constructorToData.putIfAbsent(graph.declaration as FirConstructor, info) + constructorToData.putIfAbsent((graph.declaration as FirConstructor).symbol, info) } for (propertySymbol in memberPropertySymbols) { @@ -122,13 +131,15 @@ object FirMemberPropertiesChecker : FirClassChecker() { } } - val constructorGraphs = klass.constructorsSortedByDelegation.mapNotNull { it.controlFlowGraphReference?.controlFlowGraph } + val constructorGraphs = klass.constructorsSortedByDelegation(session).mapNotNull { + it.resolvedControlFlowGraphReference?.controlFlowGraph + } for (graph in constructorGraphs) { collectInfoFromGraph( graph, initializedInConstructor, EventOccurrencesRange::or, - (graph.declaration as? FirConstructor)?.delegatedThisConstructor + (graph.declaration as? FirConstructor)?.symbol?.delegatedThisConstructor ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt index 99e73d17d1b..fd0d95edc22 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorSuperTypeChecker.kt @@ -13,10 +13,10 @@ import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn -import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.utils.isInterface -import org.jetbrains.kotlin.fir.declarations.utils.primaryConstructor +import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef @@ -36,12 +36,12 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() { return } - val primaryConstructor = declaration.primaryConstructor + val primaryConstructorSymbol = declaration.primaryConstructorIfAny(context.session) - if (primaryConstructor == null) { + if (primaryConstructorSymbol == null) { checkSupertypeInitializedWithoutPrimaryConstructor(declaration, reporter, context) } else { - checkSuperTypeNotInitialized(primaryConstructor, declaration, context, reporter) + checkSuperTypeNotInitialized(primaryConstructorSymbol, declaration, context, reporter) } } @@ -55,13 +55,13 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() { * ``` */ private fun checkSuperTypeNotInitialized( - primaryConstructor: FirConstructor, + primaryConstructorSymbol: FirConstructorSymbol, regularClass: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter ) { val containingClass = context.containingDeclarations.lastIsInstanceOrNull() - val delegatedConstructorCall = primaryConstructor.delegatedConstructor ?: return + val delegatedConstructorCall = primaryConstructorSymbol.resolvedDelegatedConstructorCall ?: return // No need to check implicit call to the constructor of `kotlin.Any`. val constructedTypeRef = delegatedConstructorCall.constructedTypeRef if (constructedTypeRef is FirImplicitAnyTypeRef) return diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index ed80fff8a1f..e66746b9ecd 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirValueParameter -import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries +import org.jetbrains.kotlin.fir.declarations.collectEnumEntries import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index 0f009be68c2..fca24e6ce9c 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -186,7 +186,7 @@ class FirElementSerializer private constructor( builder.typeTable = typeTableProto } - val representation = (klass as? FirRegularClass)?.getInlineClassUnderlyingParameter() + val representation = (klass as? FirRegularClass)?.getInlineClassUnderlyingParameter(session) if (representation != null) { builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.name) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 4a1a421b76e..906128f33a8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -561,7 +561,7 @@ fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction( // TODO: implement inlineClassRepresentation in FirRegularClass instead. fun Fir2IrComponents.computeInlineClassRepresentation(klass: FirRegularClass): InlineClassRepresentation? { if (!klass.isInline) return null - val parameter = klass.getInlineClassUnderlyingParameter() ?: error("Inline class has no underlying parameter: ${klass.render()}") + val parameter = klass.getInlineClassUnderlyingParameter(session) ?: error("Inline class has no underlying parameter: ${klass.render()}") val underlyingType = parameter.returnTypeRef.toIrType(typeConverter) return InlineClassRepresentation( parameter.name, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index e3db6a03674..a4845526f17 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.backend import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext -import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageVersionSettings @@ -19,7 +18,7 @@ import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic -import org.jetbrains.kotlin.fir.declarations.utils.primaryConstructor +import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.extensions.declarationGenerators import org.jetbrains.kotlin.fir.extensions.extensionService @@ -129,9 +128,9 @@ class Fir2IrConverter( anonymousObject: FirAnonymousObject, irClass: IrClass = classifierStorage.getCachedIrClass(anonymousObject)!! ): IrClass { - anonymousObject.primaryConstructor?.let { + anonymousObject.primaryConstructorIfAny(session)?.let { irClass.declarations += declarationStorage.createIrConstructor( - it, irClass, isLocal = true + it.fir, irClass, isLocal = true ) } val processedCallableNames = mutableSetOf() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 8414fcc571b..c3f7eea6f65 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -127,7 +127,7 @@ class Fir2IrVisitor( } else if (initializer is FirAnonymousObjectExpression) { // Otherwise, this is a default-ish enum entry, which doesn't need its own synthetic class. // During raw FIR building, we put the delegated constructor call inside an anonymous object. - val delegatedConstructor = initializer.anonymousObject.primaryConstructor?.delegatedConstructor + val delegatedConstructor = initializer.anonymousObject.primaryConstructorIfAny(session)?.fir?.delegatedConstructor if (delegatedConstructor != null) { with(memberGenerator) { irEnumEntry.initializerExpression = irFactory.createExpressionBody( diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index 0aa8db23ac8..8ed81bf1174 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries +import org.jetbrains.kotlin.fir.declarations.collectEnumEntries import org.jetbrains.kotlin.fir.declarations.utils.isStatic import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.expressions.FirExpression diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/InlineClassesUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/InlineClassesUtils.kt index c727fa80d7e..bee9f65977e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/InlineClassesUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/InlineClassesUtils.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.utils.isInline -import org.jetbrains.kotlin.fir.declarations.utils.primaryConstructor import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor import org.jetbrains.kotlin.fir.resolve.toSymbol @@ -31,9 +30,9 @@ internal fun ConeKotlinType.unsubstitutedUnderlyingTypeForInlineClass(session: F ?.toSymbol(session) as? FirRegularClassSymbol ?: return null symbol.ensureResolved(FirResolvePhase.STATUS) - return symbol.fir.getInlineClassUnderlyingParameter()?.returnTypeRef?.coneType + return symbol.fir.getInlineClassUnderlyingParameter(session)?.returnTypeRef?.coneType } // TODO: implement inlineClassRepresentation in FirRegularClass instead. -fun FirRegularClass.getInlineClassUnderlyingParameter(): FirValueParameter? = - if (isInline) primaryConstructor?.valueParameters?.singleOrNull() else null +fun FirRegularClass.getInlineClassUnderlyingParameter(session: FirSession): FirValueParameter? = + if (isInline) primaryConstructorIfAny(session)?.fir?.valueParameters?.singleOrNull() else null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt new file mode 100644 index 00000000000..58400b8c58f --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2021 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.declarations + +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol +import org.jetbrains.kotlin.utils.addToStdlib.runIf + +fun FirClass.constructors(session: FirSession): List { + val result = mutableListOf() + session.declaredMemberScope(this).processDeclaredConstructors { result += it } + return result +} + +fun FirClass.constructorsSortedByDelegation(session: FirSession): List { + return constructors(session).sortedWith(ConstructorDelegationComparator) +} + +fun FirClass.primaryConstructorIfAny(session: FirSession): FirConstructorSymbol? { + return constructors(session).find(FirConstructorSymbol::isPrimary) +} + +fun FirRegularClass.collectEnumEntries(): Collection { + assert(classKind == ClassKind.ENUM_CLASS) + return declarations.filterIsInstance() +} + +val FirConstructorSymbol.delegatedThisConstructor: FirConstructorSymbol? + get() = runIf(delegatedConstructorCallIsThis) { this.resolvedDelegatedConstructor } + + +private object ConstructorDelegationComparator : Comparator { + override fun compare(p0: FirConstructorSymbol?, p1: FirConstructorSymbol?): Int { + if (p0 == null && p1 == null) return 0 + if (p0 == null) return -1 + if (p1 == null) return 1 + if (p0.delegatedThisConstructor == p1) return 1 + if (p1.delegatedThisConstructor == p0) return -1 + // If neither is a delegation to each other, the order doesn't matter. + // Here we return 0 to preserve the original order. + return 0 + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt index c329bcbe846..6321b6fd531 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirEnumEntry import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.getSealedClassInheritors -import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries +import org.jetbrains.kotlin.fir.declarations.collectEnumEntries import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.LogicOperationKind.OR diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 945361eaaa0..74549cc1cf9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.declarations.utils.isInner -import org.jetbrains.kotlin.fir.declarations.utils.primaryConstructor +import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirWhenExpression @@ -406,7 +406,7 @@ class BodyResolveContext( ): T { val labelName = (owner as? FirRegularClass)?.name ?: if (owner.classKind == ClassKind.ENUM_ENTRY) { - owner.primaryConstructor?.symbol?.callableId?.className?.shortName() + owner.primaryConstructorIfAny(holder.session)?.callableId?.className?.shortName() } else null val type = owner.defaultType() val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt index 8dd686a4eae..38c91b999af 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt @@ -5,14 +5,10 @@ package org.jetbrains.kotlin.fir.declarations.utils -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.name.ClassId @@ -38,24 +34,6 @@ val FirClass.superConeTypes: List get() = superTypeRefs.mapNo val FirClass.anonymousInitializers: List get() = declarations.filterIsInstance() -val FirClass.constructors: List - get() = declarations.filterIsInstance() - -val FirConstructor.delegatedThisConstructor: FirConstructor? - get() = delegatedConstructor?.takeIf { it.isThis } - ?.let { (it.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirConstructor } - -val FirClass.constructorsSortedByDelegation: List - get() = constructors.sortedWith(ConstructorDelegationComparator) - -val FirClass.primaryConstructor: FirConstructor? - get() = constructors.find(FirConstructor::isPrimary) - -fun FirRegularClass.collectEnumEntries(): Collection { - assert(classKind == ClassKind.ENUM_CLASS) - return declarations.filterIsInstance() -} - val FirQualifiedAccess.referredPropertySymbol: FirPropertySymbol? get() { val reference = calleeReference as? FirResolvedNamedReference ?: return null @@ -69,16 +47,4 @@ inline val FirDeclaration.isFromLibrary: Boolean inline val FirDeclaration.isSynthetic: Boolean get() = origin == FirDeclarationOrigin.Synthetic -private object ConstructorDelegationComparator : Comparator { - override fun compare(p0: FirConstructor?, p1: FirConstructor?): Int { - if (p0 == null && p1 == null) return 0 - if (p0 == null) return -1 - if (p1 == null) return 1 - if (p0.delegatedThisConstructor == p1) return 1 - if (p1.delegatedThisConstructor == p0) return -1 - // If neither is a delegation to each other, the order doesn't matter. - // Here we return 0 to preserve the original order. - return 0 - } -} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt index 3e6e6d0a498..a3f861a094d 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt @@ -8,6 +8,9 @@ package org.jetbrains.kotlin.fir.symbols.impl import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall +import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.symbols.AccessorSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.ensureResolved @@ -30,6 +33,12 @@ sealed class FirFunctionSymbol( else -> null } as? FirResolvedContractDescription } + + val resolvedControlFlowGraphReference: FirControlFlowGraphReference? + get() { + ensureResolved(FirResolvePhase.BODY_RESOLVE) + return fir.controlFlowGraphReference + } } // ------------------------ named ------------------------ @@ -52,6 +61,25 @@ class FirConstructorSymbol( ) : FirFunctionSymbol(callableId) { val isPrimary: Boolean get() = fir.isPrimary + + val resolvedDelegatedConstructor: FirConstructorSymbol? + get() { + val delegatedConstructorCall = resolvedDelegatedConstructorCall ?: return null + return (delegatedConstructorCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol + } + + val resolvedDelegatedConstructorCall: FirDelegatedConstructorCall? + get() { + if (fir.delegatedConstructor == null) return null + ensureResolved(FirResolvePhase.BODY_RESOLVE) + return fir.delegatedConstructor + } + + val delegatedConstructorCallIsThis: Boolean + get() = fir.delegatedConstructor?.isThis ?: false + + val delegatedConstructorCallIsSuper: Boolean + get() = fir.delegatedConstructor?.isSuper ?: false } open class FirAccessorSymbol(