[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:
-19
@@ -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")
|
||||
|
||||
+3
-4
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -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)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// When inner class extends its outer, there are two instances of the outer present in the inner:
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class Foo(val value: String) {
|
||||
|
||||
open inner class Inner(val d: Double = -1.0, val s: String, vararg val y: Int) {
|
||||
|
||||
@@ -90,15 +90,15 @@ FILE fqName:<root> fileName:/annotationClasses.kt
|
||||
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.Test4 [primary]
|
||||
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
|
||||
PROPERTY name:xs visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]
|
||||
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.IntArray visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'xs: kotlin.IntArray [vararg] declared in <root>.Test4.<init>' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.Test4) returnType:kotlin.Array<out kotlin.Int>
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.Test4) returnType:kotlin.IntArray
|
||||
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Test4
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.Int> declared in <root>.Test4'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]' type=kotlin.Array<out kotlin.Int> origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.IntArray declared in <root>.Test4'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.IntArray visibility:private [final]' type=kotlin.IntArray origin=null
|
||||
receiver: GET_VAR '<this>: <root>.Test4 declared in <root>.Test4.<get-xs>' type=<root>.Test4 origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
|
||||
+4
-4
@@ -4,15 +4,15 @@ FILE fqName:<root> fileName:/varargsInAnnotationArguments.kt
|
||||
CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:<root>.A1 [primary]
|
||||
VALUE_PARAMETER name:xs index:0 type:kotlin.IntArray varargElementType:kotlin.Int [vararg]
|
||||
PROPERTY name:xs visibility:public modality:FINAL [val]
|
||||
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]
|
||||
FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.IntArray visibility:private [final]
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'xs: kotlin.IntArray [vararg] declared in <root>.A1.<init>' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A1) returnType:kotlin.Array<out kotlin.Int>
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-xs> visibility:public modality:FINAL <> ($this:<root>.A1) returnType:kotlin.IntArray
|
||||
correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.A1
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.Array<out kotlin.Int> declared in <root>.A1'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array<out kotlin.Int> visibility:private [final]' type=kotlin.Array<out kotlin.Int> origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-xs> (): kotlin.IntArray declared in <root>.A1'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.IntArray visibility:private [final]' type=kotlin.IntArray origin=null
|
||||
receiver: GET_VAR '<this>: <root>.A1 declared in <root>.A1.<get-xs>' type=<root>.A1 origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
|
||||
Reference in New Issue
Block a user