[FIR] Refactor effective visibility calculation

Before this commit, we had effective visibility as a part of FIR status,
so it was integrated into the full pipeline. In this commit,
we introduced "effective visibility as a service" which is now used
only by exposed visibility checker. This allows us to make the thing
universal for all FIR nodes, including nodes for Java / deserialized.
This commit is contained in:
Nick
2020-07-15 17:23:21 +03:00
committed by Mikhail Glukhikh
parent b15e32936e
commit 7145caca40
95 changed files with 713 additions and 484 deletions
@@ -10,11 +10,12 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.providers.AbstractFirSymbolProvider
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.types.Variance.INVARIANT
import org.jetbrains.kotlin.util.OperatorNameConventions
class JavaSymbolProvider(
val session: FirSession,
@@ -178,6 +180,16 @@ class JavaSymbolProvider(
buildOuterClassTypeParameterRef { symbol = it.symbol }
}
}
status = FirResolvedDeclarationStatusImpl(
javaClass.visibility,
javaClass.modality
).apply {
this.isInner = !isTopLevel && !this@buildJavaClass.isStatic
isCompanion = false
isData = false
isInline = false
isFun = classKind == ClassKind.INTERFACE
}
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
// TODO: may be we can process fields & methods later.
// However, they should be built up to override resolve stage
@@ -191,7 +203,10 @@ class JavaSymbolProvider(
session = this@JavaSymbolProvider.session
symbol = FirVariableSymbol(fieldId)
name = fieldName
status = FirDeclarationStatusImpl(javaField.visibility, javaField.modality).apply {
status = FirResolvedDeclarationStatusImpl(
javaField.visibility,
javaField.modality
).apply {
isStatic = javaField.isStatic
isExpect = false
isActual = false
@@ -207,6 +222,15 @@ class JavaSymbolProvider(
session = this@JavaSymbolProvider.session
symbol = FirFieldSymbol(fieldId)
name = fieldName
status = FirResolvedDeclarationStatusImpl(
javaField.visibility,
javaField.modality
).apply {
isStatic = javaField.isStatic
isExpect = false
isActual = false
isOverride = false
}
visibility = javaField.visibility
modality = javaField.modality
returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack)
@@ -238,6 +262,23 @@ class JavaSymbolProvider(
this@JavaSymbolProvider.session, index, javaTypeParameterStack,
)
}
status = FirResolvedDeclarationStatusImpl(
javaMethod.visibility,
javaMethod.modality
).apply {
isStatic = javaMethod.isStatic
isExpect = false
isActual = false
isOverride = false
// Approximation: all Java methods with name that allows to use it in operator form are considered operators
// We need here more detailed checks (see modifierChecks.kt)
isOperator = name in ALL_JAVA_OPERATION_NAMES || OperatorNameConventions.COMPONENT_REGEX.matches(name.asString())
isInfix = false
isInline = false
isTailRec = false
isExternal = false
isSuspend = false
}
}
declarations += firJavaMethod
}
@@ -254,9 +295,19 @@ class JavaSymbolProvider(
source = psi?.toFirPsiSourceElement()
session = this@JavaSymbolProvider.session
symbol = constructorSymbol
isInner = javaClass.outerClass != null && !javaClass.isStatic
val isThisInner = this.isInner
status = FirResolvedDeclarationStatusImpl(
visibility,
Modality.FINAL
).apply {
isExpect = false
isActual = false
isOverride = false
isInner = isThisInner
}
this.visibility = visibility
this.isPrimary = isPrimary
isInner = javaClass.outerClass != null && !javaClass.isStatic
returnTypeRef = buildResolvedTypeRef {
type = firSymbol.constructType(
this@buildJavaClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
@@ -274,7 +325,8 @@ class JavaSymbolProvider(
}
for (javaConstructor in javaClassDeclaredConstructors) {
declarations += prepareJavaConstructor(
visibility = javaConstructor.visibility, psi = (javaConstructor as? JavaElementImpl<*>)?.psi,
visibility = javaConstructor.visibility,
psi = (javaConstructor as? JavaElementImpl<*>)?.psi,
).apply {
this.typeParameters += javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack)
addAnnotationsFrom(this@JavaSymbolProvider.session, javaConstructor, javaTypeParameterStack)
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirRegularClassBuilder
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
@@ -142,15 +141,6 @@ internal class FirJavaClassBuilder : FirRegularClassBuilder(), FirAnnotationCont
@OptIn(FirImplementationDetail::class)
override fun build(): FirJavaClass {
val isInner = !isTopLevel && !isStatic
val status = FirDeclarationStatusImpl(visibility, modality).apply {
this.isInner = isInner
isCompanion = false
isData = false
isInline = false
isFun = classKind == ClassKind.INTERFACE
}
return FirJavaClass(
source,
session,
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.fir.java.declarations
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
@@ -144,13 +144,6 @@ class FirJavaConstructorBuilder : FirConstructorBuilder() {
@OptIn(FirImplementationDetail::class)
override fun build(): FirJavaConstructor {
val status = FirDeclarationStatusImpl(visibility, Modality.FINAL).apply {
isExpect = false
isActual = false
isOverride = false
isInner = this@FirJavaConstructorBuilder.isInner
}
return FirJavaConstructor(
source,
session,
@@ -186,13 +179,6 @@ class FirJavaConstructorBuilder : FirConstructorBuilder() {
throw IllegalStateException()
}
@Deprecated("Modification of 'status' has no impact for FirJavaConstructorBuilder", level = DeprecationLevel.HIDDEN)
override var status: FirDeclarationStatus
get() = throw IllegalStateException()
set(value) {
throw IllegalStateException()
}
@Deprecated("Modification of 'receiverTypeRef' has no impact for FirJavaConstructorBuilder", level = DeprecationLevel.HIDDEN)
override var receiverTypeRef: FirTypeRef?
get() = throw IllegalStateException()
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.java.declarations
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirImplementationDetail
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirFieldBuilder
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol
@@ -147,13 +149,6 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() {
@OptIn(FirImplementationDetail::class)
override fun build(): FirJavaField {
val status: FirDeclarationStatus = FirDeclarationStatusImpl(visibility, modality).apply {
isStatic = this@FirJavaFieldBuilder.isStatic
isExpect = false
isActual = false
isOverride = false
}
return FirJavaField(
source,
session,
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirBlock
@@ -23,7 +22,6 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.util.OperatorNameConventions.ASSIGNMENT_OPERATIONS
import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES
import org.jetbrains.kotlin.util.OperatorNameConventions.COMPARE_TO
@@ -72,7 +70,7 @@ class FirJavaMethod @FirImplementationDetail constructor(
typeParameters,
)
private val ALL_JAVA_OPERATION_NAMES =
val ALL_JAVA_OPERATION_NAMES =
UNARY_OPERATION_NAMES + BINARY_OPERATION_NAMES + ASSIGNMENT_OPERATIONS + DELEGATED_PROPERTY_OPERATORS +
EQUALS + COMPARE_TO + CONTAINS + INVOKE + ITERATOR + GET + SET + NEXT + HAS_NEXT
@@ -92,21 +90,6 @@ class FirJavaMethodBuilder : FirSimpleFunctionBuilder() {
@OptIn(FirImplementationDetail::class)
override fun build(): FirJavaMethod {
val status = FirDeclarationStatusImpl(visibility, modality).apply {
isStatic = this@FirJavaMethodBuilder.isStatic
isExpect = false
isActual = false
isOverride = false
// Approximation: all Java methods with name that allows to use it in operator form are considered operators
// We need here more detailed checks (see modifierChecks.kt)
isOperator = name in ALL_JAVA_OPERATION_NAMES || OperatorNameConventions.COMPONENT_REGEX.matches(name.asString())
isInfix = false
isInline = false
isTailRec = false
isExternal = false
isSuspend = false
}
return FirJavaMethod(
source,
session,
@@ -9,20 +9,14 @@ import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.buildUnaryArgumentList
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.createConstant
@@ -163,7 +157,6 @@ class KotlinDeserializedJvmSymbolsProvider(
val ids = part.typeAliasNameIndex[classId.shortClassName]
if (ids == null || ids.isEmpty()) return@firstNotNullResult null
val aliasProto = ids.map { part.proto.getTypeAlias(it) }.single()
part.context.memberDeserializer.loadTypeAlias(aliasProto).symbol
}
}
@@ -308,7 +301,7 @@ class KotlinDeserializedJvmSymbolsProvider(
private fun findAndDeserializeClass(
classId: ClassId,
parentContext: FirDeserializationContext? = null,
parentContext: FirDeserializationContext? = null
): FirRegularClassSymbol? {
if (hasNoTopLevelClassOf(classId)) return null
if (classesCache.containsKey(classId)) return classesCache[classId]
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.FirPrimaryConstructorBuilde
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.expressions.FirConstKind
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.*
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.Jsr305State
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class FirSignatureEnhancement(
private val owner: FirRegularClass,
@@ -98,6 +100,7 @@ class FirSignatureEnhancement(
isVar = firElement.isVar
isStatic = firElement.isStatic
annotations += firElement.annotations
status = firElement.status
}
return symbol
}
@@ -196,9 +199,18 @@ class FirSignatureEnhancement(
if (firMethod.isPrimary) {
FirPrimaryConstructorBuilder().apply {
returnTypeRef = newReturnTypeRef
status = FirDeclarationStatusImpl(firMethod.visibility, Modality.FINAL).apply {
val resolvedStatus = firMethod.status.safeAs<FirResolvedDeclarationStatus>()
status = if (resolvedStatus != null) {
FirResolvedDeclarationStatusImpl(
firMethod.visibility,
Modality.FINAL
)
} else {
FirDeclarationStatusImpl(firMethod.visibility, Modality.FINAL)
}.apply {
isExpect = false
isActual = false
isOverride = false
isInner = firMethod.isInner
}
this.symbol = symbol
@@ -127,6 +127,7 @@ class JavaClassUseSiteMemberScope(
modality = firSimpleFunction.modality
returnTypeRef = firSimpleFunction.returnTypeRef
isStatic = firSimpleFunction.status.isStatic
status = firSimpleFunction.status
}
}