FIR IDE: introduce symbol modality

This commit is contained in:
Ilya Kirillov
2020-06-29 15:51:49 +03:00
parent 75a96f0153
commit 799a49649c
19 changed files with 79 additions and 14 deletions
@@ -16,10 +16,10 @@ abstract class KtTypeAliasSymbol : KtClassLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.TOP_LEVEL
}
abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(), KtSymbolWithTypeParameters {
abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(), KtSymbolWithTypeParameters, KtSymbolWithModality<KtSymbolModality> {
abstract val classKind: KtClassKind
}
enum class KtClassKind {
CLASS, ABSTRACT_CLASS, ENUM_CLASS, ENUM_ENTRY, ANNOTATION_CLASS, OBJECT, COMPANION_OBJECT, INTERFACE
CLASS, ENUM_CLASS, ENUM_ENTRY, ANNOTATION_CLASS, OBJECT, COMPANION_OBJECT, INTERFACE
}
@@ -15,7 +15,12 @@ abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
}
abstract class KtFunctionSymbol : KtFunctionLikeSymbol(), KtNamedSymbol, KtPossibleExtensionSymbol, KtSymbolWithTypeParameters {
abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
KtNamedSymbol,
KtPossibleExtensionSymbol,
KtSymbolWithTypeParameters,
KtSymbolWithModality<KtCommonSymbolModality> {
abstract val isSuspend: Boolean
abstract val isOperator: Boolean
abstract val fqName: FqName?
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
abstract class KtSymbolProvider : ValidityOwner {
@@ -38,4 +40,6 @@ abstract class KtSymbolProvider : ValidityOwner {
* @return symbol with specified [classId] or `null` in case such symbol is not found
*/
abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol?
abstract fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): Sequence<KtSymbol>
}
@@ -19,12 +19,12 @@ abstract class KtVariableSymbol : KtVariableLikeSymbol() {
abstract val isVal: Boolean
}
abstract class KtFieldSymbol : KtVariableSymbol() {
abstract class KtFieldSymbol : KtVariableSymbol(), KtSymbolWithModality<KtCommonSymbolModality> {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
}
// TODO getters & setters
abstract class KtPropertySymbol : KtVariableSymbol(), KtPossibleExtensionSymbol {
abstract class KtPropertySymbol : KtVariableSymbol(), KtPossibleExtensionSymbol, KtSymbolWithModality<KtCommonSymbolModality> {
abstract val fqName: FqName
}
@@ -32,3 +32,17 @@ interface KtPossibleExtensionSymbol {
interface KtSymbolWithTypeParameters {
val typeParameters: List<KtTypeParameterSymbol>
}
interface KtSymbolWithModality<M : KtSymbolModality> {
val modality: M
}
sealed class KtSymbolModality {
object SEALED : KtSymbolModality()
}
sealed class KtCommonSymbolModality : KtSymbolModality() {
object FINAL : KtCommonSymbolModality()
object ABSTRACT : KtCommonSymbolModality()
object OPEN : KtCommonSymbolModality()
}
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.ReadOnlyWeakRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -31,6 +29,9 @@ internal class KtFirClassOrObjectSymbol(
override val name: Name get() = withValidityAssertion { fir.classId.shortClassName }
override val classId: ClassId get() = withValidityAssertion { fir.classId }
override val modality: KtSymbolModality
get() = withValidityAssertion { fir.modality.getSymbolModality() }
override val typeParameters by cached {
fir.typeParameters.map { typeParameter ->
builder.buildTypeParameterSymbol(typeParameter.symbol.fir)
@@ -44,7 +45,7 @@ internal class KtFirClassOrObjectSymbol(
ClassKind.ENUM_CLASS -> KtClassKind.ENUM_CLASS
ClassKind.ENUM_ENTRY -> KtClassKind.ENUM_ENTRY
ClassKind.ANNOTATION_CLASS -> KtClassKind.ANNOTATION_CLASS
ClassKind.CLASS -> if (fir.modality == Modality.ABSTRACT) KtClassKind.ABSTRACT_CLASS else KtClassKind.CLASS
ClassKind.CLASS -> KtClassKind.CLASS
ClassKind.OBJECT -> if (fir.isCompanion) KtClassKind.COMPANION_OBJECT else KtClassKind.OBJECT
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.KtType
@@ -7,12 +7,14 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirField
import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.KtType
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFieldSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
@@ -28,4 +30,6 @@ internal class KtFirFieldSymbol(
override val type: KtType by cached { builder.buildKtType(fir.returnTypeRef) }
override val isVal: Boolean get() = withValidityAssertion { fir.isVal }
override val name: Name get() = withValidityAssertion { fir.name }
override val modality: KtCommonSymbolModality get() = withValidityAssertion { fir.modality.getSymbolModality() }
}
@@ -6,17 +6,15 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.declarations.isLocal
import org.jetbrains.kotlin.fir.declarations.isOperator
import org.jetbrains.kotlin.fir.declarations.isSuspend
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
@@ -56,4 +54,5 @@ internal class KtFirFunctionSymbol(
else -> KtSymbolKind.MEMBER
}
}
override val modality: KtCommonSymbolModality get() = withValidityAssertion { fir.modality.getSymbolModality() }
}
@@ -7,12 +7,14 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
import org.jetbrains.kotlin.idea.frontend.api.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
@@ -44,4 +46,5 @@ internal class KtFirPropertySymbol(
else -> KtSymbolKind.MEMBER
}
}
override val modality: KtCommonSymbolModality get() = withValidityAssertion { fir.modality.getSymbolModality() }
}
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
internal class KtFirSymbolProvider(
@@ -68,4 +70,9 @@ internal class KtFirSymbolProvider(
val symbol = firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: return null
firSymbolBuilder.buildClassSymbol(symbol.fir)
}
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): Sequence<KtSymbol> {
val firs = firSymbolProvider.getTopLevelCallableSymbols(packageFqName, name)
return firs.asSequence().map { firSymbol -> firSymbolBuilder.buildSymbol(firSymbol.fir) }
}
}
@@ -0,0 +1,18 @@
/*
* 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.idea.frontend.api.fir.symbols
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolModality
internal inline fun <reified M : KtSymbolModality> Modality?.getSymbolModality(): M = when (this) {
Modality.FINAL -> KtCommonSymbolModality.FINAL
Modality.OPEN -> KtCommonSymbolModality.OPEN
Modality.ABSTRACT -> KtCommonSymbolModality.ABSTRACT
Modality.SEALED -> KtSymbolModality.SEALED
null -> error("Symbol modality should not be null, looks like the fir symbol was not properly resolved")
} as? M ?: error("Sealed modality can only be applied to class")
+1
View File
@@ -6,6 +6,7 @@ class A {
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
@@ -9,6 +9,7 @@ KtFirPropertySymbol:
fqName: A.a
isExtension: false
isVal: true
modality: FINAL
name: a
origin: SOURCE
receiverType: kotlin/Int
@@ -20,6 +21,7 @@ KtFirFunctionSymbol:
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: x
origin: SOURCE
symbolKind: MEMBER
@@ -30,6 +32,7 @@ KtFirFunctionSymbol:
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
@@ -14,6 +14,7 @@ KtFirTypeParameterSymbol:
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
@@ -7,6 +7,7 @@ KtFirFunctionSymbol:
isExtension: true
isOperator: false
isSuspend: false
modality: FINAL
name: foo
origin: SOURCE
receiverType: kotlin/String
@@ -14,6 +14,7 @@ KtFirFunctionSymbol:
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: foo
origin: SOURCE
symbolKind: TOP_LEVEL
@@ -18,6 +18,7 @@ KtFirFunctionSymbol:
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: foo
origin: SOURCE
symbolKind: TOP_LEVEL
@@ -7,6 +7,7 @@ KtFirFunctionSymbol:
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: foo
origin: SOURCE
symbolKind: TOP_LEVEL