From adba0a03a67e3862d508bc98094a2aaefd956871 Mon Sep 17 00:00:00 2001 From: Juan Chen Date: Mon, 25 May 2020 09:08:00 -0700 Subject: [PATCH] [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. --- .../kotlin/fir/builder/ConversionUtils.kt | 19 ------------------- .../fir/lightTree/fir/ValueParameter.kt | 7 +++---- .../kotlin/fir/builder/RawFirBuilder.kt | 5 ++--- .../transformers/FirTypeResolveTransformer.kt | 8 +++++++- .../resolve/transformers/TransformUtils.kt | 15 ++++++++++----- .../fir/declarations/FirDeclarationUtil.kt | 5 ++++- .../superConstructorCall/innerExtendsOuter.kt | 1 - .../createAnnotation/callByWithEmptyVarArg.kt | 1 - .../superConstructor/objectExtendsInner.kt | 1 - .../irText/classes/annotationClasses.fir.txt | 8 ++++---- .../varargsInAnnotationArguments.fir.txt | 8 ++++---- 11 files changed, 34 insertions(+), 44 deletions(-) diff --git a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index ed6425d2551..3eedacd60b1 100644 --- a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -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") diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt index 0a5e0aff6e5..44dd6d10efa 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt @@ -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 } } } diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 44d80d77c98..8a44d5b1390 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -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 } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 06dc806cc85..7be5506aaf9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -91,7 +91,13 @@ class FirTypeResolveTransformer( override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult { 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() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt index 97fe940deee..82bf24ea622 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt @@ -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() { internal fun FirValueParameter.transformVarargTypeToArrayType() { if (isVararg) { - val returnType = returnTypeRef.coneTypeUnsafe() - transformReturnTypeRef( - StoreType, - returnTypeRef.withReplacedConeType(ConeKotlinTypeProjectionOut(returnType).createArrayOf()) - ) + this.transformTypeToArrayType() } } +internal fun FirTypedDeclaration.transformTypeToArrayType() { + val returnType = returnTypeRef.coneTypeUnsafe() + transformReturnTypeRef( + StoreType, + returnTypeRef.withReplacedConeType(ConeKotlinTypeProjectionOut(returnType).createArrayOf()) + ) +} + inline fun withScopeCleanup(scopes: MutableList<*>, crossinline l: () -> T): T { val sizeBefore = scopes.size return try { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt index 1e12565d259..ae62acf07a1 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt @@ -107,4 +107,7 @@ fun FirRegularClass.addDeclaration(declaration: FirDeclaration) { is FirSealedClassImpl -> declarations += declaration else -> throw IllegalStateException() } -} \ No newline at end of file +} + +private object IsFromVarargKey: FirDeclarationDataKey() +var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey) diff --git a/compiler/testData/codegen/box/innerNested/superConstructorCall/innerExtendsOuter.kt b/compiler/testData/codegen/box/innerNested/superConstructorCall/innerExtendsOuter.kt index 67dd1aa3c41..8db3bfa10ca 100644 --- a/compiler/testData/codegen/box/innerNested/superConstructorCall/innerExtendsOuter.kt +++ b/compiler/testData/codegen/box/innerNested/superConstructorCall/innerExtendsOuter.kt @@ -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: diff --git a/compiler/testData/codegen/box/reflection/createAnnotation/callByWithEmptyVarArg.kt b/compiler/testData/codegen/box/reflection/createAnnotation/callByWithEmptyVarArg.kt index 362533bddf5..31eeee2a193 100644 --- a/compiler/testData/codegen/box/reflection/createAnnotation/callByWithEmptyVarArg.kt +++ b/compiler/testData/codegen/box/reflection/createAnnotation/callByWithEmptyVarArg.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/super/superConstructor/objectExtendsInner.kt b/compiler/testData/codegen/box/super/superConstructor/objectExtendsInner.kt index 20711c88538..83d075cdeae 100644 --- a/compiler/testData/codegen/box/super/superConstructor/objectExtendsInner.kt +++ b/compiler/testData/codegen/box/super/superConstructor/objectExtendsInner.kt @@ -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) { diff --git a/compiler/testData/ir/irText/classes/annotationClasses.fir.txt b/compiler/testData/ir/irText/classes/annotationClasses.fir.txt index a19905c3366..dbedffd8016 100644 --- a/compiler/testData/ir/irText/classes/annotationClasses.fir.txt +++ b/compiler/testData/ir/irText/classes/annotationClasses.fir.txt @@ -90,15 +90,15 @@ FILE fqName: fileName:/annotationClasses.kt CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:.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 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 .Test4.' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Test4) returnType:kotlin.Array + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Test4) returnType:kotlin.IntArray correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val] $this: VALUE_PARAMETER name: type:.Test4 BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array declared in .Test4' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array visibility:private [final]' type=kotlin.Array origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.IntArray declared in .Test4' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.IntArray visibility:private [final]' type=kotlin.IntArray origin=null receiver: GET_VAR ': .Test4 declared in .Test4.' type=.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: diff --git a/compiler/testData/ir/irText/declarations/annotations/varargsInAnnotationArguments.fir.txt b/compiler/testData/ir/irText/declarations/annotations/varargsInAnnotationArguments.fir.txt index 12d1ff411bb..6f202169e11 100644 --- a/compiler/testData/ir/irText/declarations/annotations/varargsInAnnotationArguments.fir.txt +++ b/compiler/testData/ir/irText/declarations/annotations/varargsInAnnotationArguments.fir.txt @@ -4,15 +4,15 @@ FILE fqName: fileName:/varargsInAnnotationArguments.kt CONSTRUCTOR visibility:public <> (xs:kotlin.IntArray) returnType:.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 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 .A1.' type=kotlin.IntArray origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.A1) returnType:kotlin.Array + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.A1) returnType:kotlin.IntArray correspondingProperty: PROPERTY name:xs visibility:public modality:FINAL [val] $this: VALUE_PARAMETER name: type:.A1 BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array declared in .A1' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.Array visibility:private [final]' type=kotlin.Array origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.IntArray declared in .A1' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:xs type:kotlin.IntArray visibility:private [final]' type=kotlin.IntArray origin=null receiver: GET_VAR ': .A1 declared in .A1.' type=.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: