[FIR builder] create error types for vararg parameters correctly
Otherwise, such types are treated as resolved, but anyway requires transformation on type phase. Also, this commit drops the redundant duplicated transformation of typeReference from primary constructor property generator ^KT-61422
This commit is contained in:
committed by
Space Team
parent
c0c1966555
commit
f1e5a9b223
+10
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -24,8 +24,10 @@ import org.jetbrains.kotlin.fir.correspondingProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.varargElementType
|
||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
internal class KtFirValueParameterSymbol(
|
||||
override val firSymbol: FirValueParameterSymbol,
|
||||
@@ -49,7 +51,12 @@ internal class KtFirValueParameterSymbol(
|
||||
override val returnType by cached {
|
||||
val returnType = firSymbol.resolvedReturnType
|
||||
if (firSymbol.isVararg) {
|
||||
builder.typeBuilder.buildKtType(returnType.varargElementType())
|
||||
// There SHOULD always be an array element type (even if it is an error type, e.g., unresolved).
|
||||
val arrayElementType = returnType.arrayElementType()
|
||||
?: errorWithAttachment("No array element type for vararg value parameter") {
|
||||
withFirSymbolEntry("symbol", firSymbol)
|
||||
}
|
||||
builder.typeBuilder.buildKtType(arrayElementType)
|
||||
} else {
|
||||
builder.typeBuilder.buildKtType(returnType)
|
||||
}
|
||||
|
||||
+4
-3
@@ -2311,9 +2311,10 @@ class LightTreeRawFirDeclarationBuilder(
|
||||
}
|
||||
}
|
||||
container += buildFunctionTypeParameter {
|
||||
source = node.toFirSourceElement()
|
||||
val parameterSource = node.toFirSourceElement()
|
||||
source = parameterSource
|
||||
this.name = name
|
||||
this.returnTypeRef = typeRef ?: createNoTypeForParameterTypeRef()
|
||||
this.returnTypeRef = typeRef ?: createNoTypeForParameterTypeRef(parameterSource)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2373,7 +2374,7 @@ class LightTreeRawFirDeclarationBuilder(
|
||||
modifiers = modifiers,
|
||||
returnTypeRef = firType
|
||||
?: when {
|
||||
valueParameterDeclaration.shouldExplicitParameterTypeBePresent -> createNoTypeForParameterTypeRef()
|
||||
valueParameterDeclaration.shouldExplicitParameterTypeBePresent -> createNoTypeForParameterTypeRef(valueParameterSource)
|
||||
else -> implicitType
|
||||
},
|
||||
source = valueParameterSource,
|
||||
|
||||
+11
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.lightTree.fir
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.builder.Context
|
||||
import org.jetbrains.kotlin.fir.builder.appliesToPrimaryConstructorParameter
|
||||
import org.jetbrains.kotlin.fir.builder.filterUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.builder.initContainingClassAttr
|
||||
import org.jetbrains.kotlin.fir.builder.wrapIntoArray
|
||||
import org.jetbrains.kotlin.fir.copy
|
||||
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
|
||||
import org.jetbrains.kotlin.fir.correspondingProperty
|
||||
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
@@ -77,13 +79,18 @@ class ValueParameter(
|
||||
source = this@ValueParameter.source
|
||||
moduleData = this@ValueParameter.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
returnTypeRef = this@ValueParameter.returnTypeRef
|
||||
isVararg = modifiers.hasVararg()
|
||||
returnTypeRef = if (isVararg && this@ValueParameter.returnTypeRef is FirErrorTypeRef) {
|
||||
this@ValueParameter.returnTypeRef.wrapIntoArray()
|
||||
} else {
|
||||
this@ValueParameter.returnTypeRef
|
||||
}
|
||||
|
||||
this.name = this@ValueParameter.name
|
||||
symbol = FirValueParameterSymbol(name)
|
||||
defaultValue = this@ValueParameter.defaultValue
|
||||
isCrossinline = modifiers.hasCrossinline()
|
||||
isNoinline = modifiers.hasNoinline()
|
||||
isVararg = modifiers.hasVararg()
|
||||
containingFunctionSymbol = this@ValueParameter.containingFunctionSymbol
|
||||
?: error("containingFunctionSymbol should present when converting ValueParameter to a FirValueParameter")
|
||||
|
||||
|
||||
+27
-8
@@ -635,15 +635,24 @@ open class PsiRawFirBuilder(
|
||||
): FirValueParameter {
|
||||
val name = convertValueParameterName(nameAsSafeName, valueParameterDeclaration) { nameIdentifier?.node?.text }
|
||||
return buildValueParameter {
|
||||
source = toFirSourceElement()
|
||||
val parameterSource = toFirSourceElement()
|
||||
source = parameterSource
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
isVararg = isVarArg
|
||||
returnTypeRef = when {
|
||||
typeReference != null -> typeReference.toFirOrErrorType()
|
||||
defaultTypeRef != null -> defaultTypeRef
|
||||
valueParameterDeclaration.shouldExplicitParameterTypeBePresent -> createNoTypeForParameterTypeRef()
|
||||
valueParameterDeclaration.shouldExplicitParameterTypeBePresent -> createNoTypeForParameterTypeRef(parameterSource)
|
||||
else -> null.toFirOrImplicitType()
|
||||
}.let {
|
||||
if (isVararg && it is FirErrorTypeRef) {
|
||||
it.wrapIntoArray()
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
this.name = name
|
||||
symbol = FirValueParameterSymbol(name)
|
||||
defaultValue = if (hasDefaultValue()) {
|
||||
@@ -651,7 +660,6 @@ open class PsiRawFirBuilder(
|
||||
} else null
|
||||
isCrossinline = hasModifier(CROSSINLINE_KEYWORD)
|
||||
isNoinline = hasModifier(NOINLINE_KEYWORD)
|
||||
isVararg = isVarArg
|
||||
containingFunctionSymbol = functionSymbol
|
||||
addAnnotationsFrom(
|
||||
this@toFirValueParameter,
|
||||
@@ -673,14 +681,23 @@ open class PsiRawFirBuilder(
|
||||
|
||||
private fun KtParameter.toFirProperty(firParameter: FirValueParameter): FirProperty {
|
||||
require(hasValOrVar())
|
||||
val type = typeReference.convertSafe<FirTypeRef>() ?: createNoTypeForParameterTypeRef()
|
||||
val status = FirDeclarationStatusImpl(visibility, modality).apply {
|
||||
isExpect = hasExpectModifier() || this@PsiRawFirBuilder.context.containerIsExpect
|
||||
isActual = hasActualModifier()
|
||||
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
||||
isConst = hasModifier(CONST_KEYWORD)
|
||||
}
|
||||
|
||||
val propertySource = toFirSourceElement(KtFakeSourceElementKind.PropertyFromParameter)
|
||||
// We can't just reuse a type from firParameter to avoid annotation leak.
|
||||
val type = (typeReference.convertSafe<FirTypeRef>() ?: createNoTypeForParameterTypeRef(propertySource)).let {
|
||||
if (it is FirErrorTypeRef && firParameter.isVararg) {
|
||||
it.wrapIntoArray()
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
val propertyName = nameAsSafeName
|
||||
val parameterAnnotations = mutableListOf<FirAnnotationCall>()
|
||||
for (annotationEntry in annotationEntries) {
|
||||
@@ -2163,11 +2180,12 @@ open class PsiRawFirBuilder(
|
||||
returnTypeRef = unwrappedElement.returnTypeReference.toFirOrErrorType()
|
||||
for (valueParameter in unwrappedElement.parameters) {
|
||||
parameters += buildFunctionTypeParameter {
|
||||
this.source = valueParameter.toFirSourceElement()
|
||||
val parameterSource = valueParameter.toFirSourceElement()
|
||||
this.source = parameterSource
|
||||
name = valueParameter.nameAsName
|
||||
returnTypeRef = when {
|
||||
valueParameter.typeReference != null -> valueParameter.typeReference.toFirOrErrorType()
|
||||
else -> createNoTypeForParameterTypeRef()
|
||||
else -> createNoTypeForParameterTypeRef(parameterSource)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2357,12 +2375,13 @@ open class PsiRawFirBuilder(
|
||||
) { ktParameter.nameIdentifier?.node?.text }
|
||||
|
||||
buildProperty {
|
||||
source = ktParameter.toFirSourceElement()
|
||||
val parameterSource = ktParameter.toFirSourceElement()
|
||||
source = parameterSource
|
||||
moduleData = baseModuleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
returnTypeRef = when {
|
||||
ktParameter.typeReference != null -> ktParameter.typeReference.toFirOrErrorType()
|
||||
else -> createNoTypeForParameterTypeRef()
|
||||
else -> createNoTypeForParameterTypeRef(parameterSource)
|
||||
}
|
||||
isVar = false
|
||||
status = FirResolvedDeclarationStatusImpl(Visibilities.Local, Modality.FINAL, EffectiveVisibility.Local)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FILE: noParameterTypRefInPrimaryConstructorWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? constructor(vararg x: <ERROR TYPE REF: No type for parameter>): R|X| {
|
||||
public? constructor(vararg x: R|kotlin/Array<out ERROR CLASS: No type for parameter>|): R|X| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FILE: noParameterTypRefInPrimaryConstructorWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=X] constructor(vararg x: <ERROR TYPE REF: No type for parameter>): R|X| {
|
||||
public? [ContainingClassKey=X] constructor(vararg x: R|kotlin/Array<out ERROR CLASS: No type for parameter>|): R|X| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
FILE: noParameterTypRefInPrimaryConsturctorValWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? constructor(vararg x: <ERROR TYPE REF: No type for parameter>): R|X| {
|
||||
public? constructor(vararg x: R|kotlin/Array<out ERROR CLASS: No type for parameter>|): R|X| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? final? val x: <ERROR TYPE REF: No type for parameter> = R|<local>/x|
|
||||
public? get(): <ERROR TYPE REF: No type for parameter>
|
||||
public? final? val x: R|kotlin/Array<out ERROR CLASS: No type for parameter>| = R|<local>/x|
|
||||
public? get(): R|kotlin/Array<out ERROR CLASS: No type for parameter>|
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
FILE: noParameterTypRefInPrimaryConsturctorValWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=X] constructor([CorrespondingProperty=/X.x] vararg x: <ERROR TYPE REF: No type for parameter>): R|X| {
|
||||
public? [ContainingClassKey=X] constructor([CorrespondingProperty=/X.x] vararg x: R|kotlin/Array<out ERROR CLASS: No type for parameter>|): R|X| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public? final? [IsFromPrimaryConstructor=true, IsFromVarargKey=true] val x: <ERROR TYPE REF: No type for parameter> = R|<local>/x|
|
||||
public? [ContainingClassKey=X] get(): <ERROR TYPE REF: No type for parameter>
|
||||
public? final? [IsFromPrimaryConstructor=true, IsFromVarargKey=true] val x: R|kotlin/Array<out ERROR CLASS: No type for parameter>| = R|<local>/x|
|
||||
public? [ContainingClassKey=X] get(): R|kotlin/Array<out ERROR CLASS: No type for parameter>|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FILE: uncompletedTypRefInPrimaryConstructorWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? constructor(vararg x: <ERROR TYPE REF: Incomplete code>): R|X| {
|
||||
public? constructor(vararg x: R|kotlin/Array<out ERROR CLASS: Incomplete code>|): R|X| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FILE: uncompletedTypRefInPrimaryConstructorWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=X] constructor(vararg x: <ERROR TYPE REF: Incomplete code>): R|X| {
|
||||
public? [ContainingClassKey=X] constructor(vararg x: R|kotlin/Array<out ERROR CLASS: Incomplete code>|): R|X| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
FILE: uncompletedTypRefInPrimaryConsturctorValWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? constructor(vararg x: <ERROR TYPE REF: Incomplete code>): R|X| {
|
||||
public? constructor(vararg x: R|kotlin/Array<out ERROR CLASS: Incomplete code>|): R|X| {
|
||||
LAZY_super<R|kotlin/Any|>
|
||||
}
|
||||
|
||||
public? final? val x: <ERROR TYPE REF: Incomplete code> = R|<local>/x|
|
||||
public? get(): <ERROR TYPE REF: Incomplete code>
|
||||
public? final? val x: R|kotlin/Array<out ERROR CLASS: Incomplete code>| = R|<local>/x|
|
||||
public? get(): R|kotlin/Array<out ERROR CLASS: Incomplete code>|
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
FILE: uncompletedTypRefInPrimaryConsturctorValWithVararg.kt
|
||||
public? final? class X : R|kotlin/Any| {
|
||||
public? [ContainingClassKey=X] constructor([CorrespondingProperty=/X.x] vararg x: <ERROR TYPE REF: Incomplete code>): R|X| {
|
||||
public? [ContainingClassKey=X] constructor([CorrespondingProperty=/X.x] vararg x: R|kotlin/Array<out ERROR CLASS: Incomplete code>|): R|X| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public? final? [IsFromPrimaryConstructor=true, IsFromVarargKey=true] val x: <ERROR TYPE REF: Incomplete code> = R|<local>/x|
|
||||
public? [ContainingClassKey=X] get(): <ERROR TYPE REF: Incomplete code>
|
||||
public? final? [IsFromPrimaryConstructor=true, IsFromVarargKey=true] val x: R|kotlin/Array<out ERROR CLASS: Incomplete code>| = R|<local>/x|
|
||||
public? [ContainingClassKey=X] get(): R|kotlin/Array<out ERROR CLASS: Incomplete code>|
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -1078,8 +1078,9 @@ abstract class AbstractRawFirBuilder<T>(val baseSession: FirSession, val context
|
||||
symbol = FirErrorPropertySymbol(diagnostic)
|
||||
}
|
||||
|
||||
protected fun createNoTypeForParameterTypeRef(): FirErrorTypeRef {
|
||||
protected fun createNoTypeForParameterTypeRef(parameterSource: KtSourceElement): FirErrorTypeRef {
|
||||
return buildErrorTypeRef {
|
||||
source = parameterSource
|
||||
diagnostic = ConeSimpleDiagnostic("No type for parameter", DiagnosticKind.ValueParameterWithNoTypeAnnotation)
|
||||
}
|
||||
}
|
||||
|
||||
+14
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -40,10 +40,14 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjectionOut
|
||||
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.constructClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImplWithoutSource
|
||||
@@ -705,3 +709,12 @@ fun KtSourceElement.withForcedKindFrom(context: Context<*>): KtSourceElement {
|
||||
else -> this.realElement()
|
||||
}
|
||||
}
|
||||
|
||||
fun FirErrorTypeRef.wrapIntoArray(): FirResolvedTypeRef {
|
||||
val typeRef = this
|
||||
return buildResolvedTypeRef {
|
||||
source = typeRef.source
|
||||
type = StandardClassIds.Array.constructClassLikeType(arrayOf(ConeKotlinTypeProjectionOut(typeRef.coneType)))
|
||||
delegatedTypeRef = typeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ArrayTypeFromVarargParameter)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user