FIR tree & builder: support expect / actual
This commit is contained in:
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.modalityModifierType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -58,6 +60,15 @@ class RawFirBuilder(val session: FirSession) {
|
||||
}
|
||||
}
|
||||
|
||||
private val KtDeclaration.platformStatus: FirMemberPlatformStatus
|
||||
get() {
|
||||
return when {
|
||||
hasExpectModifier() -> FirMemberPlatformStatus.EXPECT
|
||||
hasActualModifier() -> FirMemberPlatformStatus.ACTUAL
|
||||
else -> FirMemberPlatformStatus.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Visitor : KtVisitor<FirElement, Unit>() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <R : FirElement> KtElement?.convertSafe(): R? =
|
||||
@@ -252,6 +263,7 @@ class RawFirBuilder(val session: FirSession) {
|
||||
classOrObject.nameAsSafeName,
|
||||
classOrObject.visibility,
|
||||
classOrObject.modality,
|
||||
classOrObject.platformStatus,
|
||||
classKind,
|
||||
isInner = classOrObject.hasModifier(KtTokens.INNER_KEYWORD),
|
||||
isCompanion = (classOrObject as? KtObjectDeclaration)?.isCompanion() == true,
|
||||
@@ -272,6 +284,7 @@ class RawFirBuilder(val session: FirSession) {
|
||||
typeAlias,
|
||||
typeAlias.nameAsSafeName,
|
||||
typeAlias.visibility,
|
||||
typeAlias.platformStatus,
|
||||
typeAlias.getTypeReference().toFirOrErrorType()
|
||||
)
|
||||
typeAlias.extractAnnotationsTo(firTypeAlias)
|
||||
@@ -291,6 +304,7 @@ class RawFirBuilder(val session: FirSession) {
|
||||
function.nameAsSafeName,
|
||||
function.visibility,
|
||||
function.modality,
|
||||
function.platformStatus,
|
||||
function.hasModifier(KtTokens.OVERRIDE_KEYWORD),
|
||||
function.hasModifier(KtTokens.OPERATOR_KEYWORD),
|
||||
function.hasModifier(KtTokens.INFIX_KEYWORD),
|
||||
@@ -349,6 +363,7 @@ class RawFirBuilder(val session: FirSession) {
|
||||
property.nameAsSafeName,
|
||||
property.visibility,
|
||||
property.modality,
|
||||
property.platformStatus,
|
||||
property.hasModifier(KtTokens.OVERRIDE_KEYWORD),
|
||||
property.hasModifier(KtTokens.CONST_KEYWORD),
|
||||
property.receiverTypeReference.convertSafe(),
|
||||
|
||||
@@ -121,6 +121,14 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirMemberPlatformStatus.asString(): String {
|
||||
return when (this) {
|
||||
FirMemberPlatformStatus.DEFAULT -> ""
|
||||
FirMemberPlatformStatus.EXPECT -> "expect "
|
||||
FirMemberPlatformStatus.ACTUAL -> "actual "
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitMemberDeclaration(memberDeclaration: FirMemberDeclaration) {
|
||||
memberDeclaration.annotations.renderAnnotations()
|
||||
if (memberDeclaration.typeParameters.isNotEmpty()) {
|
||||
@@ -129,6 +137,7 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
print("> ")
|
||||
}
|
||||
print(memberDeclaration.visibility.asString() + " " + memberDeclaration.modalityAsString() + " ")
|
||||
print(memberDeclaration.platformStatus.asString())
|
||||
if (memberDeclaration is FirCallableMember && memberDeclaration.isOverride) {
|
||||
print("override ")
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@ interface FirMemberDeclaration : FirTypeParameterContainer, FirNamedDeclaration,
|
||||
|
||||
val modality: Modality?
|
||||
|
||||
val platformStatus: FirMemberPlatformStatus
|
||||
|
||||
val isExpect: Boolean get() = platformStatus == FirMemberPlatformStatus.EXPECT
|
||||
|
||||
val isActual: Boolean get() = platformStatus == FirMemberPlatformStatus.ACTUAL
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
visitor.visitMemberDeclaration(this, data)
|
||||
|
||||
@@ -25,4 +31,10 @@ interface FirMemberDeclaration : FirTypeParameterContainer, FirNamedDeclaration,
|
||||
}
|
||||
super.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
enum class FirMemberPlatformStatus {
|
||||
DEFAULT,
|
||||
EXPECT,
|
||||
ACTUAL
|
||||
}
|
||||
+3
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMember
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.transformSingle
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
@@ -22,10 +23,11 @@ abstract class FirAbstractCallableMember(
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
modality: Modality?,
|
||||
platformStatus: FirMemberPlatformStatus,
|
||||
final override val isOverride: Boolean,
|
||||
final override var receiverType: FirType?,
|
||||
final override var returnType: FirType
|
||||
) : FirAbstractMemberDeclaration(session, psi, name, visibility, modality), FirCallableMember {
|
||||
) : FirAbstractMemberDeclaration(session, psi, name, visibility, modality, platformStatus), FirCallableMember {
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
receiverType = receiverType?.transformSingle(transformer, data)
|
||||
|
||||
+3
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -18,7 +19,8 @@ abstract class FirAbstractMemberDeclaration(
|
||||
psi: PsiElement?,
|
||||
name: Name,
|
||||
final override val visibility: Visibility,
|
||||
final override val modality: Modality?
|
||||
final override val modality: Modality?,
|
||||
override val platformStatus: FirMemberPlatformStatus
|
||||
) : FirAbstractNamedAnnotatedDeclaration(session, psi, name), FirMemberDeclaration {
|
||||
final override val typeParameters = mutableListOf<FirTypeParameter>()
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.transformInplace
|
||||
import org.jetbrains.kotlin.fir.types.FirType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -23,11 +24,12 @@ open class FirClassImpl(
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
modality: Modality?,
|
||||
platformStatus: FirMemberPlatformStatus,
|
||||
final override val classKind: ClassKind,
|
||||
final override val isInner: Boolean,
|
||||
final override val isCompanion: Boolean,
|
||||
final override val isData: Boolean
|
||||
) : FirAbstractMemberDeclaration(session, psi, name, visibility, modality), FirClass {
|
||||
) : FirAbstractMemberDeclaration(session, psi, name, visibility, modality, platformStatus), FirClass {
|
||||
override val superTypes = mutableListOf<FirType>()
|
||||
|
||||
override val declarations = mutableListOf<FirDeclaration>()
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -24,6 +25,7 @@ class FirEnumEntryImpl(
|
||||
name,
|
||||
visibility = Visibilities.UNKNOWN,
|
||||
modality = Modality.FINAL,
|
||||
platformStatus = FirMemberPlatformStatus.DEFAULT,
|
||||
classKind = ClassKind.ENUM_ENTRY,
|
||||
isInner = false,
|
||||
isCompanion = false,
|
||||
|
||||
+3
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirBody
|
||||
@@ -24,6 +25,7 @@ class FirMemberFunctionImpl(
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
modality: Modality?,
|
||||
platformStatus: FirMemberPlatformStatus,
|
||||
isOverride: Boolean,
|
||||
override val isOperator: Boolean,
|
||||
override val isInfix: Boolean,
|
||||
@@ -33,7 +35,7 @@ class FirMemberFunctionImpl(
|
||||
receiverType: FirType?,
|
||||
returnType: FirType,
|
||||
override val body: FirBody?
|
||||
) : FirAbstractCallableMember(session, psi, name, visibility, modality, isOverride, receiverType, returnType),
|
||||
) : FirAbstractCallableMember(session, psi, name, visibility, modality, platformStatus, isOverride, receiverType, returnType),
|
||||
FirNamedFunction {
|
||||
override val valueParameters = mutableListOf<FirValueParameter>()
|
||||
|
||||
|
||||
+3
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
@@ -24,6 +25,7 @@ class FirMemberPropertyImpl(
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
modality: Modality?,
|
||||
platformStatus: FirMemberPlatformStatus,
|
||||
isOverride: Boolean,
|
||||
override val isConst: Boolean,
|
||||
receiverType: FirType?,
|
||||
@@ -33,7 +35,7 @@ class FirMemberPropertyImpl(
|
||||
override var getter: FirPropertyAccessor,
|
||||
override var setter: FirPropertyAccessor,
|
||||
override val delegate: FirExpression?
|
||||
) : FirAbstractCallableMember(session, psi, name, visibility, modality, isOverride, receiverType, returnType),
|
||||
) : FirAbstractCallableMember(session, psi, name, visibility, modality, platformStatus, isOverride, receiverType, returnType),
|
||||
FirProperty {
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
getter = getter.transformSingle(transformer, data)
|
||||
|
||||
+3
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberPlatformStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||
import org.jetbrains.kotlin.fir.transformInplace
|
||||
import org.jetbrains.kotlin.fir.transformSingle
|
||||
@@ -22,8 +23,9 @@ class FirTypeAliasImpl(
|
||||
psi: PsiElement?,
|
||||
name: Name,
|
||||
visibility: Visibility,
|
||||
platformStatus: FirMemberPlatformStatus,
|
||||
override var expandedType: FirType
|
||||
) : FirAbstractMemberDeclaration(session, psi, name, visibility, Modality.FINAL), FirTypeAlias {
|
||||
) : FirAbstractMemberDeclaration(session, psi, name, visibility, Modality.FINAL, platformStatus), FirTypeAlias {
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
typeParameters.transformInplace(transformer, data)
|
||||
expandedType = expandedType.transformSingle(transformer, data)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
expect class MyClass
|
||||
|
||||
expect fun foo(): String
|
||||
|
||||
expect val x: Int
|
||||
|
||||
actual class MyClass
|
||||
|
||||
actual fun foo() = "Hello"
|
||||
|
||||
actual val x = 42
|
||||
@@ -0,0 +1,13 @@
|
||||
FILE: expectActual.kt
|
||||
public? final? expect class MyClass() {
|
||||
}
|
||||
public? final? expect function foo(): String
|
||||
public? final? expect property x(val): Int
|
||||
public? get(): Int
|
||||
public? final? actual class MyClass() {
|
||||
}
|
||||
public? final? actual function foo(): <implicit> {
|
||||
STUB
|
||||
}
|
||||
public? final? actual property x(val): <implicit> = STUB
|
||||
public? get(): <implicit>
|
||||
+5
@@ -61,6 +61,11 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
runTest("compiler/testData/fir/rawBuilder/declarations/enums2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expectActual.kt")
|
||||
public void testExpectActual() throws Exception {
|
||||
runTest("compiler/testData/fir/rawBuilder/declarations/expectActual.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("F.kt")
|
||||
public void testF() throws Exception {
|
||||
runTest("compiler/testData/fir/rawBuilder/declarations/F.kt");
|
||||
|
||||
Reference in New Issue
Block a user