[FIR] Implement WRONG_NUMBER_OF_TYPE_ARGUMENTS for top level type aliases
This commit is contained in:
committed by
TeamCityServer
parent
09510633c7
commit
38820d3e41
+3
-3
@@ -2771,7 +2771,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
firDiagnostic.b,
|
||||
firDiagnostic.c.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
|
||||
}
|
||||
@@ -2785,7 +2785,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a.fir),
|
||||
firDiagnostic.b.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
|
||||
}
|
||||
@@ -2820,7 +2820,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
firDiagnostic.b.map { pair ->
|
||||
firSymbolBuilder.buildSymbol(pair.first.fir) to pair.second.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
|
||||
}
|
||||
|
||||
+2
-2
@@ -534,14 +534,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val TYPE_ARGUMENTS_NOT_ALLOWED by error<PsiElement>()
|
||||
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error<PsiElement> {
|
||||
parameter<Int>("expectedCount")
|
||||
parameter<FirRegularClassSymbol>("classifier")
|
||||
parameter<FirClassLikeSymbol<*>>("classifier")
|
||||
}
|
||||
val NO_TYPE_ARGUMENTS_ON_RHS by error<PsiElement> {
|
||||
parameter<Int>("expectedCount")
|
||||
parameter<FirClassLikeSymbol<*>>("classifier")
|
||||
}
|
||||
val OUTER_CLASS_ARGUMENTS_REQUIRED by error<PsiElement> {
|
||||
parameter<FirRegularClassSymbol>("outer")
|
||||
parameter<FirClassLikeSymbol<*>>("outer")
|
||||
}
|
||||
val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>(PositioningStrategy.TYPE_PARAMETERS_LIST)
|
||||
val TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT by error<PsiElement>(PositioningStrategy.TYPE_PARAMETERS_LIST)
|
||||
|
||||
+2
-2
@@ -353,9 +353,9 @@ object FirErrors {
|
||||
val UPPER_BOUND_VIOLATED by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<PsiElement>()
|
||||
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirRegularClassSymbol>()
|
||||
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
|
||||
val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
|
||||
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClassSymbol>()
|
||||
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirClassLikeSymbol<*>>()
|
||||
val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||
val TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT by error0<PsiElement>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||
val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>()
|
||||
|
||||
@@ -469,10 +469,10 @@ fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAs
|
||||
|
||||
|
||||
|
||||
fun FirRegularClass.getActualTypeParametersCount(session: FirSession): Int {
|
||||
var result = typeParameters.size
|
||||
fun FirClassLikeDeclaration.getActualTypeParametersCount(session: FirSession): Int {
|
||||
var result = (if (this is FirTypeAlias) this.typeParameters else (this as FirClass).typeParameters).size
|
||||
|
||||
if (!isInner) {
|
||||
if (this is FirRegularClass && !isInner) {
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
+63
-20
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeOuterClassArgumentsRequired
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedQualifierError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedDynamicType
|
||||
@@ -234,11 +235,12 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
}
|
||||
|
||||
if (symbol is FirRegularClassSymbol) {
|
||||
if (symbol is FirClassLikeSymbol<*>) {
|
||||
val isPossibleBareType = areBareTypesAllowed && allTypeArguments.isEmpty()
|
||||
if (!isPossibleBareType) {
|
||||
val actualSubstitutor = substitutor ?: ConeSubstitutor.Empty
|
||||
val typeParameters = symbol.fir.typeParameters
|
||||
|
||||
val typeParameters = calculateTypeParameters(symbol)
|
||||
|
||||
val (typeParametersAlignedToQualifierParts, outerClasses) = getClassesAlignedToQualifierParts(symbol, qualifier, session)
|
||||
|
||||
@@ -302,41 +304,82 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateTypeParameters(symbol: FirClassLikeSymbol<*>): List<FirTypeParameterRef> {
|
||||
return if (symbol is FirTypeAliasSymbol) {
|
||||
val typeAliasFir = symbol.fir
|
||||
val typeAliasTypeParameters = typeAliasFir.typeParameters.toMutableList()
|
||||
val fullyExpandedClass = typeAliasFir.fullyExpandedClass(session)
|
||||
val newTypeParameters: MutableList<FirTypeParameterRef>
|
||||
|
||||
if (fullyExpandedClass != null) { // TODO: Should not be null, move to resolver?
|
||||
val expandedTypeRef = typeAliasFir.expandedTypeRef
|
||||
|
||||
fun checkTypeArguments(typeArgument: ConeTypeProjection) {
|
||||
when (typeArgument) {
|
||||
is ConeTypeParameterType -> typeAliasTypeParameters.removeIf { it.symbol == typeArgument.lookupTag.symbol }
|
||||
is ConeClassLikeType -> {
|
||||
for (subTypeArgument in typeArgument.typeArguments) {
|
||||
checkTypeArguments(subTypeArgument)
|
||||
}
|
||||
}
|
||||
is ConeKotlinTypeProjection -> checkTypeArguments(typeArgument.type)
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkTypeArguments(expandedTypeRef.coneType)
|
||||
newTypeParameters = fullyExpandedClass.typeParameters.toMutableList()
|
||||
} else {
|
||||
newTypeParameters = mutableListOf()
|
||||
}
|
||||
|
||||
for (typeParameter in typeAliasTypeParameters) {
|
||||
newTypeParameters.add(typeParameter)
|
||||
}
|
||||
newTypeParameters
|
||||
} else {
|
||||
(symbol as FirClassSymbol<*>).fir.typeParameters
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
private fun getClassesAlignedToQualifierParts(
|
||||
symbol: FirRegularClassSymbol,
|
||||
symbol: FirClassLikeSymbol<*>,
|
||||
qualifier: List<FirQualifierPart>,
|
||||
session: FirSession
|
||||
): ParametersMapAndOuterClasses {
|
||||
var currentClass: FirRegularClass? = null
|
||||
val outerClasses = mutableListOf<FirRegularClass?>()
|
||||
var currentClassLikeDeclaration: FirClassLikeDeclaration? = null
|
||||
val outerDeclarations = mutableListOf<FirClassLikeDeclaration?>()
|
||||
|
||||
// Try to get at least qualifier.size classes that match qualifier parts
|
||||
var qualifierPartIndex = 0
|
||||
while (qualifierPartIndex < qualifier.size || currentClass != null) {
|
||||
while (qualifierPartIndex < qualifier.size || currentClassLikeDeclaration != null) {
|
||||
if (qualifierPartIndex == 0) {
|
||||
currentClass = symbol.fir
|
||||
currentClassLikeDeclaration = symbol.fir
|
||||
} else {
|
||||
if (currentClass != null) {
|
||||
currentClass = currentClass.getContainingDeclaration(session) as? FirRegularClass
|
||||
if (currentClassLikeDeclaration != null) {
|
||||
currentClassLikeDeclaration = currentClassLikeDeclaration.getContainingDeclaration(session)
|
||||
}
|
||||
}
|
||||
|
||||
outerClasses.add(currentClass)
|
||||
outerDeclarations.add(currentClassLikeDeclaration)
|
||||
qualifierPartIndex++
|
||||
}
|
||||
|
||||
val outerArgumentsCount = outerClasses.size - qualifier.size
|
||||
val reversedOuterClasses = outerClasses.asReversed()
|
||||
val outerArgumentsCount = outerDeclarations.size - qualifier.size
|
||||
val reversedOuterClasses = outerDeclarations.asReversed()
|
||||
val result = mutableMapOf<FirTypeParameterSymbol, ClassWithQualifierPartIndex>()
|
||||
|
||||
for (index in reversedOuterClasses.indices) {
|
||||
currentClass = reversedOuterClasses[index]
|
||||
if (currentClass != null) {
|
||||
for (typeParameter in currentClass.typeParameters) {
|
||||
currentClassLikeDeclaration = reversedOuterClasses[index]
|
||||
val typeParameters = if (currentClassLikeDeclaration is FirTypeAlias) currentClassLikeDeclaration.typeParameters else
|
||||
(currentClassLikeDeclaration as? FirClass)?.typeParameters
|
||||
if (currentClassLikeDeclaration != null && typeParameters != null) {
|
||||
for (typeParameter in typeParameters) {
|
||||
val typeParameterSymbol = typeParameter.symbol
|
||||
if (!result.containsKey(typeParameterSymbol)) {
|
||||
result[typeParameterSymbol] = ClassWithQualifierPartIndex(currentClass, index - outerArgumentsCount)
|
||||
result[typeParameterSymbol] = ClassWithQualifierPartIndex(currentClassLikeDeclaration, index - outerArgumentsCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,19 +390,19 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
|
||||
private data class ParametersMapAndOuterClasses(
|
||||
val parameters: Map<FirTypeParameterSymbol, ClassWithQualifierPartIndex>,
|
||||
val outerClasses: List<FirRegularClass?>
|
||||
val outerClasses: List<FirClassLikeDeclaration?>
|
||||
)
|
||||
|
||||
private data class ClassWithQualifierPartIndex(
|
||||
val klass: FirRegularClass,
|
||||
val klass: FirClassLikeDeclaration,
|
||||
val index: Int
|
||||
)
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
private fun createDiagnosticsIfExists(
|
||||
parameterClass: FirRegularClass?,
|
||||
parameterClass: FirClassLikeDeclaration?,
|
||||
qualifierPartIndex: Int,
|
||||
symbol: FirRegularClassSymbol,
|
||||
symbol: FirClassLikeSymbol<*>,
|
||||
userTypeRef: FirUserTypeRef,
|
||||
qualifierPartArgumentsCount: Int? = null
|
||||
): ConeClassErrorType? {
|
||||
|
||||
+2
-2
@@ -152,7 +152,7 @@ interface ConeUnmatchedTypeArgumentsError : ConeDiagnosticWithSingleCandidate {
|
||||
|
||||
class ConeWrongNumberOfTypeArgumentsError(
|
||||
override val desiredCount: Int,
|
||||
override val candidateSymbol: FirRegularClassSymbol,
|
||||
override val candidateSymbol: FirClassLikeSymbol<*>,
|
||||
source: KtSourceElement
|
||||
) : ConeDiagnosticWithSource(source), ConeUnmatchedTypeArgumentsError {
|
||||
override val reason: String get() = "Wrong number of type arguments"
|
||||
@@ -166,7 +166,7 @@ class ConeNoTypeArgumentsOnRhsError(
|
||||
}
|
||||
|
||||
class ConeOuterClassArgumentsRequired(
|
||||
val symbol: FirRegularClassSymbol,
|
||||
val symbol: FirClassLikeSymbol<*>,
|
||||
) : ConeDiagnostic {
|
||||
override val reason: String = "Type arguments should be specified for an outer class"
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ class Outer<T> {
|
||||
fun test5(x: <!UNRESOLVED_REFERENCE!>GenericInnerAlias<Int><!>) = x
|
||||
fun <T> test6(x: <!UNRESOLVED_REFERENCE!>GenericInnerAlias<T><!>) = x
|
||||
}
|
||||
fun test1(x: Outer<Int>.NestedAlias) = x
|
||||
fun <T> test2(x: Outer<T>.NestedAlias) = x
|
||||
fun test1(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.NestedAlias) = x
|
||||
fun <T> test2(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T><!>.NestedAlias) = x
|
||||
fun test3(x: Outer.NestedAlias) = x
|
||||
fun test4(x: Outer<Int>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test5(x: Outer<T>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test6(x: Outer<Int>.GenericNestedAlias<T>) = x
|
||||
fun test4(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test5(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T><!>.GenericNestedAlias<Int>) = x
|
||||
fun <T> test6(x: Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.GenericNestedAlias<T>) = x
|
||||
fun test7(x: Outer.GenericNestedAlias<Int>) = x
|
||||
fun <T> test8(x: Outer.GenericNestedAlias<T>) = x
|
||||
fun test9(x: Outer.InnerAlias) = x
|
||||
fun test9(x: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<!>.InnerAlias) = x
|
||||
fun test10(x: Outer<Int>.InnerAlias) = x
|
||||
fun <T> test11(x: Outer<T>.InnerAlias) = x
|
||||
fun test12(x: Outer.GenericInnerAlias<Int>) = x
|
||||
fun test12(x: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<!>.GenericInnerAlias<Int>) = x
|
||||
fun test13(x: Outer<Int>.GenericInnerAlias<Int>) = x
|
||||
fun <T> test14(x: Outer<T>.GenericInnerAlias<Int>) = x
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
||||
|
||||
class C<T> {
|
||||
inner class D
|
||||
|
||||
typealias DA = D
|
||||
typealias SDA = C<Int>.D
|
||||
typealias TSDA = C<T>.D
|
||||
typealias TC = C<T>
|
||||
typealias SSDA = C<*>.D
|
||||
typealias SSC = C<*>
|
||||
}
|
||||
|
||||
fun test1(x: C<Int>.DA) = x
|
||||
fun test2(x: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>C<!>.SDA) = x
|
||||
fun test3(x: C<Int>.TSDA) = x
|
||||
fun test4(x: C<Int>.TC) = x
|
||||
|
||||
fun test5(x: C<*>.DA) = x
|
||||
fun test6(x: C<*>.TSDA) = x
|
||||
fun test7(x: C<*>.TC) = x
|
||||
|
||||
fun test8(x: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>C<!>.SSDA) = x
|
||||
fun test9(x: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>C<!>.SSC) = x
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
||||
|
||||
class C<T> {
|
||||
|
||||
@@ -6,5 +6,5 @@ class OuterClass<T1> {
|
||||
}
|
||||
|
||||
typealias ON1<T1, T2> = OuterClass<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T1><!>.NestedClass<T2>
|
||||
typealias ON2<T1, T2> = OuterClass<T1>.NestedType<T2>
|
||||
typealias ON3<T2> = OuterClass.NestedType<T2>
|
||||
typealias ON2<T1, T2> = OuterClass<T1>.NestedType<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T2><!>
|
||||
typealias ON3<T2> = OuterClass.NestedType<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T2><!>
|
||||
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
open class Ref<T>(var x: T)
|
||||
|
||||
typealias R<T> = Ref<T>
|
||||
|
||||
// Type inference SHOULD NOT work for type alias constructor in supertypes list
|
||||
class Test1 : R(0)
|
||||
class Test2 : R<Int>(0)
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
open class Ref<T>(var x: T)
|
||||
|
||||
typealias R<T> = Ref<T>
|
||||
|
||||
Reference in New Issue
Block a user