[FIR] Support captured type parameters in lightTree2fir

This commit is contained in:
simon.ogorodnik
2020-04-06 23:34:22 +03:00
parent 9db69c0b08
commit 797b58669b
3 changed files with 172 additions and 168 deletions
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.builder package org.jetbrains.kotlin.fir.builder
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import kotlinx.collections.immutable.mutate
import org.jetbrains.kotlin.KtNodeTypes.* import org.jetbrains.kotlin.KtNodeTypes.*
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -22,11 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.builder.* import org.jetbrains.kotlin.fir.references.builder.*
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.ANONYMOUS_CLASS_ID import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -81,6 +76,10 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
context.capturedTypeParameters.addAll(0, typeParameters.map { typeParameter -> typeParameter.symbol }) context.capturedTypeParameters.addAll(0, typeParameters.map { typeParameter -> typeParameter.symbol })
} }
fun clearCapturedTypeParameters() {
context.capturedTypeParameters = context.capturedTypeParameters.clear()
}
fun callableIdForName(name: Name, local: Boolean = false) = fun callableIdForName(name: Name, local: Boolean = false) =
when { when {
local -> CallableId(name) local -> CallableId(name)
@@ -145,41 +144,23 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
} }
} }
fun T?.toDelegatedSelfType(firClass: AbstractFirRegularClassBuilder): FirResolvedTypeRef { fun T?.toDelegatedSelfType(firClass: AbstractFirRegularClassBuilder): FirResolvedTypeRef =
toDelegatedSelfType(firClass, firClass.symbol)
fun T?.toDelegatedSelfType(firObject: FirAnonymousObjectBuilder): FirResolvedTypeRef =
toDelegatedSelfType(firObject, firObject.symbol)
private fun T?.toDelegatedSelfType(firClass: FirClassBuilder, symbol: FirClassLikeSymbol<*>): FirResolvedTypeRef {
return buildResolvedTypeRef { return buildResolvedTypeRef {
source = this@toDelegatedSelfType?.toFirSourceElement() source = this@toDelegatedSelfType?.toFirSourceElement()
type = ConeClassLikeTypeImpl( type = ConeClassLikeTypeImpl(
firClass.symbol.toLookupTag(), symbol.toLookupTag(),
firClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(), firClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
false false
) )
} }
} }
fun T?.toDelegatedSelfType(firObject: FirAnonymousObjectBuilder): FirResolvedTypeRef {
return buildResolvedTypeRef {
source = this@toDelegatedSelfType?.toFirSourceElement()
type = ConeClassLikeTypeImpl(
firObject.symbol.toLookupTag(),
firObject.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
false
)
}
}
fun typeParametersFromSelfType(
delegatedSelfTypeRef: FirTypeRef
): List<FirTypeParameterRef> {
return delegatedSelfTypeRef.coneTypeSafe<ConeKotlinType>()
?.typeArguments
?.map {
buildConstructedClassTypeParameterRef {
symbol = ((it as ConeTypeParameterType).lookupTag.symbol as FirTypeParameterSymbol)
}
}
?: emptyList()
}
fun constructorTypeParametersFromConstructedClass(ownerTypeParameters: List<FirTypeParameterRef>): List<FirTypeParameterRef> { fun constructorTypeParametersFromConstructedClass(ownerTypeParameters: List<FirTypeParameterRef>): List<FirTypeParameterRef> {
return ownerTypeParameters.mapNotNull { return ownerTypeParameters.mapNotNull {
val declaredTypeParameter = (it as? FirTypeParameter) ?: return@mapNotNull null val declaredTypeParameter = (it as? FirTypeParameter) ?: return@mapNotNull null
@@ -334,14 +334,11 @@ class DeclarationsConverter(
var identifier: String? = null var identifier: String? = null
val firTypeParameters = mutableListOf<FirTypeParameter>() val firTypeParameters = mutableListOf<FirTypeParameter>()
var primaryConstructor: LighterASTNode? = null var primaryConstructor: LighterASTNode? = null
val superTypeRefs = mutableListOf<FirTypeRef>()
val superTypeCallEntry = mutableListOf<FirExpression>()
var delegatedSuperTypeRef: FirTypeRef? = null
val typeConstraints = mutableListOf<TypeConstraint>() val typeConstraints = mutableListOf<TypeConstraint>()
var classBody: LighterASTNode? = null var classBody: LighterASTNode? = null
var superTypeList: LighterASTNode? = null
var typeParameterList: LighterASTNode? = null var typeParameterList: LighterASTNode? = null
var delegatedConstructorSource: FirLightSourceElement? = null
classNode.forEachChildren { classNode.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
MODIFIER_LIST -> modifiers = convertModifierList(it) MODIFIER_LIST -> modifiers = convertModifierList(it)
@@ -351,12 +348,7 @@ class DeclarationsConverter(
IDENTIFIER -> identifier = it.asText IDENTIFIER -> identifier = it.asText
TYPE_PARAMETER_LIST -> typeParameterList = it TYPE_PARAMETER_LIST -> typeParameterList = it
PRIMARY_CONSTRUCTOR -> primaryConstructor = it PRIMARY_CONSTRUCTOR -> primaryConstructor = it
SUPER_TYPE_LIST -> convertDelegationSpecifiers(it).let { SUPER_TYPE_LIST -> superTypeList = it
delegatedSuperTypeRef = it.delegatedSuperTypeRef
superTypeRefs += it.superTypesRef
superTypeCallEntry += it.delegatedConstructorArguments
delegatedConstructorSource = it.delegatedConstructorSource
}
TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it) TYPE_CONSTRAINT_LIST -> typeConstraints += convertTypeConstraints(it)
CLASS_BODY -> classBody = it CLASS_BODY -> classBody = it
} }
@@ -375,6 +367,7 @@ class DeclarationsConverter(
val isLocal = isClassLocal(classNode) { getParent() } val isLocal = isClassLocal(classNode) { getParent() }
return withChildClassName(className) { return withChildClassName(className) {
withCapturedTypeParameters {
val status = FirDeclarationStatusImpl( val status = FirDeclarationStatusImpl(
if (isLocal) Visibilities.LOCAL else modifiers.getVisibility(), if (isLocal) Visibilities.LOCAL else modifiers.getVisibility(),
modifiers.getModality() modifiers.getModality()
@@ -404,8 +397,22 @@ class DeclarationsConverter(
annotations += modifiers.annotations annotations += modifiers.annotations
typeParameters += firTypeParameters typeParameters += firTypeParameters
if (!status.isInner) clearCapturedTypeParameters()
typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } }
addCapturedTypeParameters(firTypeParameters)
val selfType = classNode.toDelegatedSelfType(this) val selfType = classNode.toDelegatedSelfType(this)
val delegationSpecifiers = superTypeList?.let { convertDelegationSpecifiers(it) }
var delegatedSuperTypeRef: FirTypeRef? = delegationSpecifiers?.delegatedSuperTypeRef
val delegatedConstructorSource: FirLightSourceElement? = delegationSpecifiers?.delegatedConstructorSource
val superTypeCallEntry = delegationSpecifiers?.delegatedConstructorArguments.orEmpty()
val superTypeRefs = mutableListOf<FirTypeRef>()
delegationSpecifiers?.let { superTypeRefs += it.superTypesRef }
when { when {
modifiers.isEnum() && (classKind == ClassKind.ENUM_CLASS) -> { modifiers.isEnum() && (classKind == ClassKind.ENUM_CLASS) -> {
delegatedSuperTypeRef = buildResolvedTypeRef { delegatedSuperTypeRef = buildResolvedTypeRef {
@@ -415,7 +422,7 @@ class DeclarationsConverter(
isNullable = false isNullable = false
) )
} }
superTypeRefs += delegatedSuperTypeRef!! superTypeRefs += delegatedSuperTypeRef
} }
modifiers.isAnnotation() && (classKind == ClassKind.ANNOTATION_CLASS) -> { modifiers.isAnnotation() && (classKind == ClassKind.ANNOTATION_CLASS) -> {
superTypeRefs += implicitAnnotationType superTypeRefs += implicitAnnotationType
@@ -435,7 +442,8 @@ class DeclarationsConverter(
hasDefaultConstructor = if (primaryConstructor != null) !primaryConstructor!!.hasValueParameters() hasDefaultConstructor = if (primaryConstructor != null) !primaryConstructor!!.hasValueParameters()
else secondaryConstructors.isEmpty() || secondaryConstructors.any { !it.hasValueParameters() }, else secondaryConstructors.isEmpty() || secondaryConstructors.any { !it.hasValueParameters() },
delegatedSelfTypeRef = selfType, delegatedSelfTypeRef = selfType,
delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef, superTypeCallEntry = superTypeCallEntry delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef,
superTypeCallEntry = superTypeCallEntry
) )
//parse primary constructor //parse primary constructor
val primaryConstructorWrapper = convertPrimaryConstructor(primaryConstructor, classWrapper, delegatedConstructorSource) val primaryConstructorWrapper = convertPrimaryConstructor(primaryConstructor, classWrapper, delegatedConstructorSource)
@@ -475,6 +483,7 @@ class DeclarationsConverter(
}.build() }.build()
} }
} }
}
/** /**
* @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseObjectLiteral * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseObjectLiteral
@@ -512,6 +521,7 @@ class DeclarationsConverter(
classKind = ClassKind.OBJECT classKind = ClassKind.OBJECT
scopeProvider = baseScopeProvider scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol() symbol = FirAnonymousObjectSymbol()
typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } }
val delegatedSelfType = objectLiteral.toDelegatedSelfType(this) val delegatedSelfType = objectLiteral.toDelegatedSelfType(this)
annotations += modifiers.annotations annotations += modifiers.annotations
this.superTypeRefs += superTypeRefs this.superTypeRefs += superTypeRefs
@@ -527,7 +537,8 @@ class DeclarationsConverter(
superTypeCallEntry = superTypeCallEntry superTypeCallEntry = superTypeCallEntry
) )
//parse primary constructor //parse primary constructor
convertPrimaryConstructor(primaryConstructor, classWrapper, delegatedConstructorSource)?.let { this.declarations += it.firConstructor } convertPrimaryConstructor(primaryConstructor, classWrapper, delegatedConstructorSource)
?.let { this.declarations += it.firConstructor }
//parse declarations //parse declarations
classBody?.let { classBody?.let {
@@ -677,7 +688,7 @@ class DeclarationsConverter(
this.status = status this.status = status
symbol = FirConstructorSymbol(callableIdForClassConstructor()) symbol = FirConstructorSymbol(callableIdForClassConstructor())
annotations += modifiers.annotations annotations += modifiers.annotations
typeParameters += typeParametersFromSelfType(classWrapper.delegatedSelfTypeRef) typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
this.valueParameters += valueParameters.map { it.firValueParameter } this.valueParameters += valueParameters.map { it.firValueParameter }
delegatedConstructor = firDelegatedCall delegatedConstructor = firDelegatedCall
}, valueParameters }, valueParameters
@@ -743,7 +754,7 @@ class DeclarationsConverter(
context.firFunctionTargets += target context.firFunctionTargets += target
annotations += modifiers.annotations annotations += modifiers.annotations
typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
valueParameters += firValueParameters.map { it.firValueParameter } valueParameters += firValueParameters.map { it.firValueParameter }
body = convertFunctionBody(block, null) body = convertFunctionBody(block, null)
context.firFunctionTargets.removeLast() context.firFunctionTargets.removeLast()
@@ -833,8 +844,7 @@ class DeclarationsConverter(
var receiverType: FirTypeRef? = null var receiverType: FirTypeRef? = null
var returnType: FirTypeRef = implicitType var returnType: FirTypeRef = implicitType
val typeConstraints = mutableListOf<TypeConstraint>() val typeConstraints = mutableListOf<TypeConstraint>()
var getter: FirPropertyAccessor? = null val accessors = mutableListOf<LighterASTNode>()
var setter: FirPropertyAccessor? = null
var propertyInitializer: FirExpression? = null var propertyInitializer: FirExpression? = null
var typeParameterList: LighterASTNode? = null var typeParameterList: LighterASTNode? = null
property.forEachChildren { property.forEachChildren {
@@ -848,8 +858,7 @@ class DeclarationsConverter(
PROPERTY_DELEGATE -> delegateExpression = it PROPERTY_DELEGATE -> delegateExpression = it
VAR_KEYWORD -> isVar = true VAR_KEYWORD -> isVar = true
PROPERTY_ACCESSOR -> { PROPERTY_ACCESSOR -> {
val propertyAccessor = convertGetterOrSetter(it, returnType) accessors += it
if (propertyAccessor.isGetter) getter = propertyAccessor else setter = propertyAccessor
} }
else -> if (it.isExpression()) propertyInitializer = expressionConverter.getAsFirExpression(it, "Should have initializer") else -> if (it.isExpression()) propertyInitializer = expressionConverter.getAsFirExpression(it, "Should have initializer")
} }
@@ -899,6 +908,10 @@ class DeclarationsConverter(
this.isLocal = false this.isLocal = false
receiverTypeRef = receiverType receiverTypeRef = receiverType
symbol = FirPropertySymbol(callableIdForName(propertyName)) symbol = FirPropertySymbol(callableIdForName(propertyName))
withCapturedTypeParameters {
typeParameters += firTypeParameters
addCapturedTypeParameters(firTypeParameters)
val delegateBuilder = delegateExpression?.let { val delegateBuilder = delegateExpression?.let {
FirWrappedDelegateExpressionBuilder().apply { FirWrappedDelegateExpressionBuilder().apply {
source = it.toFirSourceElement() source = it.toFirSourceElement()
@@ -913,9 +926,16 @@ class DeclarationsConverter(
isConst = modifiers.isConst() isConst = modifiers.isConst()
isLateInit = modifiers.hasLateinit() isLateInit = modifiers.hasLateinit()
} }
typeParameters += firTypeParameters
this.getter = getter ?: FirDefaultPropertyGetter(null, session, returnType, modifiers.getVisibility())
this.setter = if (isVar) setter ?: FirDefaultPropertySetter(null, session, returnType, modifiers.getVisibility()) else null val convertedAccessors = accessors.map { convertGetterOrSetter(it, returnType) }
this.getter = convertedAccessors.find { it.isGetter }
?: FirDefaultPropertyGetter(null, session, returnType, modifiers.getVisibility())
this.setter =
if (isVar) {
convertedAccessors.find { it.isSetter }
?: FirDefaultPropertySetter(null, session, returnType, modifiers.getVisibility())
} else null
val receiver = delegateExpression?.let { val receiver = delegateExpression?.let {
expressionConverter.getAsFirExpression<FirExpression>(it, "Should have delegate") expressionConverter.getAsFirExpression<FirExpression>(it, "Should have delegate")
@@ -929,6 +949,7 @@ class DeclarationsConverter(
receiver receiver
) )
} }
}
annotations += modifiers.annotations annotations += modifiers.annotations
} }
} }
@@ -1150,12 +1171,14 @@ class DeclarationsConverter(
context.firFunctionTargets += target context.firFunctionTargets += target
annotations += modifiers.annotations annotations += modifiers.annotations
withCapturedTypeParameters {
if (this is FirSimpleFunctionBuilder) { if (this is FirSimpleFunctionBuilder) {
typeParameters += firTypeParameters typeParameters += firTypeParameters
addCapturedTypeParameters(typeParameters)
} }
valueParametersList?.let { list -> valueParameters += convertValueParameters(list).map { it.firValueParameter } } valueParametersList?.let { list -> valueParameters += convertValueParameters(list).map { it.firValueParameter } }
body = convertFunctionBody(block, expression) body = convertFunctionBody(block, expression)
}
context.firFunctionTargets.removeLast() context.firFunctionTargets.removeLast()
}.build().also { }.build().also {
target.bind(it) target.bind(it)
@@ -27,7 +27,7 @@ class ClassWrapper(
val hasDefaultConstructor: Boolean, val hasDefaultConstructor: Boolean,
val delegatedSelfTypeRef: FirTypeRef, val delegatedSelfTypeRef: FirTypeRef,
val delegatedSuperTypeRef: FirTypeRef, val delegatedSuperTypeRef: FirTypeRef,
val superTypeCallEntry: MutableList<FirExpression>, val superTypeCallEntry: List<FirExpression>,
) { ) {
fun isObjectLiteral(): Boolean { fun isObjectLiteral(): Boolean {
return className == SpecialNames.NO_NAME_PROVIDED && isObject() return className == SpecialNames.NO_NAME_PROVIDED && isObject()