[FIR2IR] Fix collecting declarations for Fir2IrLazyClass
Existed code might lose declarations in two cases:
1. When there is a declared function which is mapped to property
(java synthetic properties)
2. When class has property and function with same name
This commit is contained in:
committed by
teamcityserver
parent
307fa66dda
commit
33f78e3903
@@ -8,17 +8,15 @@ package org.jetbrains.kotlin.fir.lazy
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.backend.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull
|
||||
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -31,6 +29,7 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
class Fir2IrLazyClass(
|
||||
components: Fir2IrComponents,
|
||||
@@ -145,59 +144,51 @@ class Fir2IrLazyClass(
|
||||
|
||||
override val declarations: MutableList<IrDeclaration> by lazyVar(lock) {
|
||||
val result = mutableListOf<IrDeclaration>()
|
||||
val processedNames = mutableSetOf<Name>()
|
||||
// NB: it's necessary to take all callables from scope,
|
||||
// e.g. to avoid accessing un-enhanced Java declarations with FirJavaTypeRef etc. inside
|
||||
val scope = fir.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||
scope.processDeclaredConstructors {
|
||||
result += declarationStorage.getIrConstructorSymbol(it).owner
|
||||
}
|
||||
|
||||
for (declaration in fir.declarations) {
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> {
|
||||
if (fir.classKind == ClassKind.ENUM_CLASS && declaration.isStatic &&
|
||||
(declaration.source == null || declaration.source?.kind == KtFakeSourceElementKind.EnumGeneratedDeclaration)
|
||||
) {
|
||||
// Handle generated methods for enum classes (values(), valueOf(String)).
|
||||
// TODO we also come here for all deserialized static enum members (with declaration.source == null).
|
||||
// For such members we currently can't tell whether they are compiler-generated methods or not.
|
||||
result += declarationStorage.getIrFunctionSymbol(declaration.symbol).owner
|
||||
} else if (declaration.name !in processedNames) {
|
||||
processedNames += declaration.name
|
||||
if (fir.classKind == ClassKind.ANNOTATION_CLASS && declaration.origin == FirDeclarationOrigin.Java) {
|
||||
// Java annotation values are exposed as properties.
|
||||
scope.processPropertiesByName(declaration.name) {
|
||||
if (it is FirPropertySymbol && it.dispatchReceiverClassOrNull() == fir.symbol.toLookupTag()) {
|
||||
result += declarationStorage.getIrPropertySymbol(it).owner as IrProperty
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scope.processFunctionsByName(declaration.name) {
|
||||
if (it.dispatchReceiverClassOrNull() == fir.symbol.toLookupTag()) {
|
||||
if (it.isAbstractMethodOfAny()) {
|
||||
return@processFunctionsByName
|
||||
}
|
||||
result += declarationStorage.getIrFunctionSymbol(it).owner
|
||||
}
|
||||
}
|
||||
}
|
||||
if (declaration is FirRegularClass) {
|
||||
val nestedSymbol = classifierStorage.getIrClassSymbol(declaration.symbol)
|
||||
result += nestedSymbol.owner
|
||||
}
|
||||
}
|
||||
|
||||
// Handle generated methods for enum classes (values(), valueOf(String)).
|
||||
// TODO we also come here for all deserialized static enum members (with declaration.source == null).
|
||||
// For such members we currently can't tell whether they are compiler-generated methods or not.
|
||||
if (fir.classKind == ClassKind.ENUM_CLASS) {
|
||||
for (declaration in fir.declarations) {
|
||||
if (
|
||||
declaration is FirSimpleFunction &&
|
||||
declaration.isStatic &&
|
||||
(declaration.source == null || declaration.source?.kind == KtFakeSourceElementKind.EnumGeneratedDeclaration)
|
||||
) {
|
||||
result += declarationStorage.getIrFunctionSymbol(declaration.symbol).owner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val ownerLookupTag = fir.symbol.toLookupTag()
|
||||
for (name in scope.getCallableNames()) {
|
||||
scope.processFunctionsByName(name) {
|
||||
if (it.isSubstitutionOrIntersectionOverride) return@processFunctionsByName
|
||||
if (it.dispatchReceiverClassOrNull() == ownerLookupTag) {
|
||||
if (it.isAbstractMethodOfAny()) {
|
||||
return@processFunctionsByName
|
||||
}
|
||||
result += declarationStorage.getIrFunctionSymbol(it).owner
|
||||
}
|
||||
is FirProperty -> {
|
||||
if (declaration.name !in processedNames) {
|
||||
processedNames += declaration.name
|
||||
scope.processPropertiesByName(declaration.name) {
|
||||
if (it is FirPropertySymbol && it.dispatchReceiverClassOrNull() == fir.symbol.toLookupTag()) {
|
||||
result += declarationStorage.getIrPropertySymbol(it).owner as IrProperty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.processPropertiesByName(name) {
|
||||
if (it.isSubstitutionOrIntersectionOverride) return@processPropertiesByName
|
||||
if (it is FirPropertySymbol && it.dispatchReceiverClassOrNull() == ownerLookupTag) {
|
||||
result.addIfNotNull(declarationStorage.getIrPropertySymbol(it).owner as? IrDeclaration)
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
val nestedSymbol = classifierStorage.getIrClassSymbol(declaration.symbol)
|
||||
result += nestedSymbol.owner
|
||||
}
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,14 +196,6 @@ class Fir2IrLazyClass(
|
||||
result += getFakeOverridesByName(name)
|
||||
}
|
||||
|
||||
// TODO: remove this check to save time
|
||||
// for (declaration in result) {
|
||||
// if (declaration.parent != this) {
|
||||
// throw AssertionError(
|
||||
// "Unmatched parent for lazy class ${fir.name} member ${declaration.render()} f/o ${declaration.isFakeOverride}"
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user