diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt index ecc70c37c8b..8be87b279e5 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtFileSymbol.kt @@ -9,5 +9,8 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer abstract class KtFileSymbol : KtAnnotatedSymbol { + + abstract val topLevelCallableSymbols: List + abstract override fun createPointer(): KtSymbolPointer } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt index d7e809829e4..4dd067930bf 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/FirLightClassForFacade.kt @@ -12,31 +12,26 @@ import com.intellij.psi.impl.light.LightEmptyImplementsList import com.intellij.psi.impl.light.LightModifierList import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.asJava.classes.* -import org.jetbrains.kotlin.asJava.elements.* -import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName -import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.lazyPub -import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass -import org.jetbrains.kotlin.asJava.elements.KtLightField -import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget +import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.asJava.classes.createField import org.jetbrains.kotlin.idea.asJava.classes.createMethods import org.jetbrains.kotlin.idea.frontend.api.analyze import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtKotlinPropertySymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol -import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility -import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibility import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.psiUtil.isPrivate class FirLightClassForFacade( manager: PsiManager, @@ -80,32 +75,24 @@ class FirLightClassForFacade( override fun getModifierList(): PsiModifierList = _modifierList - override fun getScope(): PsiElement? = parent - - private fun loadMethodsFromFile( - file: KtFile, - result: MutableList - ) { - val declarations = file.declarations - .filterIsInstance() - .filterNot { multiFileClass && it.isPrivate() } - - if (declarations.isEmpty()) return - - val symbols = analyze(file) { - declarations.mapNotNull { - it.getSymbol() as? KtCallableSymbol - } - } - - createMethods(symbols.asSequence(), result, isTopLevel = true) - } + override fun getScope(): PsiElement = parent private val _ownMethods: List by lazyPub { val result = mutableListOf() - for (file in files) { - loadMethodsFromFile(file, result) + + val methodsAndProperties = sequence { + for (fileSymbol in fileSymbols) { + for (callableSymbol in fileSymbol.topLevelCallableSymbols) { + if (callableSymbol !is KtFunctionSymbol && callableSymbol !is KtPropertySymbol) continue + if (callableSymbol !is KtSymbolWithVisibility) continue + val isPrivate = callableSymbol.toPsiVisibilityForMember(isTopLevel = true) == PsiModifier.PRIVATE + if (isPrivate && multiFileClass) continue + yield(callableSymbol) + } + } } + createMethods(methodsAndProperties, result, isTopLevel = true) + result } @@ -114,25 +101,16 @@ class FirLightClassForFacade( } private fun loadFieldsFromFile( - file: KtFile, + fileSymbol: KtFileSymbol, nameGenerator: FirLightField.FieldNameGenerator, result: MutableList ) { - val properties = file.declarations - .filterIsInstance() - .applyIf(multiFileClass) { - filter { it.hasModifier(KtTokens.CONST_KEYWORD) } - } + for (propertySymbol in fileSymbol.topLevelCallableSymbols) { - if (properties.isEmpty()) return + if (propertySymbol !is KtPropertySymbol) continue - val propertySymbols = analyze(file) { - properties.mapNotNull { - it.getSymbol() as? KtPropertySymbol - } - } + if (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isConst && multiFileClass) continue - for (propertySymbol in propertySymbols) { val isLateInitWithPublicAccessors = if (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit) { val getterIsPublic = propertySymbol.getter?.toPsiVisibilityForMember(isTopLevel = true) ?.let { it == PsiModifier.PUBLIC } ?: true @@ -160,8 +138,8 @@ class FirLightClassForFacade( private val _ownFields: List by lazyPub { val result = mutableListOf() val nameGenerator = FirLightField.FieldNameGenerator() - for (file in files) { - loadFieldsFromFile(file, nameGenerator, result) + for (fileSymbol in fileSymbols) { + loadFieldsFromFile(fileSymbol, nameGenerator, result) } result } @@ -266,6 +244,8 @@ class FirLightClassForFacade( if (this.hashCode() != other.hashCode()) return false if (manager != other.manager) return false if (facadeClassFqName != other.facadeClassFqName) return false + if (!fileSymbols.containsAll(other.fileSymbols)) return false + if (!other.fileSymbols.containsAll(fileSymbols)) return false return true } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt index bc810e90b06..8e918f299dd 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFileSymbol.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.idea.fir.findPsi @@ -14,6 +15,7 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.utils.convertAnnotation import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer @@ -27,7 +29,13 @@ internal class KtFirFileSymbol( ) : KtFileSymbol(), KtFirSymbol { override val firRef = firRef(fir, resolveState) - override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.session) } + override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.session) } + + override val topLevelCallableSymbols: List by firRef.withFirAndCache { + it.declarations.mapNotNull { declaration -> + if (declaration is FirCallableDeclaration<*>) builder.buildCallableSymbol(declaration) else null + } + } override fun createPointer(): KtSymbolPointer { KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }