From 33f78e39037d5bee469201b6e0521ff833a8f6db Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 25 Oct 2021 15:22:15 +0300 Subject: [PATCH] [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 --- .../kotlin/fir/lazy/Fir2IrLazyClass.kt | 91 ++++++++----------- 1 file changed, 37 insertions(+), 54 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt index 9910cf00320..5df4d8ee70f 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyClass.kt @@ -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 by lazyVar(lock) { val result = mutableListOf() - val processedNames = mutableSetOf() // 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 }