[FIR] Resolve arguments of error types during type resolution
This commit is contained in:
committed by
Space Team
parent
bc93556dbb
commit
bd26c29229
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
KtType: suspend (kotlin.Int) -> kotlin.Unit
|
KtType: suspend (kotlin.Int) -> kotlin.Unit
|
||||||
PsiType: PsiType:Function2<? super Integer, ? super NonExistentClass, ? extends Object>
|
PsiType: PsiType:Function2<? super Integer, ? super NonExistentClass<Unit>, ? extends Object>
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
Resolved to:
|
Resolved to:
|
||||||
0: (in Controller) suspend fun suspendHere(x: ERROR_TYPE(Symbol not found for Continuation))
|
0: (in Controller) suspend fun suspendHere(x: ERROR_TYPE(Symbol not found for Continuation))
|
||||||
|
|||||||
+2
-1
@@ -12,11 +12,12 @@ import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt
|
|||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.analyze
|
import org.jetbrains.kotlin.analysis.api.analyze
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt
|
import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
|
||||||
internal fun PsiElement.nonExistentType(): PsiType =
|
internal fun PsiElement.nonExistentType(): PsiType =
|
||||||
JavaPsiFacade.getElementFactory(project).createTypeFromText("error.NonExistentClass", this)
|
JavaPsiFacade.getElementFactory(project).createTypeFromText(StandardNames.NON_EXISTENT_CLASS.asString(), this)
|
||||||
|
|
||||||
@OptIn(KtAllowAnalysisOnEdt::class)
|
@OptIn(KtAllowAnalysisOnEdt::class)
|
||||||
private inline fun <E> allowLightClassesOnEdt(crossinline action: () -> E): E = allowAnalysisOnEdt(action)
|
private inline fun <E> allowLightClassesOnEdt(crossinline action: () -> E): E = allowAnalysisOnEdt(action)
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JAVA_LANG_RECORD_FQ_NAME
|
import org.jetbrains.kotlin.resolve.jvm.JAVA_LANG_RECORD_FQ_NAME
|
||||||
@@ -76,6 +75,7 @@ import org.jetbrains.kotlin.types.checker.convertVariance
|
|||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.zipWithNulls
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
@@ -1446,10 +1446,10 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
SimpleClassicTypeSystemContext.getVarianceForWildcard(parameter, projection, mode)
|
SimpleClassicTypeSystemContext.getVarianceForWildcard(parameter, projection, mode)
|
||||||
|
|
||||||
private fun TypeSystemCommonBackendContext.getVarianceForWildcard(
|
private fun TypeSystemCommonBackendContext.getVarianceForWildcard(
|
||||||
parameter: TypeParameterMarker, projection: TypeArgumentMarker, mode: TypeMappingMode
|
parameter: TypeParameterMarker?, projection: TypeArgumentMarker, mode: TypeMappingMode
|
||||||
): Variance {
|
): Variance {
|
||||||
val projectionKind = projection.getVariance().convertVariance()
|
val projectionKind = projection.getVariance().convertVariance()
|
||||||
val parameterVariance = parameter.getVariance().convertVariance()
|
val parameterVariance = parameter?.getVariance()?.convertVariance() ?: Variance.INVARIANT
|
||||||
|
|
||||||
if (parameterVariance == Variance.INVARIANT) {
|
if (parameterVariance == Variance.INVARIANT) {
|
||||||
return projectionKind
|
return projectionKind
|
||||||
@@ -1465,7 +1465,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
return Variance.INVARIANT
|
return Variance.INVARIANT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameterVariance == Variance.IN_VARIANCE && isMostPreciseContravariantArgument(projection.getType(), parameter)) {
|
if (parameterVariance == Variance.IN_VARIANCE && isMostPreciseContravariantArgument(projection.getType())) {
|
||||||
return Variance.INVARIANT
|
return Variance.INVARIANT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1484,10 +1484,11 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
mode: TypeMappingMode,
|
mode: TypeMappingMode,
|
||||||
mapType: (KotlinTypeMarker, JvmSignatureWriter, TypeMappingMode) -> Type
|
mapType: (KotlinTypeMarker, JvmSignatureWriter, TypeMappingMode) -> Type
|
||||||
) {
|
) {
|
||||||
for ((parameter, argument) in parameters.zip(arguments)) {
|
for ((parameter, argument) in parameters.zipWithNulls(arguments)) {
|
||||||
|
if (argument == null) break
|
||||||
if (argument.isStarProjection() ||
|
if (argument.isStarProjection() ||
|
||||||
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
|
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
|
||||||
argument.getType().isNothing() && parameter.getVariance() == TypeVariance.IN
|
argument.getType().isNothing() && parameter?.getVariance() == TypeVariance.IN
|
||||||
) {
|
) {
|
||||||
signatureVisitor.writeUnboundedWildcard()
|
signatureVisitor.writeUnboundedWildcard()
|
||||||
} else {
|
} else {
|
||||||
@@ -1496,10 +1497,11 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
|
|
||||||
signatureVisitor.writeTypeArgument(projectionKind)
|
signatureVisitor.writeTypeArgument(projectionKind)
|
||||||
|
|
||||||
|
val parameterVariance = parameter?.getVariance()?.convertVariance() ?: Variance.INVARIANT
|
||||||
mapType(
|
mapType(
|
||||||
argument.getType(), signatureVisitor,
|
argument.getType(), signatureVisitor,
|
||||||
argumentMode.toGenericArgumentMode(
|
argumentMode.toGenericArgumentMode(
|
||||||
getEffectiveVariance(parameter.getVariance().convertVariance(), argument.getVariance().convertVariance())
|
getEffectiveVariance(parameterVariance, argument.getVariance().convertVariance())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,8 @@ import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
|
|||||||
import org.jetbrains.kotlin.types.checker.convertVariance
|
import org.jetbrains.kotlin.types.checker.convertVariance
|
||||||
import org.jetbrains.kotlin.types.getEffectiveVariance
|
import org.jetbrains.kotlin.types.getEffectiveVariance
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
|
||||||
|
|
||||||
// TODO: probably class upper bound should be used
|
fun TypeSystemCommonBackendContext.isMostPreciseContravariantArgument(type: KotlinTypeMarker): Boolean =
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
fun TypeSystemCommonBackendContext.isMostPreciseContravariantArgument(type: KotlinTypeMarker, parameter: TypeParameterMarker): Boolean =
|
|
||||||
type.typeConstructor().isAnyConstructor()
|
type.typeConstructor().isAnyConstructor()
|
||||||
|
|
||||||
fun TypeSystemCommonBackendContext.isMostPreciseCovariantArgument(type: KotlinTypeMarker): Boolean =
|
fun TypeSystemCommonBackendContext.isMostPreciseCovariantArgument(type: KotlinTypeMarker): Boolean =
|
||||||
@@ -62,7 +59,7 @@ private fun TypeSystemCommonBackendContext.canHaveSubtypesIgnoringNullability(ko
|
|||||||
|
|
||||||
val effectiveVariance = getEffectiveVariance(parameter.getVariance().convertVariance(), projectionKind)
|
val effectiveVariance = getEffectiveVariance(parameter.getVariance().convertVariance(), projectionKind)
|
||||||
if (effectiveVariance == Variance.OUT_VARIANCE && !isMostPreciseCovariantArgument(type)) return true
|
if (effectiveVariance == Variance.OUT_VARIANCE && !isMostPreciseCovariantArgument(type)) return true
|
||||||
if (effectiveVariance == Variance.IN_VARIANCE && !isMostPreciseContravariantArgument(type, parameter)) return true
|
if (effectiveVariance == Variance.IN_VARIANCE && !isMostPreciseContravariantArgument(type)) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -43,14 +43,12 @@ class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLike
|
|||||||
class ConeErrorType(
|
class ConeErrorType(
|
||||||
val diagnostic: ConeDiagnostic,
|
val diagnostic: ConeDiagnostic,
|
||||||
val isUninferredParameter: Boolean = false,
|
val isUninferredParameter: Boolean = false,
|
||||||
|
override val typeArguments: Array<out ConeTypeProjection> = EMPTY_ARRAY,
|
||||||
override val attributes: ConeAttributes = ConeAttributes.Empty
|
override val attributes: ConeAttributes = ConeAttributes.Empty
|
||||||
) : ConeClassLikeType() {
|
) : ConeClassLikeType() {
|
||||||
override val lookupTag: ConeClassLikeLookupTag
|
override val lookupTag: ConeClassLikeLookupTag
|
||||||
get() = ConeClassLikeErrorLookupTag(ClassId.fromString("<error>"))
|
get() = ConeClassLikeErrorLookupTag(ClassId.fromString("<error>"))
|
||||||
|
|
||||||
override val typeArguments: Array<out ConeTypeProjection>
|
|
||||||
get() = EMPTY_ARRAY
|
|
||||||
|
|
||||||
override val nullability: ConeNullability
|
override val nullability: ConeNullability
|
||||||
get() = ConeNullability.UNKNOWN
|
get() = ConeNullability.UNKNOWN
|
||||||
|
|
||||||
|
|||||||
+30
-13
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend.jvm
|
package org.jetbrains.kotlin.fir.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
@@ -43,9 +45,16 @@ import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
|||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatureWriter>, FirSessionComponent {
|
class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatureWriter>, FirSessionComponent {
|
||||||
|
companion object {
|
||||||
|
val NON_EXISTENT_ID = ClassId.topLevel(StandardNames.NON_EXISTENT_CLASS)
|
||||||
|
private val typeForNonExistentClass = ConeClassLikeLookupTagImpl(NON_EXISTENT_ID)
|
||||||
|
.constructClassType(emptyArray(), isNullable = false)
|
||||||
|
}
|
||||||
|
|
||||||
override val typeContext = ConeTypeSystemCommonBackendContextForTypeMapping(session.typeContext)
|
override val typeContext = ConeTypeSystemCommonBackendContextForTypeMapping(session.typeContext)
|
||||||
|
|
||||||
fun mapType(type: ConeKotlinType, mode: TypeMappingMode = TypeMappingMode.DEFAULT, sw: JvmSignatureWriter? = null): Type {
|
fun mapType(type: ConeKotlinType, mode: TypeMappingMode = TypeMappingMode.DEFAULT, sw: JvmSignatureWriter? = null): Type {
|
||||||
@@ -67,7 +76,7 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val possiblyInnerType = type.buildPossiblyInnerType() ?: error("possiblyInnerType with arguments should not be null")
|
val possiblyInnerType = type.buildPossiblyInnerType()
|
||||||
|
|
||||||
val innerTypesAsList = possiblyInnerType.segments()
|
val innerTypesAsList = possiblyInnerType.segments()
|
||||||
|
|
||||||
@@ -78,7 +87,7 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
} else {
|
} else {
|
||||||
val outerType = innerTypesAsList[indexOfParameterizedType]
|
val outerType = innerTypesAsList[indexOfParameterizedType]
|
||||||
|
|
||||||
writeOuterClassBegin(asmType, mapType(outerType.classifier.fir.defaultType()).internalName)
|
writeOuterClassBegin(asmType, mapType(outerType.classifier?.fir?.defaultType() ?: typeForNonExistentClass).internalName)
|
||||||
writeGenericArguments(this, outerType, mode)
|
writeGenericArguments(this, outerType, mode)
|
||||||
|
|
||||||
writeInnerParts(
|
writeInnerParts(
|
||||||
@@ -96,8 +105,12 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
typeContext.hasNothingInNonContravariantPosition(type)
|
typeContext.hasNothingInNonContravariantPosition(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.buildPossiblyInnerType(): PossiblyInnerConeType? {
|
private fun ConeKotlinType.buildPossiblyInnerType(): PossiblyInnerConeType {
|
||||||
if (this !is ConeClassLikeType) return null
|
fun createForError(): PossiblyInnerConeType {
|
||||||
|
return PossiblyInnerConeType(classifier = null, typeArguments.toList(), outerType = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this !is ConeClassLikeType) return createForError()
|
||||||
|
|
||||||
return when (val symbol = lookupTag.toSymbol(session)) {
|
return when (val symbol = lookupTag.toSymbol(session)) {
|
||||||
is FirRegularClassSymbol -> buildPossiblyInnerType(symbol, 0)
|
is FirRegularClassSymbol -> buildPossiblyInnerType(symbol, 0)
|
||||||
@@ -107,7 +120,7 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
classSymbol?.let { expandedType.buildPossiblyInnerType(it, 0) }
|
classSymbol?.let { expandedType.buildPossiblyInnerType(it, 0) }
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
} ?: createForError()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassLikeType.parentClassOrNull(): FirRegularClassSymbol? {
|
private fun ConeClassLikeType.parentClassOrNull(): FirRegularClassSymbol? {
|
||||||
@@ -135,7 +148,7 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class PossiblyInnerConeType(
|
private class PossiblyInnerConeType(
|
||||||
val classifier: FirRegularClassSymbol,
|
val classifier: FirRegularClassSymbol?,
|
||||||
val arguments: List<ConeTypeProjection>,
|
val arguments: List<ConeTypeProjection>,
|
||||||
private val outerType: PossiblyInnerConeType?
|
private val outerType: PossiblyInnerConeType?
|
||||||
) {
|
) {
|
||||||
@@ -147,9 +160,9 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
type: PossiblyInnerConeType,
|
type: PossiblyInnerConeType,
|
||||||
mode: TypeMappingMode
|
mode: TypeMappingMode
|
||||||
) {
|
) {
|
||||||
val classifier = type.classifier.fir
|
val classifier = type.classifier?.fir
|
||||||
val defaultType = classifier.defaultType()
|
val defaultType = classifier?.defaultType() ?: typeForNonExistentClass
|
||||||
val parameters = classifier.typeParameters.map { it.symbol }
|
val parameters = classifier?.typeParameters.orEmpty().map { it.symbol }
|
||||||
val arguments = type.arguments
|
val arguments = type.arguments
|
||||||
|
|
||||||
if ((defaultType.isFunctionalType(session) && arguments.size > BuiltInFunctionArity.BIG_ARITY)
|
if ((defaultType.isFunctionalType(session) && arguments.size > BuiltInFunctionArity.BIG_ARITY)
|
||||||
@@ -183,16 +196,20 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
index: Int
|
index: Int
|
||||||
) {
|
) {
|
||||||
for (innerPart in innerTypesAsList.subList(index, innerTypesAsList.size)) {
|
for (innerPart in innerTypesAsList.subList(index, innerTypesAsList.size)) {
|
||||||
sw.writeInnerClass(getJvmShortName(innerPart.classifier.fir))
|
sw.writeInnerClass(getJvmShortName(innerPart.classifier?.classId ?: NON_EXISTENT_ID))
|
||||||
writeGenericArguments(sw, innerPart, mode)
|
writeGenericArguments(sw, innerPart, mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getJvmShortName(klass: FirRegularClass): String {
|
internal fun getJvmShortName(klass: FirRegularClass): String {
|
||||||
val result = runIf(!klass.isLocal) {
|
return getJvmShortName(klass.classId)
|
||||||
klass.classId.asSingleFqName().toUnsafe().let { JavaToKotlinClassMap.mapKotlinToJava(it)?.shortClassName?.asString() }
|
}
|
||||||
|
|
||||||
|
internal fun getJvmShortName(classId: ClassId): String {
|
||||||
|
val result = runUnless(classId.isLocal) {
|
||||||
|
classId.asSingleFqName().toUnsafe().let { JavaToKotlinClassMap.mapKotlinToJava(it)?.shortClassName?.asString() }
|
||||||
}
|
}
|
||||||
return result ?: SpecialNames.safeIdentifier(klass.name).identifier
|
return result ?: SpecialNames.safeIdentifier(classId.shortClassName).identifier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
|
|||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeErrorType -> this
|
is ConeErrorType -> ConeErrorType(diagnostic, isUninferredParameter, arguments, attributes) as T
|
||||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
||||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T
|
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T
|
||||||
else -> error("Not supported: $this: ${this.renderForDebugging()}")
|
else -> error("Not supported: $this: ${this.renderForDebugging()}")
|
||||||
|
|||||||
+1
-1
@@ -127,7 +127,7 @@ private class CalculatorForNestedCall(
|
|||||||
) {
|
) {
|
||||||
val unwrappedType = type.lowerBoundIfFlexible()
|
val unwrappedType = type.lowerBoundIfFlexible()
|
||||||
val typeArgumentsCount = unwrappedType.argumentsCount()
|
val typeArgumentsCount = unwrappedType.argumentsCount()
|
||||||
if (typeArgumentsCount > 0) {
|
if (typeArgumentsCount > 0 && !unwrappedType.isError()) {
|
||||||
for (position in 0 until typeArgumentsCount) {
|
for (position in 0 until typeArgumentsCount) {
|
||||||
val argument = unwrappedType.getArgument(position)
|
val argument = unwrappedType.getArgument(position)
|
||||||
val parameter = unwrappedType.typeConstructor().getParameter(position)
|
val parameter = unwrappedType.typeConstructor().getParameter(position)
|
||||||
|
|||||||
+37
-29
@@ -235,34 +235,6 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
TypeResolutionResult.Unresolved -> null to null
|
TypeResolutionResult.Unresolved -> null to null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol == null || symbol !is FirClassifierSymbol<*>) {
|
|
||||||
val diagnostic = when {
|
|
||||||
symbol?.fir is FirEnumEntry -> {
|
|
||||||
if (isOperandOfIsOperator) {
|
|
||||||
ConeSimpleDiagnostic("'is' operator can not be applied to an enum entry.", DiagnosticKind.IsEnumEntry)
|
|
||||||
} else {
|
|
||||||
ConeSimpleDiagnostic("An enum entry should not be used as a type.", DiagnosticKind.EnumEntryAsType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result is TypeResolutionResult.Ambiguity -> {
|
|
||||||
ConeAmbiguityError(typeRef.qualifier.last().name, result.typeCandidates.first().applicability, result.typeCandidates)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
ConeUnresolvedTypeQualifierError(typeRef.qualifier, isNullable = typeRef.isMarkedNullable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ConeErrorType(diagnostic, attributes = typeRef.annotations.computeTypeAttributes(session))
|
|
||||||
}
|
|
||||||
if (symbol is FirTypeParameterSymbol) {
|
|
||||||
for (part in typeRef.qualifier) {
|
|
||||||
if (part.typeArgumentList.typeArguments.isNotEmpty()) {
|
|
||||||
return ConeErrorType(
|
|
||||||
ConeUnexpectedTypeArgumentsError("Type arguments not allowed", part.typeArgumentList.source)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val allTypeArguments = mutableListOf<ConeTypeProjection>()
|
val allTypeArguments = mutableListOf<ConeTypeProjection>()
|
||||||
var typeArgumentsCount = 0
|
var typeArgumentsCount = 0
|
||||||
|
|
||||||
@@ -351,8 +323,44 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val resultingArguments = allTypeArguments.toTypedArray()
|
||||||
|
|
||||||
|
if (symbol == null || symbol !is FirClassifierSymbol<*>) {
|
||||||
|
val diagnostic = when {
|
||||||
|
symbol?.fir is FirEnumEntry -> {
|
||||||
|
if (isOperandOfIsOperator) {
|
||||||
|
ConeSimpleDiagnostic("'is' operator can not be applied to an enum entry.", DiagnosticKind.IsEnumEntry)
|
||||||
|
} else {
|
||||||
|
ConeSimpleDiagnostic("An enum entry should not be used as a type.", DiagnosticKind.EnumEntryAsType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result is TypeResolutionResult.Ambiguity -> {
|
||||||
|
ConeAmbiguityError(typeRef.qualifier.last().name, result.typeCandidates.first().applicability, result.typeCandidates)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
ConeUnresolvedTypeQualifierError(typeRef.qualifier, isNullable = typeRef.isMarkedNullable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ConeErrorType(
|
||||||
|
diagnostic,
|
||||||
|
typeArguments = resultingArguments,
|
||||||
|
attributes = typeRef.annotations.computeTypeAttributes(session)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symbol is FirTypeParameterSymbol) {
|
||||||
|
for (part in typeRef.qualifier) {
|
||||||
|
if (part.typeArgumentList.typeArguments.isNotEmpty()) {
|
||||||
|
return ConeErrorType(
|
||||||
|
ConeUnexpectedTypeArgumentsError("Type arguments not allowed", part.typeArgumentList.source),
|
||||||
|
typeArguments = resultingArguments
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return symbol.constructType(
|
return symbol.constructType(
|
||||||
allTypeArguments.toTypedArray(),
|
resultingArguments,
|
||||||
typeRef.isMarkedNullable,
|
typeRef.isMarkedNullable,
|
||||||
typeRef.annotations.computeTypeAttributes(session)
|
typeRef.annotations.computeTypeAttributes(session)
|
||||||
).also {
|
).also {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull
|
|||||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||||
import org.jetbrains.kotlin.asJava.elements.*
|
import org.jetbrains.kotlin.asJava.elements.*
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
@@ -142,7 +143,7 @@ internal open class KtUltraLightFieldImpl protected constructor(
|
|||||||
get() = type
|
get() = type
|
||||||
|
|
||||||
private val _type: PsiType by lazyPub {
|
private val _type: PsiType by lazyPub {
|
||||||
fun nonExistent() = JavaPsiFacade.getElementFactory(project).createTypeFromText("error.NonExistentClass", declaration)
|
fun nonExistent() = JavaPsiFacade.getElementFactory(project).createTypeFromText(StandardNames.NON_EXISTENT_CLASS.asString(), declaration)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
(declaration is KtProperty && declaration.hasDelegate()) || declaration is KtEnumEntry || declaration is KtObjectDeclaration ->
|
(declaration is KtProperty && declaration.hasDelegate()) || declaration is KtEnumEntry || declaration is KtObjectDeclaration ->
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ object StandardNames {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val KOTLIN_INTERNAL_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("internal"))
|
val KOTLIN_INTERNAL_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("internal"))
|
||||||
|
|
||||||
|
val NON_EXISTENT_CLASS = FqName("error.NonExistentClass")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val BUILT_INS_PACKAGE_FQ_NAMES = setOf(
|
val BUILT_INS_PACKAGE_FQ_NAMES = setOf(
|
||||||
BUILT_INS_PACKAGE_FQ_NAME,
|
BUILT_INS_PACKAGE_FQ_NAME,
|
||||||
|
|||||||
@@ -300,3 +300,23 @@ fun <T : Enum<T>> enumSetOf(element: T, vararg elements: T): EnumSet<T> = EnumSe
|
|||||||
fun shouldNotBeCalled(message: String = "should not be called"): Nothing {
|
fun shouldNotBeCalled(message: String = "should not be called"): Nothing {
|
||||||
error(message)
|
error(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <T, R> Iterable<T>.zipWithDefault(other: Iterable<R>, leftDefault: () -> T, rightDefault: () -> R): List<Pair<T, R>> {
|
||||||
|
val leftIterator = this.iterator()
|
||||||
|
val rightIterator = other.iterator()
|
||||||
|
return buildList {
|
||||||
|
while (leftIterator.hasNext() && rightIterator.hasNext()) {
|
||||||
|
add(leftIterator.next() to rightIterator.next())
|
||||||
|
}
|
||||||
|
while (leftIterator.hasNext()) {
|
||||||
|
add(leftIterator.next() to rightDefault())
|
||||||
|
}
|
||||||
|
while (rightIterator.hasNext()) {
|
||||||
|
add(leftDefault() to rightIterator.next())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> Iterable<T>.zipWithNulls(other: Iterable<R>): List<Pair<T?, R?>> {
|
||||||
|
return zipWithDefault(other, { null }, { null })
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user