[FIR] Create builtin primitive array types for properties

If the primary constructor has a vararg parameter, the corresponding
property has an array type. This commit creates the builtin array
types for such properties if the vararg element type is primitive,
e.g., CharArray instead of Array.
This commit is contained in:
Juan Chen
2020-05-25 09:08:00 -07:00
committed by Denis Zharkov
parent ed6aceca87
commit adba0a03a6
11 changed files with 34 additions and 44 deletions
@@ -24,24 +24,17 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.builder.*
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeStarProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
import org.jetbrains.kotlin.fir.types.builder.buildUserTypeRef
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
fun String.parseCharacter(): Char? {
// Strip the quotes
@@ -453,18 +446,6 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
}
}
fun FirTypeRef.convertToArrayType(): FirUserTypeRef = buildUserTypeRef {
source = this@convertToArrayType.source
isMarkedNullable = false
qualifier += FirQualifierPartImpl(StandardClassIds.Array.shortClassName).apply {
typeArguments += buildTypeProjectionWithVariance {
source = this@convertToArrayType.source
typeRef = this@convertToArrayType
variance = Variance.OUT_VARIANCE
}
}
}
private val GET_VALUE = Name.identifier("getValue")
private val SET_VALUE = Name.identifier("setValue")
private val PROVIDE_DELEGATE = Name.identifier("provideDelegate")
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.convertToArrayType
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
@@ -14,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.declarations.isFromVararg
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.builder.buildQualifiedAccessExpression
@@ -38,9 +38,6 @@ class ValueParameter(
fun toFirProperty(session: FirSession, callableId: CallableId): FirProperty {
val name = this.firValueParameter.name
var type = this.firValueParameter.returnTypeRef
if (this.firValueParameter.isVararg) {
type = type.convertToArrayType()
}
if (type is FirImplicitTypeRef) {
type = buildErrorTypeRef { diagnostic = ConeSimpleDiagnostic("Incomplete code", DiagnosticKind.Syntax) }
}
@@ -70,6 +67,8 @@ class ValueParameter(
annotations += this@ValueParameter.firValueParameter.annotations
getter = FirDefaultPropertyGetter(null, session, FirDeclarationOrigin.Source, type, modifiers.getVisibility())
setter = if (this.isVar) FirDefaultPropertySetter(null, session, FirDeclarationOrigin.Source, type, modifiers.getVisibility()) else null
}.apply {
this.isFromVararg = firValueParameter.isVararg
}
}
}
@@ -349,9 +349,6 @@ class RawFirBuilder(
private fun KtParameter.toFirProperty(firParameter: FirValueParameter): FirProperty {
require(hasValOrVar())
var type = typeReference.toFirOrErrorType()
if (firParameter.isVararg) {
type = type.convertToArrayType()
}
val status = FirDeclarationStatusImpl(visibility, modality).apply {
isExpect = hasExpectModifier()
isActual = hasActualModifier()
@@ -390,6 +387,8 @@ class RawFirBuilder(
visibility
) else null
extractAnnotationsTo(this)
}.apply {
isFromVararg = firParameter.isVararg
}
}
@@ -91,7 +91,13 @@ class FirTypeResolveTransformer(
override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult<FirDeclaration> {
return withScopeCleanup {
property.addTypeParametersScope()
transformDeclaration(property, data)
val result = transformDeclaration(property, data).single as FirProperty
if (property.isFromVararg == true) {
result.transformTypeToArrayType()
property.getter?.transformReturnTypeRef(StoreType, property.returnTypeRef)
property.setter?.valueParameters?.map { it.transformReturnTypeRef(StoreType, property.returnTypeRef) }
}
result.compose()
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.*
@@ -90,14 +91,18 @@ internal object StoreReceiver : FirTransformer<FirExpression>() {
internal fun FirValueParameter.transformVarargTypeToArrayType() {
if (isVararg) {
val returnType = returnTypeRef.coneTypeUnsafe<ConeKotlinType>()
transformReturnTypeRef(
StoreType,
returnTypeRef.withReplacedConeType(ConeKotlinTypeProjectionOut(returnType).createArrayOf())
)
this.transformTypeToArrayType()
}
}
internal fun FirTypedDeclaration.transformTypeToArrayType() {
val returnType = returnTypeRef.coneTypeUnsafe<ConeKotlinType>()
transformReturnTypeRef(
StoreType,
returnTypeRef.withReplacedConeType(ConeKotlinTypeProjectionOut(returnType).createArrayOf())
)
}
inline fun <T> withScopeCleanup(scopes: MutableList<*>, crossinline l: () -> T): T {
val sizeBefore = scopes.size
return try {
@@ -107,4 +107,7 @@ fun FirRegularClass.addDeclaration(declaration: FirDeclaration) {
is FirSealedClassImpl -> declarations += declaration
else -> throw IllegalStateException()
}
}
}
private object IsFromVarargKey: FirDeclarationDataKey()
var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey)