diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt index 74ee8da90a2..182b67ba0f2 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt @@ -107,7 +107,7 @@ abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule } } - protected open val isTopLevel: Boolean get() = false + internal open val isTopLevel: Boolean get() = false private val _containingFile: PsiFile? by lazyPub { val kotlinOrigin = kotlinOrigin ?: return@lazyPub null diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt index 6a8dbb6d763..6626285d21f 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt @@ -273,6 +273,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC containingClass = this, name = JvmAbi.INSTANCE_FIELD, lightMemberOrigin = null, + isCompanion = false, ) ) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt index 98f13ae7cd6..555a5e8beaa 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt @@ -26,8 +26,6 @@ import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForPrope import org.jetbrains.kotlin.light.classes.symbol.isConstOrJvmField import org.jetbrains.kotlin.light.classes.symbol.isLateInit import org.jetbrains.kotlin.light.classes.symbol.modifierLists.GranularModifiersBox -import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with -import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.utils.addToStdlib.applyIf @@ -137,6 +135,7 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike< containingClass = this, name = it.name.asString(), lightMemberOrigin = null, + isCompanion = true, ) ) } @@ -144,8 +143,7 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike< internal fun computeModifiers(modifier: String): Map? = when (modifier) { in GranularModifiersBox.VISIBILITY_MODIFIERS -> { - val visibility = withClassOrObjectSymbol { it.toPsiVisibilityForClass(isNested = !isTopLevel) } - GranularModifiersBox.VISIBILITY_MODIFIERS_MAP.with(visibility) + GranularModifiersBox.computeVisibilityForClass(ktModule, classOrObjectSymbolPointer, isTopLevel) } in GranularModifiersBox.MODALITY_MODIFIERS -> GranularModifiersBox.computeSimpleModality(ktModule, classOrObjectSymbolPointer) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt index 67b72b3d4bf..7af49acc9d8 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClas import org.jetbrains.kotlin.light.classes.symbol.compareSymbolPointers import org.jetbrains.kotlin.light.classes.symbol.isValid import org.jetbrains.kotlin.light.classes.symbol.modifierLists.GranularModifiersBox +import org.jetbrains.kotlin.light.classes.symbol.modifierLists.InitializedModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList import org.jetbrains.kotlin.light.classes.symbol.nonExistentType import org.jetbrains.kotlin.light.classes.symbol.withSymbol @@ -35,6 +36,7 @@ internal class SymbolLightFieldForObject private constructor( lightMemberOrigin: LightMemberOrigin?, private val objectSymbolPointer: KtSymbolPointer, override val kotlinOrigin: KtObjectDeclaration?, + private val isCompanion: Boolean, ) : SymbolLightField(containingClass, lightMemberOrigin) { internal constructor( ktAnalysisSession: KtAnalysisSession, @@ -42,12 +44,14 @@ internal class SymbolLightFieldForObject private constructor( name: String, lightMemberOrigin: LightMemberOrigin?, containingClass: SymbolLightClassForClassLike<*>, + isCompanion: Boolean, ) : this( containingClass = containingClass, name = name, lightMemberOrigin = lightMemberOrigin, kotlinOrigin = objectSymbol.sourcePsiSafe(), objectSymbolPointer = with(ktAnalysisSession) { objectSymbol.createPointer() }, + isCompanion = isCompanion, ) private inline fun withObjectDeclarationSymbol(crossinline action: KtAnalysisSession.(KtNamedClassOrObjectSymbol) -> T): T = @@ -58,22 +62,26 @@ internal class SymbolLightFieldForObject private constructor( private val _modifierList: PsiModifierList by lazyPub { SymbolLightMemberModifierList( containingDeclaration = this, - modifiersBox = GranularModifiersBox( - initialValue = GranularModifiersBox.MODALITY_MODIFIERS_MAP.mutate { - it[PsiModifier.FINAL] = true - it[PsiModifier.STATIC] = true - }, - computer = ::computeModifiers, - ), + modifiersBox = if (isCompanion) { + GranularModifiersBox( + initialValue = GranularModifiersBox.MODALITY_MODIFIERS_MAP.mutate { + it[PsiModifier.FINAL] = true + it[PsiModifier.STATIC] = true + }, + computer = ::computeCompanionModifiers, + ) + } else { + InitializedModifiersBox(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL) + }, annotationsBox = ComputeAllAtOnceAnnotationsBox { modifierList -> listOf(SymbolLightSimpleAnnotation(NotNull::class.java.name, modifierList)) }, ) } - private fun computeModifiers(modifier: String): Map? { + private fun computeCompanionModifiers(modifier: String): Map? { if (modifier !in GranularModifiersBox.VISIBILITY_MODIFIERS) return null - return GranularModifiersBox.computeVisibilityForMember(ktModule, objectSymbolPointer) + return GranularModifiersBox.computeVisibilityForClass(ktModule, objectSymbolPointer, isTopLevel = false) } private val _isDeprecated: Boolean by lazyPub { diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/modifierLists/GranularModifiersBox.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/modifierLists/GranularModifiersBox.kt index 3e121f4f01d..28a8f2a7e8c 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/modifierLists/GranularModifiersBox.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/modifierLists/GranularModifiersBox.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.light.classes.symbol.computeSimpleModality +import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForMember import org.jetbrains.kotlin.light.classes.symbol.withSymbol import org.jetbrains.kotlin.utils.keysToMap @@ -71,6 +72,18 @@ internal class GranularModifiersBox( return VISIBILITY_MODIFIERS_MAP.with(visibility) } + internal fun computeVisibilityForClass( + ktModule: KtModule, + declarationPointer: KtSymbolPointer, + isTopLevel: Boolean, + ): PersistentMap { + val visibility = declarationPointer.withSymbol(ktModule) { + it.toPsiVisibilityForClass(!isTopLevel) + } + + return VISIBILITY_MODIFIERS_MAP.with(visibility) + } + internal fun computeSimpleModality( ktModule: KtModule, declarationPointer: KtSymbolPointer, diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.descriptors.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.descriptors.java index 673db05481e..5a4ea9aa697 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.descriptors.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.descriptors.java @@ -13,15 +13,15 @@ final class PrivateObject /* one.PrivateObject*/ { private final void privateFun();// privateFun() - public final boolean getInternalProperty$test_module();// getInternalProperty$test_module() + public final boolean getInternalProperty$light_idea_test_case();// getInternalProperty$light_idea_test_case() public final int getPublicProperty();// getPublicProperty() - public final void internalFun$test_module();// internalFun$test_module() + public final void internalFun$light_idea_test_case();// internalFun$light_idea_test_case() public final void publicFun();// publicFun() - public final void setInternalProperty$test_module(boolean);// setInternalProperty$test_module(boolean) + public final void setInternalProperty$light_idea_test_case(boolean);// setInternalProperty$light_idea_test_case(boolean) public final void setPublicProperty(int);// setPublicProperty(int) -} \ No newline at end of file +} diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.java index e21a83a4dbe..3302dd8489a 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/PrivateObject.java @@ -1,9 +1,9 @@ final class PrivateObject /* one.PrivateObject*/ { @org.jetbrains.annotations.NotNull() - private static final one.PrivateObject INSTANCE; + private static java.lang.String privateProperty = "" /* initializer type: java.lang.String */; @org.jetbrains.annotations.NotNull() - private static java.lang.String privateProperty = "" /* initializer type: java.lang.String */; + public static final one.PrivateObject INSTANCE; private static boolean internalProperty = false /* initializer type: boolean */; diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/companionDuplication.descriptors.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/companionDuplication.descriptors.java new file mode 100644 index 00000000000..c194f88d1a3 --- /dev/null +++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/companionDuplication.descriptors.java @@ -0,0 +1,20 @@ +public final class C /* C*/ { + @org.jetbrains.annotations.NotNull() + public static final C.Companion Companion; + + public C();// .ctor() + + class Companion ... + + class Factory ... +} + +public static final class Companion /* C.Companion*/ { + private Companion();// .ctor() + + public final void bar();// bar() +} + +public static final class Factory /* C.Factory*/ { + private Factory();// .ctor() +} diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.descriptors.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.descriptors.java index a6a9ae5b28f..7c207482f51 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.descriptors.java +++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.descriptors.java @@ -37,6 +37,15 @@ public final class C1 /* C1*/ { class Companion ... } +public final class C2 /* C2*/ { + @org.jetbrains.annotations.NotNull() + public static final C2.Companion Companion; + + public C2();// .ctor() + + class Companion ... +} + public final class ClassWithConstContainer /* ClassWithConstContainer*/ { @org.jetbrains.annotations.NotNull() public static final ClassWithConstContainer.Companion Companion; @@ -96,6 +105,10 @@ public static final class Companion /* I.Companion*/ { private Companion();// .ctor() } +public static final class Companion /* C2.Companion*/ { + private Companion();// .ctor() +} + public static final class Companion /* ClassWithConstContainer.Companion*/ { private Companion();// .ctor() } diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.java index 76b77a54998..95ed4a064aa 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.java +++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.java @@ -44,6 +44,15 @@ public final class C1 /* C1*/ { class Companion ... } +public final class C2 /* C2*/ { + @org.jetbrains.annotations.NotNull() + public static final C2.Companion Companion; + + public C2();// .ctor() + + class Companion ... +} + public final class ClassWithConstContainer /* ClassWithConstContainer*/ { @org.jetbrains.annotations.NotNull() public static final ClassWithConstContainer.Companion Companion; @@ -103,6 +112,10 @@ public static final class Companion /* I.Companion*/ { private Companion();// .ctor() } +public static final class Companion /* C2.Companion*/ { + private Companion();// .ctor() +} + public static final class Companion /* ClassWithConstContainer.Companion*/ { private Companion();// .ctor() } diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.kt b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.kt index 7d5ffa1f3d7..65710f6f88b 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.kt +++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.kt @@ -23,6 +23,12 @@ interface I { companion object { } } +class C2 { + internal companion object { + + } +} + object Obj : java.lang.Runnable { @JvmStatic var x: String = "" override fun run() {} diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.lib.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.lib.java index 22fb509c32f..7b6e592796f 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.lib.java +++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/objects.lib.java @@ -37,6 +37,15 @@ public final class C1 /* C1*/ { class Companion ... } +public final class C2 /* C2*/ { + @org.jetbrains.annotations.NotNull() + public static final C2.Companion Companion; + + public C2();// .ctor() + + class Companion ... +} + public final class ClassWithConstContainer /* ClassWithConstContainer*/ { @org.jetbrains.annotations.NotNull() public static final ClassWithConstContainer.Companion Companion; @@ -65,11 +74,7 @@ private static final class Companion /* C1.Companion*/ { private Companion();// .ctor() } -public static final class Companion /* I.Companion*/ { - private Companion();// .ctor() -} - -public static final class Companion /* ClassWithConstContainer.Companion*/ { +public static final class Companion /* C2.Companion*/ { private Companion();// .ctor() } @@ -100,6 +105,14 @@ public static final class Companion /* C.Companion*/ { public final void setX(@org.jetbrains.annotations.NotNull() java.lang.String);// setX(java.lang.String) } +public static final class Companion /* I.Companion*/ { + private Companion();// .ctor() +} + +public static final class Companion /* ClassWithConstContainer.Companion*/ { + private Companion();// .ctor() +} + public final class ConstContainer /* ConstContainer*/ { @org.jetbrains.annotations.NotNull() public static final ConstContainer INSTANCE; diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/asJava/AbstractCompilerLightClassTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/asJava/AbstractCompilerLightClassTest.kt index 6fdbb3789d5..506f9147cc1 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/asJava/AbstractCompilerLightClassTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/asJava/AbstractCompilerLightClassTest.kt @@ -34,7 +34,7 @@ abstract class AbstractCompilerLightClassTest : KotlinMultiFileTestWithJava findLightClass(allowFrontendExceptions, environment, fqname) }, - LightClassTestCommon::removeEmptyDefaultImpls + { LightClassTestCommon.removeEmptyDefaultImpls(it).replace("\$test_module", "\$light_idea_test_case") }, ) KotlinTestUtils.assertEqualsToFile(expectedFile, actual) }