From 50a9313a5e80225f546fdef41f08ddd908c3457a Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 18 Mar 2020 18:04:00 +0300 Subject: [PATCH] [FIR] Support some approximation of effective visibility --- .../resolve/cfg/propertiesAndInitBlocks.txt | 4 +- .../localClassAccessesContainingClass.txt | 4 +- .../resolve/expresssions/localConstructor.txt | 2 +- .../resolve/expresssions/localInnerClass.txt | 4 +- .../resolve/expresssions/localObjects.txt | 2 +- .../resolve/expresssions/localScopes.txt | 8 +- .../resolve/expresssions/localTypes.txt | 10 +- .../resolve/expresssions/nestedVisibility.txt | 8 +- .../expresssions/outerMemberAccesses.txt | 10 +- .../expresssions/privateVisibility.txt | 26 +- .../expresssions/protectedVisibility.txt | 10 +- .../callableReferenceToLocalClass.txt | 4 +- .../testData/resolve/objectInnerClass.txt | 24 +- .../hashTableWithForEach.txt | 8 +- .../testData/resolveWithStdlib/problems.txt | 2 +- .../kotlin/fir/FirEffectiveVisibilityUtils.kt | 144 ++++++++++++ .../FirStatusResolveTransformer.kt | 12 +- .../scopes/impl/FirIntegerLiteralTypeScope.kt | 3 +- .../fir/declarations/FirDeclarationStatus.kt | 2 + .../FirResolvedDeclarationStatus.kt | 2 + .../kotlin/fir/FirEffectiveVisibility.kt | 222 ++++++++++++++++++ .../org/jetbrains/kotlin/fir/FirRenderer.kt | 25 +- .../fir/declarations/FirDeclarationUtil.kt | 1 + .../impl/FirDeclarationStatusImpl.kt | 8 +- .../impl/FirResolvedDeclarationStatusImpl.kt | 5 +- .../kotlin/fir/tree/generator/FieldSets.kt | 2 + .../fir/tree/generator/NodeConfigurator.kt | 3 + .../kotlin/fir/tree/generator/Types.kt | 6 +- 28 files changed, 480 insertions(+), 81 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.txt index 2416514e27b..d98f9ab34ee 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.txt +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.txt @@ -18,7 +18,7 @@ FILE: propertiesAndInitBlocks.kt } local final class LocalClass : R|kotlin/Any| { - public constructor(): R|LocalClass| { + public[local] constructor(): R|LocalClass| { super() } @@ -34,7 +34,7 @@ FILE: propertiesAndInitBlocks.kt ) public get(): R|kotlin/Unit| { local final class LocalClass : R|kotlin/Any| { - public constructor(): R|LocalClass| { + public[local] constructor(): R|LocalClass| { super() } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/localClassAccessesContainingClass.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/localClassAccessesContainingClass.txt index baac226e0cd..a2eccee27fc 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/localClassAccessesContainingClass.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/localClassAccessesContainingClass.txt @@ -6,11 +6,11 @@ FILE: localClassAccessesContainingClass.kt public final fun foo(): R|kotlin/Unit| { local final class Local : R|kotlin/Any| { - public constructor(): R|Outer.Local| { + public[local] constructor(): R|Outer.Local| { super() } - public final fun bar(): R|kotlin/Unit| { + public[local] final fun bar(): R|kotlin/Unit| { lval x: R|kotlin/String| = this@R|/Outer|.R|/Outer.y| } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/localConstructor.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/localConstructor.txt index 0fb17b39b70..9c0bce13683 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/localConstructor.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/localConstructor.txt @@ -1,7 +1,7 @@ FILE: localConstructor.kt public final fun test(): R|kotlin/Unit| { local final class Local : R|kotlin/Any| { - public constructor(): R|Local| { + public[local] constructor(): R|Local| { super() } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/localInnerClass.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/localInnerClass.txt index 86ebb32cf06..c6503ef4801 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/localInnerClass.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/localInnerClass.txt @@ -12,11 +12,11 @@ FILE: localInnerClass.kt } local final inner class Derived : R|Foo| { - public constructor(x: R|kotlin/Int|): R|.Derived| { + public[local] constructor(x: R|kotlin/Int|): R|.Derived| { super() } - public final val x: R|kotlin/Int| = R|/x| + public[local] final val x: R|kotlin/Int| = R|/x| public get(): R|kotlin/Int| } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/localObjects.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/localObjects.txt index ba918a5f207..bbc003a9218 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/localObjects.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/localObjects.txt @@ -33,7 +33,7 @@ FILE: localObjects.kt super() } - public final fun foo(): R|kotlin/Unit| { + public[local] final fun foo(): R|kotlin/Unit| { } } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/localScopes.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/localScopes.txt index f4bf2adc92d..d2d47a74119 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/localScopes.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/localScopes.txt @@ -10,11 +10,11 @@ FILE: localScopes.kt } public final fun test(): R|kotlin/Unit| { local open class BaseLocal : R|Bar| { - public constructor(): R|BaseLocal| { + public[local] constructor(): R|BaseLocal| { super() } - public final fun baz(): R|kotlin/Unit| { + public[local] final fun baz(): R|kotlin/Unit| { } } @@ -35,11 +35,11 @@ FILE: localScopes.kt R|/anonymous|.R|/anonymous.baz|() R|/anonymous|.R|/Bar.foo|() local final class DerivedLocal : R|BaseLocal| { - public constructor(): R|DerivedLocal| { + public[local] constructor(): R|DerivedLocal| { super() } - public final fun gau(): R|kotlin/Unit| { + public[local] final fun gau(): R|kotlin/Unit| { } } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/localTypes.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/localTypes.txt index d6c9e10d056..448c0f5fce1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/localTypes.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/localTypes.txt @@ -4,24 +4,24 @@ FILE: localTypes.kt public final fun foo(): R|kotlin/Unit| { lval x: R|kotlin/Int| = Int(1) local final class Bar : R|Foo| { - public constructor(): R|Bar| { + public[local] constructor(): R|Bar| { super() } - public final val y: R|kotlin/String| = String() + public[local] final val y: R|kotlin/String| = String() public get(): R|kotlin/String| - public final fun R|kotlin/Int|.bar(s: R|kotlin/String|): R|kotlin/Boolean| { + public[local] final fun R|kotlin/Int|.bar(s: R|kotlin/String|): R|kotlin/Boolean| { lval z: R|kotlin/Double| = Double(0.0) ^bar Boolean(true) } - public final val R|kotlin/Boolean|.w: R|kotlin/Char| + public[local] final val R|kotlin/Boolean|.w: R|kotlin/Char| public get(): R|kotlin/Char| { ^ Char( ) } - public final fun id(arg: R|T|): R|T| { + public[local] final fun id(arg: R|T|): R|T| { ^id R|/arg| } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt index 6f90c6c44f0..3c96308f742 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt @@ -5,28 +5,28 @@ FILE: nestedVisibility.kt } private final class PrivateNested : R|kotlin/Any| { - public constructor(): R|Outer.PrivateNested| { + public[private] constructor(): R|Outer.PrivateNested| { super() } } private final inner class PrivateInner : R|kotlin/Any| { - public constructor(): R|Outer.PrivateInner| { + public[private] constructor(): R|Outer.PrivateInner| { super() } } protected final class ProtectedNested : R|kotlin/Any| { - public constructor(): R|Outer.ProtectedNested| { + public[protected] constructor(): R|Outer.ProtectedNested| { super() } } protected final inner class ProtectedInner : R|kotlin/Any| { - public constructor(): R|Outer.ProtectedInner| { + public[protected] constructor(): R|Outer.ProtectedInner| { super() } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/outerMemberAccesses.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/outerMemberAccesses.txt index 83e12edf6ef..bbb604d4e3d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/outerMemberAccesses.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/outerMemberAccesses.txt @@ -14,7 +14,7 @@ FILE: O.kt } private final class Derived : R|Base| { - public constructor(bar: R|kotlin/Int|): R|O.Derived| { + public[private] constructor(bar: R|kotlin/Int|): R|O.Derived| { super() } @@ -22,14 +22,14 @@ FILE: O.kt private get(): R|kotlin/Int| private final inner class Some : R|kotlin/Any| { - public constructor(z: R|kotlin/Boolean|): R|O.Derived.Some| { + public[private] constructor(z: R|kotlin/Boolean|): R|O.Derived.Some| { super() } - public final val z: R|kotlin/Boolean| = R|/z| + public[private] final val z: R|kotlin/Boolean| = R|/z| public get(): R|kotlin/Boolean| - public final fun test(): R|kotlin/Unit| { + public[private] final fun test(): R|kotlin/Unit| { lval x: R|kotlin/Int| = this@R|/O.Derived|.R|/O.Derived.bar| lval o: R|anonymous| = object : R|Wrapper| { private constructor(): R|anonymous| { @@ -58,7 +58,7 @@ FILE: O.kt } - public final fun test(): R|kotlin/Unit| { + public[private] final fun test(): R|kotlin/Unit| { lval x: R|kotlin/Int| = this@R|/O.Derived|.R|/O.Derived.bar| lval o: R|anonymous| = object : R|kotlin/Any| { private constructor(): R|anonymous| { diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/privateVisibility.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/privateVisibility.txt index 993a8dcd1bd..9b671587a56 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/privateVisibility.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/privateVisibility.txt @@ -2,26 +2,26 @@ FILE: first.kt private final fun foo(): R|kotlin/Unit| { } private final class Private : R|kotlin/Any| { - public constructor(): R|Private| { + public[private] constructor(): R|Private| { super() } private final fun bar(): R|kotlin/Unit| { } - public final fun baz(): R|kotlin/Unit| { + public[private] final fun baz(): R|kotlin/Unit| { this@R|/Private|.R|/Private.bar|() R|/Private.Nested.Nested|() this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|() Q|Private.NotCompanion|.#() } - public final inner class Inner : R|kotlin/Any| { - public constructor(): R|Private.Inner| { + public[private] final inner class Inner : R|kotlin/Any| { + public[private] constructor(): R|Private.Inner| { super() } - public final fun foo(): R|kotlin/Unit| { + public[private] final fun foo(): R|kotlin/Unit| { this@R|/Private|.R|/Private.bar|() this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|() Q|Private.NotCompanion|.#() @@ -30,18 +30,18 @@ FILE: first.kt } private final class Nested : R|kotlin/Any| { - public constructor(): R|Private.Nested| { + public[private] constructor(): R|Private.Nested| { super() } - public final fun foo(): R|kotlin/Unit| { + public[private] final fun foo(): R|kotlin/Unit| { this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|() Q|Private.NotCompanion|.#() } } - public final companion object Companion : R|kotlin/Any| { + public[private] final companion object Companion : R|kotlin/Any| { private constructor(): R|Private.Companion| { super() } @@ -51,7 +51,7 @@ FILE: first.kt } - public final object NotCompanion : R|kotlin/Any| { + public[private] final object NotCompanion : R|kotlin/Any| { private constructor(): R|Private.NotCompanion| { super() } @@ -64,23 +64,23 @@ FILE: first.kt } public final fun withLocals(): R|kotlin/Unit| { local final class Local : R|kotlin/Any| { - public constructor(): R|Local| { + public[local] constructor(): R|Local| { super() } private final fun bar(): R|kotlin/Unit| - public final fun baz(): R|kotlin/Unit| { + public[local] final fun baz(): R|kotlin/Unit| { R|/Local.bar|() this@R|/Local|.R|/Local.Inner.Inner|() } local final inner class Inner : R|kotlin/Any| { - public constructor(): R|Local.Inner| { + public[local] constructor(): R|Local.Inner| { super() } - public final fun foo(): R|kotlin/Unit| { + public[local] final fun foo(): R|kotlin/Unit| { R|/Local.bar|() } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt index 266339ab398..503194dfe9e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt @@ -24,11 +24,11 @@ FILE: protectedVisibility.kt } protected open class Nested : R|kotlin/Any| { - public constructor(): R|Protected.Nested| { + public[protected (in different classes)] constructor(): R|Protected.Nested| { super() } - public final fun foo(): R|kotlin/Unit| { + public[protected (in different classes)] final fun foo(): R|kotlin/Unit| { this@R|/Protected.Nested|.R|/Protected.Nested.bar|() } @@ -42,7 +42,7 @@ FILE: protectedVisibility.kt super() } - public final fun fromCompanion(): R|kotlin/Unit| { + public[protected] final fun fromCompanion(): R|kotlin/Unit| { } protected final fun protectedFromCompanion(): R|kotlin/Unit| { @@ -65,11 +65,11 @@ FILE: protectedVisibility.kt } private final class NestedDerived : R|Protected.Nested| { - public constructor(): R|Derived.NestedDerived| { + public[private] constructor(): R|Derived.NestedDerived| { super() } - public final fun use(): R|kotlin/Unit| { + public[private] final fun use(): R|kotlin/Unit| { this@R|/Derived.NestedDerived|.R|/Protected.Nested.bar|() } diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/callableReferenceToLocalClass.txt b/compiler/fir/analysis-tests/testData/resolve/inference/callableReferenceToLocalClass.txt index 52632affaf2..ba50c560fab 100644 --- a/compiler/fir/analysis-tests/testData/resolve/inference/callableReferenceToLocalClass.txt +++ b/compiler/fir/analysis-tests/testData/resolve/inference/callableReferenceToLocalClass.txt @@ -4,11 +4,11 @@ FILE: callableReferenceToLocalClass.kt } public final fun test_1(): R|kotlin/Unit| { local final class Data : R|kotlin/Any| { - public constructor(x: R|kotlin/Int|): R|Data| { + public[local] constructor(x: R|kotlin/Int|): R|Data| { super() } - public final val x: R|kotlin/Int| = R|/x| + public[local] final val x: R|kotlin/Int| = R|/x| public get(): R|kotlin/Int| } diff --git a/compiler/fir/analysis-tests/testData/resolve/objectInnerClass.txt b/compiler/fir/analysis-tests/testData/resolve/objectInnerClass.txt index 76f87edec84..337c0a71bd3 100644 --- a/compiler/fir/analysis-tests/testData/resolve/objectInnerClass.txt +++ b/compiler/fir/analysis-tests/testData/resolve/objectInnerClass.txt @@ -5,15 +5,15 @@ FILE: objectInnerClass.kt } local final inner class Child : R|ERROR CLASS: Symbol not found, for `Base`| { - public constructor(property: R|B|): R|.Child| { + public[local] constructor(property: R|B|): R|.Child| { super(R|/property|) } - public final fun R|ERROR CLASS: Symbol not found, for `Base`|.zoo(): R|kotlin/Unit| { + public[local] final fun R|ERROR CLASS: Symbol not found, for `Base`|.zoo(): R|kotlin/Unit| { lval x: = # } - public final fun foo(): R|kotlin/Unit| { + public[local] final fun foo(): R|kotlin/Unit| { #() lval x: = # #() @@ -31,14 +31,14 @@ FILE: objectInnerClass.kt } local open inner class Base : R|kotlin/Any| { - public constructor(property: R|B|): R|.Base| { + public[local] constructor(property: R|B|): R|.Base| { super() } - public final val property: R|B| = R|/property| + public[local] final val property: R|B| = R|/property| public get(): R|B| - public final fun baseFun(): R|kotlin/Unit| { + public[local] final fun baseFun(): R|kotlin/Unit| { } } @@ -130,15 +130,15 @@ FILE: objectInnerClass.kt } local final inner class Child : R|ERROR CLASS: Symbol not found, for `Base`| { - public constructor(property: R|B|): R|Case3..Child| { + public[local] constructor(property: R|B|): R|Case3..Child| { super(R|/property|) } - public final fun R|ERROR CLASS: Symbol not found, for `Base`|.zoo(): R|kotlin/Unit| { + public[local] final fun R|ERROR CLASS: Symbol not found, for `Base`|.zoo(): R|kotlin/Unit| { lval x: = # } - public final fun foo(): R|kotlin/Unit| { + public[local] final fun foo(): R|kotlin/Unit| { #() lval x: = # this@R|/Case3..Child|.R|/Case3..Child.zoo|() @@ -156,14 +156,14 @@ FILE: objectInnerClass.kt } local open inner class Base : R|kotlin/Any| { - public constructor(property: R|B|): R|Case3..Base| { + public[local] constructor(property: R|B|): R|Case3..Base| { super() } - public final val property: R|B| = R|/property| + public[local] final val property: R|B| = R|/property| public get(): R|B| - public final fun baseFun(): R|kotlin/Unit| { + public[local] final fun baseFun(): R|kotlin/Unit| { } } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/hashTableWithForEach.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/hashTableWithForEach.txt index 4da94d184ca..7840573b9c2 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/hashTableWithForEach.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/hashTableWithForEach.txt @@ -27,17 +27,17 @@ FILE: hashTableWithForEach.kt } private final class Entry : R|kotlin/collections/MutableMap.MutableEntry| { - public constructor(key: R|K|, value: R|V|): R|SomeHashTable.Entry| { + public[private] constructor(key: R|K|, value: R|V|): R|SomeHashTable.Entry| { super() } - public final override val key: R|K| = R|/key| + public[private] final override val key: R|K| = R|/key| public get(): R|K| - public final override val value: R|V| = R|/value| + public[private] final override val value: R|V| = R|/value| public get(): R|V| - public final override fun setValue(newValue: R|V|): R|V| { + public[private] final override fun setValue(newValue: R|V|): R|V| { ^setValue throw R|java/lang/UnsupportedOperationException.UnsupportedOperationException|() } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.txt index 25f80329371..361754e2061 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.txt @@ -18,7 +18,7 @@ FILE: problems.kt public get(): R|anonymous| public final fun test(): R|kotlin/Unit| { local final class Local : R|kotlin/Any| { - public constructor(): R|Local| { + public[local] constructor(): R|Local| { super() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt new file mode 100644 index 00000000000..5b7c5143632 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt @@ -0,0 +1,144 @@ +/* + * Copyright 2010-2020 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 + +import org.jetbrains.kotlin.descriptors.RelationToType +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility.* +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection + +fun firEffectiveVisibility( + session: FirSession, + visibility: Visibility, + declaration: FirMemberDeclaration? +) = + visibility.forVisibility(session, declaration) + +fun FirRegularClass.firEffectiveVisibility(session: FirSession, checkPublishedApi: Boolean = false) = + firEffectiveVisibility(session, emptySet(), checkPublishedApi) + +fun Visibility.firEffectiveVisibility(session: FirSession, declaration: FirMemberDeclaration?): FirEffectiveVisibility = + firEffectiveVisibility(session, normalize(), declaration) + +fun ConeKotlinType.leastPermissiveDescriptor(session: FirSession, base: FirEffectiveVisibility): DeclarationWithRelation? = + dependentDeclarations(session).leastPermissive(session, base) + +fun FirMemberDeclaration.firEffectiveVisibility( + session: FirSession, visibility: Visibility = this.visibility, checkPublishedApi: Boolean = false +): FirEffectiveVisibility = + lowerBound( + visibility.firEffectiveVisibility(session, this), + this.containingClass(session)?.firEffectiveVisibility(session, checkPublishedApi) ?: Public + ) + +private fun lowerBound(first: FirEffectiveVisibility, second: FirEffectiveVisibility) = + first.lowerBound(second) + +private fun FirMemberDeclaration.containingClass(session: FirSession): FirRegularClass? { + val classId = when (this) { + is FirRegularClass -> symbol.classId.outerClassId + is FirCallableMemberDeclaration<*> -> symbol.callableId.classId + else -> null + } ?: return null + if (classId.isLocal) return null + return session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.fir as? FirRegularClass +} + +private fun Visibility.forVisibility( + session: FirSession, declaration: FirMemberDeclaration? +): FirEffectiveVisibility = + when (this) { + Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS, Visibilities.INVISIBLE_FAKE -> Private + Visibilities.PROTECTED -> Protected(declaration?.containingClass(session)) + Visibilities.INTERNAL -> Internal + Visibilities.PUBLIC -> Public + Visibilities.LOCAL -> Local + // NB: visibility must be already normalized here, so e.g. no JavaVisibilities are possible at this point + else -> throw AssertionError("Visibility $name is not allowed in forVisibility") + } + +class DeclarationWithRelation internal constructor(val declaration: FirMemberDeclaration, private val relation: RelationToType) { + fun firEffectiveVisibility(session: FirSession) = + declaration.visibility.firEffectiveVisibility(session, declaration) + + override fun toString(): String { + val name = when (declaration) { + is FirRegularClass -> declaration.name + is FirSimpleFunction -> declaration.name + is FirVariable<*> -> declaration.name + else -> "" + } + return "$relation $name" + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is DeclarationWithRelation) return false + if (declaration != other.declaration) return false + if (relation != other.relation) return false + return true + } + + override fun hashCode(): Int { + var result = declaration.hashCode() + result = 31 * result + relation.hashCode() + return result + } +} + +private fun FirMemberDeclaration.dependentDeclarations(session: FirSession, ownRelation: RelationToType): Set = + setOf(DeclarationWithRelation(this, ownRelation)) + + (this.containingClass(session)?.dependentDeclarations(session, ownRelation.containerRelation()) ?: emptySet()) + +private fun FirRegularClass.firEffectiveVisibility( + session: FirSession, classes: Set, checkPublishedApi: Boolean +): FirEffectiveVisibility = + if (this in classes) Public + else with(this.containingClass(session)) { + lowerBound( + visibility.firEffectiveVisibility(session, this@firEffectiveVisibility), + this?.firEffectiveVisibility(session, classes + this@firEffectiveVisibility, checkPublishedApi) ?: Public + ) + } + +// Should collect all dependent classifier descriptors, to get verbose diagnostic +private fun ConeKotlinType.dependentDeclarations(session: FirSession) = + dependentDeclarations(session, emptySet(), RelationToType.CONSTRUCTOR) + +private fun ConeKotlinType.dependentDeclarations( + session: FirSession, types: Set, ownRelation: RelationToType +): Set { + if (this in types) return emptySet() + val classLikeType = this as? ConeClassLikeType ?: return emptySet() + val lookupTag = classLikeType.lookupTag + val classSymbol = lookupTag.toSymbol(session) ?: return emptySet() + val ownDependent = (classSymbol.fir as? FirMemberDeclaration)?.dependentDeclarations(session, ownRelation) ?: emptySet() + val argumentDependent = classLikeType.typeArguments.mapNotNull { + (it as? ConeKotlinTypeProjection)?.type?.dependentDeclarations(session, types + this, RelationToType.ARGUMENT) + }.flatten() + return ownDependent + argumentDependent +} + +private fun Set.leastPermissive(session: FirSession, base: FirEffectiveVisibility): DeclarationWithRelation? { + for (declarationWithRelation in this) { + val currentVisibility = declarationWithRelation.firEffectiveVisibility(session) + when (currentVisibility.relation(base)) { + Permissiveness.LESS, Permissiveness.UNKNOWN -> { + return declarationWithRelation + } + else -> { + } + } + } + return null +} + diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index bf7d1504b8b..611ee036217 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -5,15 +5,14 @@ package org.jetbrains.kotlin.fir.resolve.transformers -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.firEffectiveVisibility import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose @@ -119,7 +118,10 @@ class FirStatusResolveTransformer : FirAbstractTreeTransformer status.visibility } val modality = status.modality ?: resolveModality(containingClass) - return (status as FirDeclarationStatusImpl).resolved(visibility, modality) + val containerEffectiveVisibility = containingClass?.effectiveVisibility ?: FirEffectiveVisibility.Public + val effectiveVisibility = + visibility.firEffectiveVisibility(session, this as? FirMemberDeclaration).lowerBound(containerEffectiveVisibility) + return (status as FirDeclarationStatusImpl).resolved(visibility, effectiveVisibility, modality) } return status } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt index 6dc718ed450..f7407cf1d92 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.scopes.impl +import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* @@ -102,7 +103,7 @@ class FirIntegerLiteralTypeScope(private val session: FirSession) : FirScope() { FirILTTypeRefPlaceHolder(), receiverTypeRef = null, ALL_OPERATORS.getValue(name), - FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL), + FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, FirEffectiveVisibility.Public, Modality.FINAL), symbol ).apply { resolvePhase = FirResolvePhase.BODY_RESOLVE diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt index 9b1a8561515..8de4aeed087 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclarationStatus.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.visitors.* @@ -19,6 +20,7 @@ import org.jetbrains.kotlin.fir.visitors.* interface FirDeclarationStatus : FirElement { override val source: FirSourceElement? val visibility: Visibility + val effectiveVisibility: FirEffectiveVisibility val modality: Modality? val isExpect: Boolean val isActual: Boolean diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt index 6166df8225c..63032a8c9d6 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirResolvedDeclarationStatus.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.visitors.* @@ -18,6 +19,7 @@ import org.jetbrains.kotlin.fir.visitors.* interface FirResolvedDeclarationStatus : FirDeclarationStatus { override val source: FirSourceElement? override val visibility: Visibility + override val effectiveVisibility: FirEffectiveVisibility override val modality: Modality? override val isExpect: Boolean override val isActual: Boolean diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt new file mode 100644 index 00000000000..24fde86473a --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt @@ -0,0 +1,222 @@ +/* + * Copyright 2010-2020 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 + +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility.* +import org.jetbrains.kotlin.fir.declarations.FirRegularClass + +sealed class FirEffectiveVisibility(val name: String, val publicApi: Boolean = false, val privateApi: Boolean = false) { + + override fun toString() = name + + // Public + // /--/ | \-------------\ + // Protected(Base) | \ + // | Protected(Other) Internal = PackagePrivate + // Protected(Derived) | / \ + // | | / InternalProtected(Base) + // ProtectedBound / \ + // \ / /InternalProtected(Derived) + // \InternalProtectedBound/ + // | + // Private = Local + + + object Private : FirEffectiveVisibility("private", privateApi = true) { + override fun relation(other: FirEffectiveVisibility) = + if (this == other || Local == other) Permissiveness.SAME else Permissiveness.LESS + + override fun toVisibility() = Visibilities.PRIVATE + } + + // Effectively same as Private + object Local : FirEffectiveVisibility("local") { + override fun relation(other: FirEffectiveVisibility) = + if (this == other || Private == other) Permissiveness.SAME else Permissiveness.LESS + + override fun toVisibility() = Visibilities.LOCAL + } + + object Public : FirEffectiveVisibility("public", publicApi = true) { + override fun relation(other: FirEffectiveVisibility) = + if (this == other) Permissiveness.SAME else Permissiveness.MORE + + override fun toVisibility() = Visibilities.PUBLIC + } + + abstract class InternalOrPackage protected constructor(internal: Boolean) : FirEffectiveVisibility( + if (internal) "internal" else "public/*package*/" + ) { + override fun relation(other: FirEffectiveVisibility) = when (other) { + Public -> Permissiveness.LESS + Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE + is InternalOrPackage -> Permissiveness.SAME + ProtectedBound, is Protected -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other) { + Public -> this + Private, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other + is Protected -> InternalProtected(other.container) + ProtectedBound -> InternalProtectedBound + } + } + + object Internal : InternalOrPackage(true) { + override fun toVisibility() = Visibilities.INTERNAL + } + + object PackagePrivate : InternalOrPackage(false) { + override fun toVisibility() = Visibilities.PRIVATE + } + + class Protected(val container: FirRegularClass?) : FirEffectiveVisibility("protected", publicApi = true) { + + override fun equals(other: Any?) = (other is Protected && container == other.container) + + override fun hashCode() = container?.hashCode() ?: 0 + + override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" + + override fun relation(other: FirEffectiveVisibility) = when (other) { + Public -> Permissiveness.LESS + Private, Local, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE + is Protected -> containerRelation(container, other.container) + is InternalProtected -> when (containerRelation(container, other.container)) { + // Protected never can be less permissive than internal & protected + Permissiveness.SAME, Permissiveness.MORE -> Permissiveness.MORE + Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN + } + is InternalOrPackage -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other) { + Public -> this + Private, Local, ProtectedBound, InternalProtectedBound -> other + is Protected -> when (relation(other)) { + Permissiveness.SAME, Permissiveness.MORE -> this + Permissiveness.LESS -> other + Permissiveness.UNKNOWN -> ProtectedBound + } + is InternalProtected -> when (relation(other)) { + Permissiveness.LESS -> other + else -> InternalProtectedBound + } + is InternalOrPackage -> InternalProtected(container) + } + + override fun toVisibility() = Visibilities.PROTECTED + } + + // Lower bound for all protected visibilities + object ProtectedBound : FirEffectiveVisibility("protected (in different classes)", publicApi = true) { + override fun relation(other: FirEffectiveVisibility) = when (other) { + Public, is Protected -> Permissiveness.LESS + Private, Local, InternalProtectedBound -> Permissiveness.MORE + ProtectedBound -> Permissiveness.SAME + is InternalOrPackage, is InternalProtected -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other) { + Public, is Protected -> this + Private, Local, ProtectedBound, InternalProtectedBound -> other + is InternalOrPackage, is InternalProtected -> InternalProtectedBound + } + + override fun toVisibility() = Visibilities.PROTECTED + } + + // Lower bound for internal and protected(C) + class InternalProtected(val container: FirRegularClass?) : FirEffectiveVisibility("internal & protected") { + + override fun equals(other: Any?) = (other is InternalProtected && container == other.container) + + override fun hashCode() = container?.hashCode() ?: 0 + + override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" + + override fun relation(other: FirEffectiveVisibility) = when (other) { + Public, is InternalOrPackage -> Permissiveness.LESS + Private, Local, InternalProtectedBound -> Permissiveness.MORE + is InternalProtected -> containerRelation(container, other.container) + is Protected -> when (containerRelation(container, other.container)) { + // Internal & protected never can be more permissive than just protected + Permissiveness.SAME, Permissiveness.LESS -> Permissiveness.LESS + Permissiveness.UNKNOWN, Permissiveness.MORE -> Permissiveness.UNKNOWN + } + ProtectedBound -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other) { + Public, is InternalOrPackage -> this + Private, Local, InternalProtectedBound -> other + is Protected, is InternalProtected -> when (relation(other)) { + Permissiveness.SAME, Permissiveness.MORE -> this + Permissiveness.LESS -> other + Permissiveness.UNKNOWN -> InternalProtectedBound + } + ProtectedBound -> InternalProtectedBound + } + + override fun toVisibility() = Visibilities.PRIVATE + } + + // Lower bound for internal and protected lower bound + object InternalProtectedBound : FirEffectiveVisibility("internal & protected (in different classes)") { + override fun relation(other: FirEffectiveVisibility) = when (other) { + Public, is Protected, is InternalProtected, ProtectedBound, is InternalOrPackage -> Permissiveness.LESS + Private, Local -> Permissiveness.MORE + InternalProtectedBound -> Permissiveness.SAME + } + + override fun toVisibility() = Visibilities.PRIVATE + } + + enum class Permissiveness { + LESS, + SAME, + MORE, + UNKNOWN + } + + abstract fun relation(other: FirEffectiveVisibility): Permissiveness + + abstract fun toVisibility(): Visibility + + open fun lowerBound(other: FirEffectiveVisibility) = when (relation(other)) { + Permissiveness.SAME, Permissiveness.LESS -> this + Permissiveness.MORE -> other + Permissiveness.UNKNOWN -> Private + } +} + +internal fun containerRelation(first: FirRegularClass?, second: FirRegularClass?): Permissiveness = + if (first == null || second == null) { + Permissiveness.UNKNOWN + } else if (first == second) { + Permissiveness.SAME + // TODO +// } else if (DescriptorUtils.isSubclass(first, second)) { +// Permissiveness.LESS +// } else if (DescriptorUtils.isSubclass(second, first)) { +// Permissiveness.MORE + } else { + Permissiveness.UNKNOWN + } + +internal fun Visibility.firEffectiveVisibilityApproximation(): FirEffectiveVisibility = + when (this) { + Visibilities.PUBLIC -> Public + Visibilities.PRIVATE -> Private + Visibilities.PRIVATE_TO_THIS -> Private + Visibilities.INTERNAL -> Internal + Visibilities.LOCAL -> Local + Visibilities.PROTECTED -> ProtectedBound + else -> Public + } + diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index af0bab54c62..a677c836fb6 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -41,6 +41,13 @@ fun FirElement.render(mode: FirRenderer.RenderMode = FirRenderer.RenderMode.Norm buildString { this@render.accept(FirRenderer(this, mode)) } class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderMode.Normal) : FirVisitorVoid() { + companion object { + private val visibilitiesToRenderEffectiveSet = setOf( + Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS, Visibilities.INTERNAL, + Visibilities.PROTECTED, Visibilities.PUBLIC, Visibilities.LOCAL + ) + } + abstract class RenderMode(val renderLambdaBodies: Boolean, val renderCallArguments: Boolean) { object Normal : RenderMode(renderLambdaBodies = true, renderCallArguments = true) } @@ -152,11 +159,18 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM callableDeclaration.returnTypeRef.accept(this) } - private fun Visibility.asString() = - when (this) { - Visibilities.UNKNOWN -> "public?" + private fun Visibility.asString(effectiveVisibility: FirEffectiveVisibility? = null): String { + val itself = when (this) { + Visibilities.UNKNOWN -> return "public?" else -> toString() } + if (effectiveVisibility == null) return itself + val effectiveAsVisibility = effectiveVisibility.toVisibility() + if (effectiveAsVisibility == this) return itself + if (effectiveAsVisibility == Visibilities.PRIVATE && this == Visibilities.PRIVATE_TO_THIS) return itself + if (this !in visibilitiesToRenderEffectiveSet) return itself + return itself + "[${effectiveVisibility.name}]" + } private fun FirMemberDeclaration.modalityAsString(): String { return modality?.name?.toLowerCase() ?: run { @@ -187,7 +201,8 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM override fun visitMemberDeclaration(memberDeclaration: FirMemberDeclaration) { memberDeclaration.annotations.renderAnnotations() if (memberDeclaration !is FirProperty || !memberDeclaration.isLocal) { - print(memberDeclaration.visibility.asString() + " " + memberDeclaration.modalityAsString() + " ") + print(memberDeclaration.visibility.asString(memberDeclaration.effectiveVisibility) + " ") + print(memberDeclaration.modalityAsString() + " ") } if (memberDeclaration.isExpect) { print("expect ") @@ -377,7 +392,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM override fun visitConstructor(constructor: FirConstructor) { constructor.annotations.renderAnnotations() - print(constructor.visibility.asString() + " constructor") + print(constructor.visibility.asString(constructor.effectiveVisibility) + " constructor") constructor.typeParameters.renderTypeParameters() constructor.valueParameters.renderParameters() print(": ") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt index 7b0a2055173..8bb16f7e451 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt @@ -26,6 +26,7 @@ inline val FirRegularClass.isData get() = status.isData inline val FirRegularClass.isInline get() = status.isInline inline val FirMemberDeclaration.modality get() = status.modality inline val FirMemberDeclaration.visibility get() = status.visibility +inline val FirMemberDeclaration.effectiveVisibility get() = status.effectiveVisibility inline val FirMemberDeclaration.isActual get() = status.isActual inline val FirMemberDeclaration.isExpect get() = status.isExpect inline val FirMemberDeclaration.isInner get() = status.isInner diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt index f93b9f8e673..b662f2c7f20 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt @@ -7,10 +7,12 @@ package org.jetbrains.kotlin.fir.declarations.impl import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.FirPureAbstractElement import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl.Modifier.* +import org.jetbrains.kotlin.fir.firEffectiveVisibilityApproximation import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor @@ -19,6 +21,8 @@ open class FirDeclarationStatusImpl( override val modality: Modality? ) : FirPureAbstractElement(), FirDeclarationStatus { override val source: FirSourceElement? get() = null + override val effectiveVisibility: FirEffectiveVisibility + get() = visibility.firEffectiveVisibilityApproximation() protected var flags: Int = 0 private operator fun get(modifier: Modifier): Boolean = (flags and modifier.mask) != 0 @@ -159,7 +163,7 @@ open class FirDeclarationStatusImpl( return this } - fun resolved(visibility: Visibility, modality: Modality): FirDeclarationStatus { - return FirResolvedDeclarationStatusImpl(visibility, modality, flags) + fun resolved(visibility: Visibility, effectiveVisibility: FirEffectiveVisibility, modality: Modality): FirDeclarationStatus { + return FirResolvedDeclarationStatusImpl(visibility, effectiveVisibility, modality, flags) } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirResolvedDeclarationStatusImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirResolvedDeclarationStatusImpl.kt index dc7b35a22a6..a5897ceaf62 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirResolvedDeclarationStatusImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirResolvedDeclarationStatusImpl.kt @@ -7,18 +7,21 @@ package org.jetbrains.kotlin.fir.declarations.impl import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.declarations.FirResolvedDeclarationStatus class FirResolvedDeclarationStatusImpl( visibility: Visibility, + override var effectiveVisibility: FirEffectiveVisibility, modality: Modality ) : FirDeclarationStatusImpl(visibility, modality), FirResolvedDeclarationStatus { internal constructor( visibility: Visibility, + effectiveVisibility: FirEffectiveVisibility, modality: Modality, flags: Int - ) : this(visibility, modality) { + ) : this(visibility, effectiveVisibility, modality) { this.flags = flags } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt index 0c73cd355bd..8a3f1234035 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt @@ -75,6 +75,8 @@ object FieldSets { val visibility = field(visibilityType) + val effectiveVisibility = field("effectiveVisibility", effectiveVisibilityType) + val modality = field(modalityType, nullable = true) val scopeProvider = field("scopeProvider", firScopeProviderType) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index b22e06e88db..332ecb67c31 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -5,12 +5,14 @@ package org.jetbrains.kotlin.fir.tree.generator +import org.jetbrains.kotlin.descriptors.effectiveVisibility import org.jetbrains.kotlin.fir.tree.generator.FieldSets.annotations import org.jetbrains.kotlin.fir.tree.generator.FieldSets.arguments import org.jetbrains.kotlin.fir.tree.generator.FieldSets.body import org.jetbrains.kotlin.fir.tree.generator.FieldSets.classKind import org.jetbrains.kotlin.fir.tree.generator.FieldSets.controlFlowGraphReferenceField import org.jetbrains.kotlin.fir.tree.generator.FieldSets.declarations +import org.jetbrains.kotlin.fir.tree.generator.FieldSets.effectiveVisibility import org.jetbrains.kotlin.fir.tree.generator.FieldSets.initializer import org.jetbrains.kotlin.fir.tree.generator.FieldSets.modality import org.jetbrains.kotlin.fir.tree.generator.FieldSets.name @@ -303,6 +305,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild declarationStatus.configure { +visibility + +effectiveVisibility +modality generateBooleanFields( "expect", "actual", "override", "operator", "infix", "inline", "tailRec", diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index 4dcf42ae032..336e3cb0491 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.fir.tree.generator import org.jetbrains.kotlin.contracts.description.InvocationKind -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.tree.generator.context.generatedType import org.jetbrains.kotlin.fir.tree.generator.context.type @@ -29,6 +26,7 @@ val invocationKindType = type(InvocationKind::class) val varianceType = type(Variance::class) val nameType = type(Name::class) val visibilityType = type(Visibility::class) +val effectiveVisibilityType = type("fir", "FirEffectiveVisibility") val visibilitiesType = type(Visibilities::class) val modalityType = type(Modality::class) val fqNameType = type(FqName::class)