FIR tree & builder: support expect / actual

This commit is contained in:
Mikhail Glukhikh
2018-03-22 10:15:57 +03:00
parent d16303342e
commit 4d48c40832
13 changed files with 85 additions and 6 deletions
@@ -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
}
@@ -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)
@@ -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,
@@ -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>()
@@ -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)
@@ -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>
@@ -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");