[FIR] Properly collect constructors from class in presence of plugins
This commit is contained in:
committed by
TeamCityServer
parent
6712191538
commit
af6d6ec2b9
+2
-2
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
|||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.resolved
|
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.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
@@ -42,7 +42,7 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSess
|
|||||||
if (annotation !is FirAnnotationCall) return emptyMap()
|
if (annotation !is FirAnnotationCall) return emptyMap()
|
||||||
val annotationCone = annotation.annotationTypeRef.coneType as? ConeClassLikeType ?: 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 annotationCtorParameterNames = annotationPrimaryCtor?.valueParameters?.map { it.name }
|
||||||
|
|
||||||
val resultMap = mutableMapOf<String, FirExpression>()
|
val resultMap = mutableMapOf<String, FirExpression>()
|
||||||
|
|||||||
+1
-1
@@ -75,7 +75,7 @@ object FirJvmRecordChecker : FirRegularClassChecker() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
declaration.primaryConstructor?.valueParameters?.let { params ->
|
declaration.primaryConstructorIfAny(context.session)?.valueParameterSymbols?.let { params ->
|
||||||
if (params.isEmpty()) {
|
if (params.isEmpty()) {
|
||||||
reporter.reportOn(annotationSource, FirJvmErrors.JVM_RECORD_WITHOUT_PRIMARY_CONSTRUCTOR_PARAMETERS, context)
|
reporter.reportOn(annotationSource, FirJvmErrors.JVM_RECORD_WITHOUT_PRIMARY_CONSTRUCTOR_PARAMETERS, context)
|
||||||
return
|
return
|
||||||
|
|||||||
+5
-5
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
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.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
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.analysis.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isData
|
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() {
|
object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() {
|
||||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -22,14 +22,14 @@ object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val primaryConstructor = declaration.primaryConstructor
|
val primaryConstructor = declaration.primaryConstructorIfAny(context.session)
|
||||||
|
|
||||||
if (primaryConstructor == null || primaryConstructor.source.let { it == null || it.kind is FirFakeSourceElementKind }) {
|
if (primaryConstructor == null || primaryConstructor.source.let { it == null || it.kind is FirFakeSourceElementKind }) {
|
||||||
reporter.reportOn(declaration.source, FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, context)
|
reporter.reportOn(declaration.source, FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val valueParameters = primaryConstructor.valueParameters
|
val valueParameters = primaryConstructor.valueParameterSymbols
|
||||||
if (valueParameters.isEmpty()) {
|
if (valueParameters.isEmpty()) {
|
||||||
reporter.reportOn(primaryConstructor.source, FirErrors.DATA_CLASS_WITHOUT_PARAMETERS, context)
|
reporter.reportOn(primaryConstructor.source, FirErrors.DATA_CLASS_WITHOUT_PARAMETERS, context)
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() {
|
|||||||
if (parameter.isVararg) {
|
if (parameter.isVararg) {
|
||||||
reporter.reportOn(parameter.source, FirErrors.DATA_CLASS_VARARG_PARAMETER, context)
|
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)
|
reporter.reportOn(parameter.source, FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-6
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
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.PropertyInitializationInfo
|
||||||
import org.jetbrains.kotlin.fir.analysis.cfa.util.PropertyInitializationInfoCollector
|
import org.jetbrains.kotlin.fir.analysis.cfa.util.PropertyInitializationInfoCollector
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.contains
|
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.ControlFlowGraph
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.NormalPath
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.NormalPath
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
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.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
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 all member properties have its own initializer, we don't need to collect property initialization info at all.
|
||||||
if (memberPropertySymbols.any { !it.hasInitializer }) {
|
if (memberPropertySymbols.any { !it.hasInitializer }) {
|
||||||
collectPropertyInitialization(declaration, memberPropertySymbols, initializedInConstructor, initializedInInitOrOtherProperty)
|
collectPropertyInitialization(
|
||||||
|
declaration,
|
||||||
|
context.session,
|
||||||
|
memberPropertySymbols,
|
||||||
|
initializedInConstructor,
|
||||||
|
initializedInInitOrOtherProperty
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val deadEnds = declaration.collectDeadEndDeclarations()
|
val deadEnds = declaration.collectDeadEndDeclarations()
|
||||||
@@ -60,6 +68,7 @@ object FirMemberPropertiesChecker : FirClassChecker() {
|
|||||||
|
|
||||||
private fun collectPropertyInitialization(
|
private fun collectPropertyInitialization(
|
||||||
klass: FirClass,
|
klass: FirClass,
|
||||||
|
session: FirSession,
|
||||||
memberPropertySymbols: Set<FirPropertySymbol>,
|
memberPropertySymbols: Set<FirPropertySymbol>,
|
||||||
initializedInConstructor: MutableMap<FirPropertySymbol, EventOccurrencesRange>,
|
initializedInConstructor: MutableMap<FirPropertySymbol, EventOccurrencesRange>,
|
||||||
initializedInInitOrOtherProperty: MutableMap<FirPropertySymbol, EventOccurrencesRange>
|
initializedInInitOrOtherProperty: MutableMap<FirPropertySymbol, EventOccurrencesRange>
|
||||||
@@ -86,13 +95,13 @@ object FirMemberPropertiesChecker : FirClassChecker() {
|
|||||||
|
|
||||||
// To handle the delegated constructor call, we need a cache from constructor to (analyzed) property init info.
|
// To handle the delegated constructor call, we need a cache from constructor to (analyzed) property init info.
|
||||||
val constructorToData =
|
val constructorToData =
|
||||||
mutableMapOf<FirConstructor, PropertyInitializationInfo>().withDefault { PropertyInitializationInfo.EMPTY }
|
mutableMapOf<FirConstructorSymbol, PropertyInitializationInfo>().withDefault { PropertyInitializationInfo.EMPTY }
|
||||||
|
|
||||||
fun collectInfoFromGraph(
|
fun collectInfoFromGraph(
|
||||||
graph: ControlFlowGraph,
|
graph: ControlFlowGraph,
|
||||||
map: MutableMap<FirPropertySymbol, EventOccurrencesRange>,
|
map: MutableMap<FirPropertySymbol, EventOccurrencesRange>,
|
||||||
acc: (EventOccurrencesRange, EventOccurrencesRange) -> EventOccurrencesRange,
|
acc: (EventOccurrencesRange, EventOccurrencesRange) -> EventOccurrencesRange,
|
||||||
delegatedConstructor: FirConstructor? = null,
|
delegatedConstructor: FirConstructorSymbol? = null,
|
||||||
) {
|
) {
|
||||||
val delegatedInfo = delegatedConstructor?.let { constructorToData.getValue(it) } ?: PropertyInitializationInfo.EMPTY
|
val delegatedInfo = delegatedConstructor?.let { constructorToData.getValue(it) } ?: PropertyInitializationInfo.EMPTY
|
||||||
|
|
||||||
@@ -104,7 +113,7 @@ object FirMemberPropertiesChecker : FirClassChecker() {
|
|||||||
val info = delegatedInfo.plus(infoAtExitNode)
|
val info = delegatedInfo.plus(infoAtExitNode)
|
||||||
|
|
||||||
if (graph.declaration is FirConstructor) {
|
if (graph.declaration is FirConstructor) {
|
||||||
constructorToData.putIfAbsent(graph.declaration as FirConstructor, info)
|
constructorToData.putIfAbsent((graph.declaration as FirConstructor).symbol, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (propertySymbol in memberPropertySymbols) {
|
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) {
|
for (graph in constructorGraphs) {
|
||||||
collectInfoFromGraph(
|
collectInfoFromGraph(
|
||||||
graph,
|
graph,
|
||||||
initializedInConstructor,
|
initializedInConstructor,
|
||||||
EventOccurrencesRange::or,
|
EventOccurrencesRange::or,
|
||||||
(graph.declaration as? FirConstructor)?.delegatedThisConstructor
|
(graph.declaration as? FirConstructor)?.symbol?.delegatedThisConstructor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -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.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
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.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
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.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef
|
||||||
@@ -36,12 +36,12 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val primaryConstructor = declaration.primaryConstructor
|
val primaryConstructorSymbol = declaration.primaryConstructorIfAny(context.session)
|
||||||
|
|
||||||
if (primaryConstructor == null) {
|
if (primaryConstructorSymbol == null) {
|
||||||
checkSupertypeInitializedWithoutPrimaryConstructor(declaration, reporter, context)
|
checkSupertypeInitializedWithoutPrimaryConstructor(declaration, reporter, context)
|
||||||
} else {
|
} else {
|
||||||
checkSuperTypeNotInitialized(primaryConstructor, declaration, context, reporter)
|
checkSuperTypeNotInitialized(primaryConstructorSymbol, declaration, context, reporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +55,13 @@ object FirPrimaryConstructorSuperTypeChecker : FirRegularClassChecker() {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
private fun checkSuperTypeNotInitialized(
|
private fun checkSuperTypeNotInitialized(
|
||||||
primaryConstructor: FirConstructor,
|
primaryConstructorSymbol: FirConstructorSymbol,
|
||||||
regularClass: FirRegularClass,
|
regularClass: FirRegularClass,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
) {
|
) {
|
||||||
val containingClass = context.containingDeclarations.lastIsInstanceOrNull<FirRegularClass>()
|
val containingClass = context.containingDeclarations.lastIsInstanceOrNull<FirRegularClass>()
|
||||||
val delegatedConstructorCall = primaryConstructor.delegatedConstructor ?: return
|
val delegatedConstructorCall = primaryConstructorSymbol.resolvedDelegatedConstructorCall ?: return
|
||||||
// No need to check implicit call to the constructor of `kotlin.Any`.
|
// No need to check implicit call to the constructor of `kotlin.Any`.
|
||||||
val constructedTypeRef = delegatedConstructorCall.constructedTypeRef
|
val constructedTypeRef = delegatedConstructorCall.constructedTypeRef
|
||||||
if (constructedTypeRef is FirImplicitAnyTypeRef) return
|
if (constructedTypeRef is FirImplicitAnyTypeRef) return
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
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.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
|||||||
+1
-1
@@ -186,7 +186,7 @@ class FirElementSerializer private constructor(
|
|||||||
builder.typeTable = typeTableProto
|
builder.typeTable = typeTableProto
|
||||||
}
|
}
|
||||||
|
|
||||||
val representation = (klass as? FirRegularClass)?.getInlineClassUnderlyingParameter()
|
val representation = (klass as? FirRegularClass)?.getInlineClassUnderlyingParameter(session)
|
||||||
if (representation != null) {
|
if (representation != null) {
|
||||||
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.name)
|
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.name)
|
||||||
|
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ fun Fir2IrComponents.createTemporaryVariableForSafeCallConstruction(
|
|||||||
// TODO: implement inlineClassRepresentation in FirRegularClass instead.
|
// TODO: implement inlineClassRepresentation in FirRegularClass instead.
|
||||||
fun Fir2IrComponents.computeInlineClassRepresentation(klass: FirRegularClass): InlineClassRepresentation<IrSimpleType>? {
|
fun Fir2IrComponents.computeInlineClassRepresentation(klass: FirRegularClass): InlineClassRepresentation<IrSimpleType>? {
|
||||||
if (!klass.isInline) return null
|
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)
|
val underlyingType = parameter.returnTypeRef.toIrType(typeConverter)
|
||||||
return InlineClassRepresentation(
|
return InlineClassRepresentation(
|
||||||
parameter.name,
|
parameter.name,
|
||||||
|
|||||||
@@ -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.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
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.backend.common.ir.BuiltinSymbolsBase
|
||||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
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.descriptors.FirModuleDescriptor
|
||||||
import org.jetbrains.kotlin.fir.extensions.declarationGenerators
|
import org.jetbrains.kotlin.fir.extensions.declarationGenerators
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
@@ -129,9 +128,9 @@ class Fir2IrConverter(
|
|||||||
anonymousObject: FirAnonymousObject,
|
anonymousObject: FirAnonymousObject,
|
||||||
irClass: IrClass = classifierStorage.getCachedIrClass(anonymousObject)!!
|
irClass: IrClass = classifierStorage.getCachedIrClass(anonymousObject)!!
|
||||||
): IrClass {
|
): IrClass {
|
||||||
anonymousObject.primaryConstructor?.let {
|
anonymousObject.primaryConstructorIfAny(session)?.let {
|
||||||
irClass.declarations += declarationStorage.createIrConstructor(
|
irClass.declarations += declarationStorage.createIrConstructor(
|
||||||
it, irClass, isLocal = true
|
it.fir, irClass, isLocal = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val processedCallableNames = mutableSetOf<Name>()
|
val processedCallableNames = mutableSetOf<Name>()
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class Fir2IrVisitor(
|
|||||||
} else if (initializer is FirAnonymousObjectExpression) {
|
} else if (initializer is FirAnonymousObjectExpression) {
|
||||||
// Otherwise, this is a default-ish enum entry, which doesn't need its own synthetic class.
|
// 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.
|
// 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) {
|
if (delegatedConstructor != null) {
|
||||||
with(memberGenerator) {
|
with(memberGenerator) {
|
||||||
irEnumEntry.initializerExpression = irFactory.createExpressionBody(
|
irEnumEntry.initializerExpression = irFactory.createExpressionBody(
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
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.isStatic
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
|||||||
+3
-4
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.declarations
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
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.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
@@ -31,9 +30,9 @@ internal fun ConeKotlinType.unsubstitutedUnderlyingTypeForInlineClass(session: F
|
|||||||
?.toSymbol(session) as? FirRegularClassSymbol
|
?.toSymbol(session) as? FirRegularClassSymbol
|
||||||
?: return null
|
?: return null
|
||||||
symbol.ensureResolved(FirResolvePhase.STATUS)
|
symbol.ensureResolved(FirResolvePhase.STATUS)
|
||||||
return symbol.fir.getInlineClassUnderlyingParameter()?.returnTypeRef?.coneType
|
return symbol.fir.getInlineClassUnderlyingParameter(session)?.returnTypeRef?.coneType
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement inlineClassRepresentation in FirRegularClass instead.
|
// TODO: implement inlineClassRepresentation in FirRegularClass instead.
|
||||||
fun FirRegularClass.getInlineClassUnderlyingParameter(): FirValueParameter? =
|
fun FirRegularClass.getInlineClassUnderlyingParameter(session: FirSession): FirValueParameter? =
|
||||||
if (isInline) primaryConstructor?.valueParameters?.singleOrNull() else null
|
if (isInline) primaryConstructorIfAny(session)?.fir?.valueParameters?.singleOrNull() else null
|
||||||
|
|||||||
@@ -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<FirConstructorSymbol> {
|
||||||
|
val result = mutableListOf<FirConstructorSymbol>()
|
||||||
|
session.declaredMemberScope(this).processDeclaredConstructors { result += it }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirClass.constructorsSortedByDelegation(session: FirSession): List<FirConstructorSymbol> {
|
||||||
|
return constructors(session).sortedWith(ConstructorDelegationComparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirClass.primaryConstructorIfAny(session: FirSession): FirConstructorSymbol? {
|
||||||
|
return constructors(session).find(FirConstructorSymbol::isPrimary)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirRegularClass.collectEnumEntries(): Collection<FirEnumEntry> {
|
||||||
|
assert(classKind == ClassKind.ENUM_CLASS)
|
||||||
|
return declarations.filterIsInstance<FirEnumEntry>()
|
||||||
|
}
|
||||||
|
|
||||||
|
val FirConstructorSymbol.delegatedThisConstructor: FirConstructorSymbol?
|
||||||
|
get() = runIf(delegatedConstructorCallIsThis) { this.resolvedDelegatedConstructor }
|
||||||
|
|
||||||
|
|
||||||
|
private object ConstructorDelegationComparator : Comparator<FirConstructorSymbol> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.getSealedClassInheritors
|
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.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.LogicOperationKind.OR
|
import org.jetbrains.kotlin.fir.expressions.LogicOperationKind.OR
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
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.FirCallableReferenceAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||||
@@ -406,7 +406,7 @@ class BodyResolveContext(
|
|||||||
): T {
|
): T {
|
||||||
val labelName = (owner as? FirRegularClass)?.name
|
val labelName = (owner as? FirRegularClass)?.name
|
||||||
?: if (owner.classKind == ClassKind.ENUM_ENTRY) {
|
?: if (owner.classKind == ClassKind.ENUM_ENTRY) {
|
||||||
owner.primaryConstructor?.symbol?.callableId?.className?.shortName()
|
owner.primaryConstructorIfAny(holder.session)?.callableId?.className?.shortName()
|
||||||
} else null
|
} else null
|
||||||
val type = owner.defaultType()
|
val type = owner.defaultType()
|
||||||
val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type)
|
val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type)
|
||||||
|
|||||||
+1
-35
@@ -5,14 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.declarations.utils
|
package org.jetbrains.kotlin.fir.declarations.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
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.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -38,24 +34,6 @@ val FirClass.superConeTypes: List<ConeClassLikeType> get() = superTypeRefs.mapNo
|
|||||||
val FirClass.anonymousInitializers: List<FirAnonymousInitializer>
|
val FirClass.anonymousInitializers: List<FirAnonymousInitializer>
|
||||||
get() = declarations.filterIsInstance<FirAnonymousInitializer>()
|
get() = declarations.filterIsInstance<FirAnonymousInitializer>()
|
||||||
|
|
||||||
val FirClass.constructors: List<FirConstructor>
|
|
||||||
get() = declarations.filterIsInstance<FirConstructor>()
|
|
||||||
|
|
||||||
val FirConstructor.delegatedThisConstructor: FirConstructor?
|
|
||||||
get() = delegatedConstructor?.takeIf { it.isThis }
|
|
||||||
?.let { (it.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirConstructor }
|
|
||||||
|
|
||||||
val FirClass.constructorsSortedByDelegation: List<FirConstructor>
|
|
||||||
get() = constructors.sortedWith(ConstructorDelegationComparator)
|
|
||||||
|
|
||||||
val FirClass.primaryConstructor: FirConstructor?
|
|
||||||
get() = constructors.find(FirConstructor::isPrimary)
|
|
||||||
|
|
||||||
fun FirRegularClass.collectEnumEntries(): Collection<FirEnumEntry> {
|
|
||||||
assert(classKind == ClassKind.ENUM_CLASS)
|
|
||||||
return declarations.filterIsInstance<FirEnumEntry>()
|
|
||||||
}
|
|
||||||
|
|
||||||
val FirQualifiedAccess.referredPropertySymbol: FirPropertySymbol?
|
val FirQualifiedAccess.referredPropertySymbol: FirPropertySymbol?
|
||||||
get() {
|
get() {
|
||||||
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||||
@@ -69,16 +47,4 @@ inline val FirDeclaration.isFromLibrary: Boolean
|
|||||||
inline val FirDeclaration.isSynthetic: Boolean
|
inline val FirDeclaration.isSynthetic: Boolean
|
||||||
get() = origin == FirDeclarationOrigin.Synthetic
|
get() = origin == FirDeclarationOrigin.Synthetic
|
||||||
|
|
||||||
private object ConstructorDelegationComparator : Comparator<FirConstructor> {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ package org.jetbrains.kotlin.fir.symbols.impl
|
|||||||
import org.jetbrains.kotlin.fir.FirLabel
|
import org.jetbrains.kotlin.fir.FirLabel
|
||||||
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
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.AccessorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||||
@@ -30,6 +33,12 @@ sealed class FirFunctionSymbol<D : FirFunction>(
|
|||||||
else -> null
|
else -> null
|
||||||
} as? FirResolvedContractDescription
|
} as? FirResolvedContractDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val resolvedControlFlowGraphReference: FirControlFlowGraphReference?
|
||||||
|
get() {
|
||||||
|
ensureResolved(FirResolvePhase.BODY_RESOLVE)
|
||||||
|
return fir.controlFlowGraphReference
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------ named ------------------------
|
// ------------------------ named ------------------------
|
||||||
@@ -52,6 +61,25 @@ class FirConstructorSymbol(
|
|||||||
) : FirFunctionSymbol<FirConstructor>(callableId) {
|
) : FirFunctionSymbol<FirConstructor>(callableId) {
|
||||||
val isPrimary: Boolean
|
val isPrimary: Boolean
|
||||||
get() = fir.isPrimary
|
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(
|
open class FirAccessorSymbol(
|
||||||
|
|||||||
Reference in New Issue
Block a user