[FIR] Fix positioning and detecting of WRONG_NUMBER_OF_TYPE_ARGUMENTS

Refactor code and fix compilation errors caused by changes to symbol.fir
This commit is contained in:
Ivan Kochurkin
2021-07-06 22:23:04 +03:00
committed by TeamCityServer
parent 345152d198
commit dd54338ec0
49 changed files with 377 additions and 301 deletions
@@ -9,9 +9,9 @@ abstract class My<T : Some> {
abstract fun foo(arg: T)
abstract val y: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>My.T<!>
abstract val y: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>My<!>.T
abstract val z: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>test.My.T<!>
abstract val z: test.<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>My<!>.T
class Some : <!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, UNRESOLVED_REFERENCE!>T<!>()
}
@@ -10,4 +10,4 @@ class A<T1, T2> {
fun <R1, R2, R3> foo(c: A<R1, R1>.B<R2, R2>.C<R3, R3>) {}
fun <R3> foo(c: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A.B.C<R3, R3><!>) {}
fun <R3> foo(c: A.<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>B<!>.C<R3, R3>) {}
@@ -446,14 +446,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<FirClassLikeSymbol<*>>("classifier")
parameter<FirRegularClassSymbol>("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<FirRegularClass>("outer")
val OUTER_CLASS_ARGUMENTS_REQUIRED by error<PsiElement> {
parameter<FirRegularClassSymbol>("outer")
}
val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<PsiElement>()
@@ -295,9 +295,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, FirClassLikeSymbol<*>>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirRegularClassSymbol>()
val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClass>()
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClassSymbol>()
val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>()
@@ -8,14 +8,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.extractArgumentTypeRefAndSource
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.resolve.getClassThatContainsTypeParameter
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameter
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.toTypeProjections
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -23,15 +21,10 @@ import org.jetbrains.kotlin.fir.types.*
object FirOuterClassArgumentsRequiredChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
// Checking the rest super types that weren't resolved on the first OUTER_CLASS_ARGUMENTS_REQUIRED check in FirTypeResolver
for (superTypeRef in declaration.superTypeRefs) {
checkOuterClassArgumentsRequired(superTypeRef, declaration, context, reporter)
}
for (subDecl in declaration.declarations) {
if (subDecl is FirTypedDeclaration) {
checkOuterClassArgumentsRequired(subDecl.returnTypeRef, declaration, context, reporter)
}
}
}
}
@@ -41,65 +34,29 @@ private fun checkOuterClassArgumentsRequired(
context: CheckerContext,
reporter: DiagnosticReporter
) {
val type: ConeKotlinType
if (typeRef !is FirResolvedTypeRef || typeRef is FirErrorTypeRef) {
return
}
if (typeRef is FirResolvedTypeRef) {
if (typeRef is FirErrorTypeRef) {
return
}
val type: ConeKotlinType = typeRef.type
val delegatedTypeRef = typeRef.delegatedTypeRef
type = typeRef.type
val delegatedTypeRef = typeRef.delegatedTypeRef
if (delegatedTypeRef is FirUserTypeRef && type is ConeClassLikeType) {
val symbol = type.lookupTag.toSymbol(context.session)
if (delegatedTypeRef is FirUserTypeRef) {
if (symbol is FirRegularClassSymbol) {
val typeArguments = delegatedTypeRef.qualifier.toTypeProjections()
val typeParameters = symbol.typeParameterSymbols
if (type is ConeClassLikeType) {
val symbol = type.lookupTag.toSymbol(context.session)
if (symbol is FirRegularClassSymbol) {
var problemTypeParameter: FirTypeParameterRef? = null
val typeArguments = delegatedTypeRef.qualifier.toTypeProjections()
val argumentsFromOuterClassesAndParentsCount = symbol.fir.typeParameters.drop(typeArguments.size).sumOf {
val result = if (isValidTypeParameter(it, declaration, context.session)) {
1
} else {
if (problemTypeParameter == null) {
problemTypeParameter = it
}
0
}
return@sumOf result
}
val finalTypeArgumentsCount = typeArguments.size + argumentsFromOuterClassesAndParentsCount
if (finalTypeArgumentsCount != symbol.fir.typeParameters.size) {
val source = typeRef.source
if (problemTypeParameter != null) {
var outerClass: FirRegularClass? = null
context.findClosest<FirRegularClass> {
outerClass = getClassThatContainsTypeParameter(it, problemTypeParameter!!)
return@findClosest outerClass != null
}
if (outerClass != null) {
reporter.reportOn(source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass!!, context)
}
} else {
reporter.reportOn(
source,
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
symbol.fir.typeParameters.size - argumentsFromOuterClassesAndParentsCount,
symbol,
context
)
}
}
for (index in typeArguments.size until typeParameters.size) {
val typeParameter = typeParameters[index]
if (!isValidTypeParameterFromOuterClass(typeParameter, declaration, context.session)) {
val outerClass = typeParameter.containingDeclarationSymbol as FirRegularClassSymbol
reporter.reportOn(typeRef.source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass, context)
break
}
}
}
} else if (typeRef is ConeKotlinType) {
type = typeRef
} else {
return
}
for (index in type.typeArguments.indices) {
@@ -717,7 +717,7 @@ class FirDefaultErrorMessages {
WRONG_NUMBER_OF_TYPE_ARGUMENTS,
"{0,choice,0#No type arguments|1#One type argument|1<{0,number,integer} type arguments} expected for {1}",
null,
SYMBOL
RENDER_CLASS_OR_OBJECT_NAME
)
map.put(
OUTER_CLASS_ARGUMENTS_REQUIRED,
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -80,17 +81,17 @@ object FirDiagnosticRenderers {
"$classOrObject $name"
}
val RENDER_CLASS_OR_OBJECT_NAME = Renderer { firClassLike: FirClassLikeDeclaration ->
val RENDER_CLASS_OR_OBJECT_NAME = Renderer { firClassLike: FirClassLikeSymbol<*> ->
val name = firClassLike.classId.relativeClassName.shortName().asString()
val prefix = when (firClassLike) {
is FirTypeAlias -> "typealias"
is FirRegularClass -> {
is FirTypeAliasSymbol -> "typealias"
is FirRegularClassSymbol -> {
when {
firClassLike.isCompanion -> "companion object"
firClassLike.isInterface -> "interface"
firClassLike.isEnumClass -> "enum class"
firClassLike.isFromEnumClass -> "enum entry"
firClassLike.isLocalClassOrAnonymousObject() -> "object"
firClassLike.isLocalClassOrAnonymousObject -> "object"
else -> "class"
}
}
@@ -68,9 +68,9 @@ private fun ConeDiagnostic.toFirDiagnostic(
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source ?: source)
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
is ConeWrongNumberOfTypeArgumentsError ->
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(this.source ?: qualifiedAccessSource ?: source, this.desiredCount, this.symbol)
is ConeOuterClassArgumentsRequired ->
FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(qualifiedAccessSource ?: source, this.type)
FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(qualifiedAccessSource ?: source, this.symbol)
is ConeNoTypeArgumentsOnRhsError ->
FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
is ConeSimpleDiagnostic -> when (source.kind) {
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.providers.getSymbolByTypeRef
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
@@ -449,14 +451,17 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null
fun isValidTypeParameter(typeParameter: FirTypeParameterRef, classDeclaration: FirRegularClass?, session: FirSession): Boolean {
if (typeParameter !is FirOuterClassTypeParameterRef || classDeclaration == null) {
return true
fun isValidTypeParameterFromOuterClass(
typeParameterSymbol: FirTypeParameterSymbol,
classDeclaration: FirRegularClass?,
session: FirSession
): Boolean {
if (classDeclaration == null) {
return true // Extra check is required because of classDeclaration will be resolved later
}
fun containsTypeParameter(currentClassDeclaration: FirRegularClass): Boolean {
val result = currentClassDeclaration.typeParameters.any { it.symbol == typeParameter.symbol }
if (result) {
if (currentClassDeclaration.typeParameters.any { it.symbol == typeParameterSymbol }) {
return true
}
@@ -473,19 +478,29 @@ fun isValidTypeParameter(typeParameter: FirTypeParameterRef, classDeclaration: F
return containsTypeParameter(classDeclaration)
}
fun getClassThatContainsTypeParameter(klass: FirRegularClass, typeParameter: FirTypeParameterRef): FirRegularClass? {
if (klass.typeParameters.any { param -> param.symbol == typeParameter.symbol }) {
return klass
fun getOuterClassAndActualTypeParametersCount(klass: FirRegularClass, session: FirSession): Pair<FirRegularClass?, Int> {
var result = klass.typeParameters.size
if (!klass.isInner) {
return Pair(null, result)
}
for (declaration in klass.declarations) {
if (declaration is FirRegularClass) {
val result = getClassThatContainsTypeParameter(declaration, typeParameter)
if (result != null) {
return result
}
}
val outerClass = getOuterClass(klass, session)
if (outerClass != null) {
result -= outerClass.typeParameters.size
}
return Pair(outerClass, result)
}
fun getOuterClass(klass: FirRegularClass, session: FirSession): FirRegularClass? {
val classId = klass.symbol.classId
val parentId = classId.relativeClassName.parent()
if (!parentId.isRoot) {
val outerClassId = ClassId(classId.packageFqName, parentId, false)
val parentSymbol = session.symbolProvider.getClassLikeSymbolByFqName(outerClassId)
return (parentSymbol as? FirRegularClassSymbol)?.fir
}
return null
}
}
@@ -6,16 +6,14 @@
package org.jetbrains.kotlin.fir.resolve.diagnostics
import kotlinx.collections.immutable.ImmutableList
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.ClassId
@@ -101,9 +99,10 @@ class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic() {
abstract class ConeUnmatchedTypeArgumentsError(val desiredCount: Int, val type: FirClassLikeSymbol<*>) : ConeDiagnostic()
class ConeWrongNumberOfTypeArgumentsError(
desiredCount: Int,
type: FirClassLikeSymbol<*>
) : ConeUnmatchedTypeArgumentsError(desiredCount, type) {
val desiredCount: Int,
val symbol: FirRegularClassSymbol,
val source: FirSourceElement?
) : ConeDiagnostic() {
override val reason: String get() = "Wrong number of type arguments"
}
@@ -115,7 +114,7 @@ class ConeNoTypeArgumentsOnRhsError(
}
class ConeOuterClassArgumentsRequired(
val type: FirRegularClass,
val symbol: FirRegularClassSymbol,
) : ConeDiagnostic() {
override val reason: String = "Type arguments should be specified for an outer class"
}
@@ -6,12 +6,11 @@
package org.jetbrains.kotlin.fir.resolve.providers.impl
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeOuterClassArgumentsRequired
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedQualifierError
@@ -19,6 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedDynamicType
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeWrongNumberOfTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
@@ -48,7 +48,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
private fun resolveToSymbol(
typeRef: FirTypeRef,
scopeClassDeclaration: ScopeClassDeclaration
scope: FirScope,
): Pair<FirClassifierSymbol<*>?, ConeSubstitutor?> {
return when (typeRef) {
is FirResolvedTypeRef -> {
@@ -60,7 +60,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
val qualifierResolver = session.qualifierResolver
var resolvedSymbol: FirClassifierSymbol<*>? = null
var substitutor: ConeSubstitutor? = null
scopeClassDeclaration.scope.processClassifiersByNameWithSubstitution(typeRef.qualifier.first().name) { symbol, substitutorFromScope ->
scope.processClassifiersByNameWithSubstitution(typeRef.qualifier.first().name) { symbol, substitutorFromScope ->
if (resolvedSymbol != null) return@processClassifiersByNameWithSubstitution
resolvedSymbol = when (symbol) {
is FirClassLikeSymbol<*> -> {
@@ -97,7 +97,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
symbol: FirClassifierSymbol<*>?,
substitutor: ConeSubstitutor?,
areBareTypesAllowed: Boolean,
scopeClassDeclaration: ScopeClassDeclaration
topDeclaration: FirRegularClass?
): ConeKotlinType {
if (symbol == null) {
return ConeKotlinErrorType(ConeUnresolvedQualifierError(typeRef.render()))
@@ -111,57 +111,78 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
}
}
}
var typeArguments = typeRef.qualifier.toTypeProjections()
if (symbol is FirRegularClassSymbol) {
val isPossibleBareType = areBareTypesAllowed && typeArguments.isEmpty()
if (typeArguments.size != symbol.fir.typeParameters.size && !isPossibleBareType) {
@Suppress("NAME_SHADOWING")
if (symbol.fir.typeParameters.size < typeArguments.size) {
return ConeClassErrorType(ConeWrongNumberOfTypeArgumentsError(symbol.fir.typeParameters.size, symbol))
} else {
val substitutor = substitutor ?: ConeSubstitutor.Empty
var problemTypeParameter: FirTypeParameterRef? = null
val classDeclarations = scopeClassDeclaration.classDeclarations
val argumentsFromOuterClassesAndParents = symbol.fir.typeParameters.drop(typeArguments.size).mapNotNull {
if (isValidTypeParameter(it, classDeclarations.lastOrNull(), session)) {
val type = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(it.symbol), isNullable = false)
// we should report ConeSimpleDiagnostic(..., WrongNumberOfTypeArguments)
// but genericArgumentNumberMismatch.kt test fails with
// index out of bounds exception for start offset of
// the source
substitutor.substituteOrNull(type)
} else {
if (problemTypeParameter == null) {
problemTypeParameter = it
}
null
}
}.toTypedArray<ConeTypeProjection>()
typeArguments += argumentsFromOuterClassesAndParents
if (typeArguments.size != symbol.fir.typeParameters.size) {
if (problemTypeParameter != null) {
var outerClass: FirRegularClass? = null
classDeclarations.forEach {
getClassThatContainsTypeParameter(it, problemTypeParameter!!)?.let { result ->
outerClass = result
return@forEach
}
}
return ConeClassErrorType(ConeOuterClassArgumentsRequired(outerClass!!))
val allTypeArguments = mutableListOf<ConeTypeProjection>()
var typeArgumentsCount = 0
val qualifier = typeRef.qualifier
for (qualifierIndex in qualifier.size - 1 downTo 0) {
val qualifierTypeArguments = qualifier[qualifierIndex].typeArgumentList.typeArguments
for (qualifierTypeArgument in qualifierTypeArguments) {
allTypeArguments.add(qualifierTypeArgument.toConeTypeProjection())
typeArgumentsCount++
}
}
if (symbol is FirRegularClassSymbol) {
val isPossibleBareType = areBareTypesAllowed && allTypeArguments.isEmpty()
if (!isPossibleBareType) {
val actualSubstitutor = substitutor ?: ConeSubstitutor.Empty
val typeParameters = symbol.fir.typeParameters
val (typeParametersAlignedToQualifierParts, outerClasses) = getClassesAlignedToQualifierParts(symbol, qualifier, session)
for ((index, typeParameter) in typeParameters.withIndex()) {
val (parameterClass, qualifierPartIndex) = typeParametersAlignedToQualifierParts[typeParameter.symbol] ?: continue
if (index < typeArgumentsCount) {
// Check if type argument matches type parameter in respective qualifier part
val qualifierPartArgumentsCount = qualifier[qualifierPartIndex].typeArgumentList.typeArguments.size
createDiagnosticsIfExists(
parameterClass,
qualifierPartIndex,
symbol,
typeRef,
qualifierPartArgumentsCount
)?.let { return it }
continue
}
if (typeParameter !is FirOuterClassTypeParameterRef ||
isValidTypeParameterFromOuterClass(typeParameter.symbol, topDeclaration, session)
) {
val type = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(typeParameter.symbol), isNullable = false)
val substituted = actualSubstitutor.substituteOrNull(type)
if (substituted == null) {
createDiagnosticsIfExists(parameterClass, qualifierPartIndex, symbol, typeRef)?.let { return it }
} else {
return ConeClassErrorType(
ConeWrongNumberOfTypeArgumentsError(
desiredCount = symbol.fir.typeParameters.size - argumentsFromOuterClassesAndParents.size,
type = symbol
)
)
allTypeArguments.add(substituted)
}
} else {
return ConeClassErrorType(ConeOuterClassArgumentsRequired(parameterClass.symbol))
}
}
// Check rest type arguments
if (typeArgumentsCount > typeParameters.size) {
for (index in qualifier.indices) {
if (qualifier[index].typeArgumentList.typeArguments.isNotEmpty()) {
val parameterClass = outerClasses.elementAtOrNull(index)
createDiagnosticsIfExists(
parameterClass,
index,
symbol,
typeRef,
ignoreOuterClassCheck = true
)?.let { return it }
}
}
}
}
}
return symbol.constructType(typeArguments, typeRef.isMarkedNullable, typeRef.annotations.computeTypeAttributes())
return symbol.constructType(allTypeArguments.toTypedArray(), typeRef.isMarkedNullable, typeRef.annotations.computeTypeAttributes())
.also {
val lookupTag = it.lookupTag
if (lookupTag is ConeClassLikeLookupTagImpl && symbol is FirClassLikeSymbol<*>) {
@@ -170,6 +191,102 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
}
}
private fun getClassesAlignedToQualifierParts(
symbol: FirRegularClassSymbol,
qualifier: List<FirQualifierPart>,
session: FirSession
): ParametersMapAndOuterClasses {
var currentClass: FirRegularClass? = null
val outerClasses = mutableListOf<FirRegularClass?>()
// Try to get at least qualifier.size classes that match qualifier parts
var qualifierPartIndex = 0
while (qualifierPartIndex < qualifier.size || currentClass != null) {
if (qualifierPartIndex == 0) {
currentClass = symbol.fir
} else {
if (currentClass != null) {
currentClass = getOuterClass(currentClass, session)
}
}
outerClasses.add(currentClass)
qualifierPartIndex++
}
val outerArgumentsCount = outerClasses.size - qualifier.size
val reversedOuterClasses = outerClasses.asReversed()
val result = mutableMapOf<FirTypeParameterSymbol, ClassWithQualifierPartIndex>()
for (index in reversedOuterClasses.indices) {
currentClass = reversedOuterClasses[index]
if (currentClass != null) {
for (typeParameter in currentClass.typeParameters) {
val typeParameterSymbol = typeParameter.symbol
if (!result.containsKey(typeParameterSymbol)) {
result[typeParameterSymbol] = ClassWithQualifierPartIndex(currentClass, index - outerArgumentsCount)
}
}
}
}
return ParametersMapAndOuterClasses(result, reversedOuterClasses.drop(outerArgumentsCount))
}
private data class ParametersMapAndOuterClasses(
val parameters: Map<FirTypeParameterSymbol, ClassWithQualifierPartIndex>,
val outerClasses: List<FirRegularClass?>
)
private data class ClassWithQualifierPartIndex(
val klass: FirRegularClass,
val index: Int
)
private fun createDiagnosticsIfExists(
parameterClass: FirRegularClass?,
qualifierPartIndex: Int,
symbol: FirRegularClassSymbol,
userTypeRef: FirUserTypeRef,
qualifierPartArgumentsCount: Int? = null,
ignoreOuterClassCheck: Boolean = false
): ConeClassErrorType? {
// TODO: It should be TYPE_ARGUMENTS_NOT_ALLOWED diagnostics when parameterClass is null
val (outerClass, actualTypeParametersCount) = getOuterClassAndActualTypeParametersCount(
parameterClass ?: symbol.fir,
session
)
if (qualifierPartArgumentsCount == null || actualTypeParametersCount != qualifierPartArgumentsCount) {
// TODO: fix obtaining outer class for cases like
// https://github.com/JetBrains/kotlin/blob/master/compiler/testData/diagnostics/tests/generics/innerClasses/implicitArguments/fromSuperClassesLocal.kt#L16
if (ignoreOuterClassCheck ||
(parameterClass != null && parameterClass.classId.relativeClassName.parent().isRoot)
|| outerClass != null
) {
return ConeClassErrorType(
ConeWrongNumberOfTypeArgumentsError(
actualTypeParametersCount,
parameterClass?.symbol ?: symbol,
getTypeArgumentsOrNameSource(userTypeRef, qualifierPartIndex)
)
)
}
}
return null
}
private fun getTypeArgumentsOrNameSource(typeRef: FirUserTypeRef, qualifierIndex: Int?): FirSourceElement? {
val qualifierPart = if (qualifierIndex != null) typeRef.qualifier.elementAtOrNull(qualifierIndex) else null
val typeArgumentsList = qualifierPart?.typeArgumentList
return if (typeArgumentsList == null || typeArgumentsList.typeArguments.isEmpty()) {
qualifierPart?.source ?: typeRef.source
} else {
typeArgumentsList.source
}
}
private fun createFunctionalType(typeRef: FirFunctionTypeRef): ConeClassLikeType {
val parameters =
listOfNotNull(typeRef.receiverTypeRef?.coneType) +
@@ -202,8 +319,8 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
return when (typeRef) {
is FirResolvedTypeRef -> typeRef.type
is FirUserTypeRef -> {
val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration)
resolveUserType(typeRef, symbol, substitutor, areBareTypesAllowed, scopeClassDeclaration)
val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration.scope)
resolveUserType(typeRef, symbol, substitutor, areBareTypesAllowed, scopeClassDeclaration.topDeclaration)
}
is FirFunctionTypeRef -> createFunctionalType(typeRef)
is FirDynamicTypeRef -> ConeKotlinErrorType(ConeUnsupportedDynamicType())
@@ -30,7 +30,7 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
protected val scopeSession: ScopeSession
) : FirAbstractTreeTransformer<Any?>(phase) {
protected val scopes = mutableListOf<FirScope>()
protected val classDeclarations = mutableListOf<FirRegularClass>()
protected val classDeclarationsStack = ArrayDeque<FirRegularClass>()
protected val towerScope = FirCompositeScope(scopes.asReversed())
protected open fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = transformerPhase > firDeclaration.resolvePhase
@@ -47,10 +47,9 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
}
protected inline fun <T> withClassDeclarationCleanup(declaration: FirRegularClass, crossinline l: () -> T): T {
classDeclarations.add(declaration)
val result = l()
classDeclarations.removeAt(classDeclarations.lastIndex)
return result
withClassDeclarationCleanup(classDeclarationsStack, declaration) {
return l()
}
}
protected fun resolveNestedClassesSupertypes(
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.typeResolver
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -215,7 +215,7 @@ open class FirSupertypeResolverVisitor(
private val firProviderInterceptor: FirProviderInterceptor? = null,
) : FirDefaultVisitor<Unit, Any?>() {
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
private val classDeclarations = mutableListOf<FirRegularClass>()
private val classDeclarationsStack = ArrayDeque<FirRegularClass>()
private fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? =
if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierContainerFileIfAny(symbol)
@@ -309,7 +309,10 @@ open class FirSupertypeResolverVisitor(
val scopes = prepareScopes(classLikeDeclaration)
val transformer = FirSpecificTypeResolverTransformer(session)
val resolvedTypesRefs = resolveSuperTypeRefs(transformer, ScopeClassDeclaration(FirCompositeScope(scopes), classDeclarations))
val resolvedTypesRefs = resolveSuperTypeRefs(
transformer,
ScopeClassDeclaration(FirCompositeScope(scopes), classDeclarationsStack.lastOrNull())
)
supertypeComputationSession.storeSupertypes(classLikeDeclaration, resolvedTypesRefs)
return resolvedTypesRefs
@@ -320,10 +323,10 @@ open class FirSupertypeResolverVisitor(
}
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?) {
classDeclarations.add(regularClass)
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
visitDeclarationContent(regularClass, null)
classDeclarations.removeAt(classDeclarations.lastIndex)
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
visitDeclarationContent(regularClass, null)
}
}
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) {
@@ -190,7 +190,7 @@ open class FirTypeResolveTransformer(
return typeResolverTransformer.withFile(currentFile) {
typeRef.transform(
typeResolverTransformer,
ScopeClassDeclaration(towerScope, classDeclarations)
ScopeClassDeclaration(towerScope, classDeclarationsStack.lastOrNull())
)
}
}
@@ -8,5 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.scopes.FirScope
data class ScopeClassDeclaration(val scope: FirScope, val classDeclarations: List<FirRegularClass>) {
}
data class ScopeClassDeclaration(
val scope: FirScope,
val topDeclaration: FirRegularClass?
)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -132,3 +133,16 @@ inline fun <T> withScopeCleanup(scopes: MutableList<*>, l: () -> T): T {
}
}
}
inline fun <T> withClassDeclarationCleanup(
classDeclarations: ArrayDeque<FirRegularClass>,
topClassDeclaration: FirRegularClass,
l: () -> T
): T {
classDeclarations.addLast(topClassDeclaration)
return try {
l()
} finally {
classDeclarations.removeLast()
}
}
@@ -87,13 +87,17 @@ class BodyResolveContext(
val anonymousFunctionsAnalyzedInDependentContext: MutableSet<FirFunctionSymbol<*>> = mutableSetOf()
var containingClassDeclarations: ArrayDeque<FirRegularClass> = ArrayDeque()
val topClassDeclaration: FirRegularClass?
get() = containingClassDeclarations.lastOrNull()
private inline fun <T> withNewTowerDataForClassParts(newContexts: FirTowerDataContextsForClassParts, f: () -> T): T {
val old = towerDataContextsForClassParts
towerDataContextsForClassParts = newContexts
return try {
f()
} finally {
towerDataContextsForClassParts = old
}
}
@@ -130,6 +134,15 @@ class BodyResolveContext(
}
}
inline fun <T> withContainingClass(declaration: FirRegularClass, f: () -> T): T {
containingClassDeclarations.add(declaration)
return try {
f()
} finally {
containingClassDeclarations.removeLast()
}
}
@PrivateForInline
inline fun <R> withTowerDataCleanup(l: () -> R): R {
val initialContext = towerDataContext
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration
import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.impl.createCurrentScopeList
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
@@ -47,7 +44,6 @@ open class FirBodyResolveTransformer(
internal open val expressionsTransformer = FirExpressionsResolveTransformer(this)
protected open val declarationsTransformer = FirDeclarationsResolveTransformer(this)
private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this)
private val classDeclarations = mutableListOf<FirRegularClass>()
override fun transformFile(file: FirFile, data: ResolutionMode): FirFile {
checkSessionConsistency(file)
@@ -70,7 +66,13 @@ open class FirBodyResolveTransformer(
typeRef
} else {
typeResolverTransformer.withFile(context.file) {
transformTypeRef(typeRef, ScopeClassDeclaration(FirCompositeScope(components.createCurrentScopeList()), classDeclarations))
transformTypeRef(
typeRef,
ScopeClassDeclaration(
FirCompositeScope(components.createCurrentScopeList()),
context.topClassDeclaration
)
)
}
}
return resolvedTypeRef.transformAnnotations(this, data)
@@ -263,10 +265,7 @@ open class FirBodyResolveTransformer(
}
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
classDeclarations.add(regularClass)
val result = declarationsTransformer.transformRegularClass(regularClass, data)
classDeclarations.removeAt(classDeclarations.lastIndex)
return result
return declarationsTransformer.transformRegularClass(regularClass, data)
}
override fun transformAnonymousObject(
@@ -356,18 +356,20 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
}
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) {
return regularClass.runAllPhasesForLocalClass(
transformer,
components,
data,
transformer.firTowerDataContextCollector,
transformer.firProviderInterceptor
)
}
context.withContainingClass(regularClass) {
if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) {
return regularClass.runAllPhasesForLocalClass(
transformer,
components,
data,
transformer.firTowerDataContextCollector,
transformer.firProviderInterceptor
)
}
doTransformTypeParameters(regularClass)
return doTransformRegularClass(regularClass, data)
doTransformTypeParameters(regularClass)
return doTransformRegularClass(regularClass, data)
}
}
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: ResolutionMode): FirTypeAlias {
@@ -90,7 +90,7 @@ private class FirAnnotationResolveTransformer(
)
private var owners: PersistentList<FirAnnotatedDeclaration> = persistentListOf()
protected val classDeclarations = mutableListOf<FirRegularClass>()
private val classDeclarationsStack = ArrayDeque<FirRegularClass>()
override fun beforeChildren(declaration: FirAnnotatedDeclaration): PersistentList<FirAnnotatedDeclaration> {
val current = owners
@@ -107,24 +107,26 @@ private class FirAnnotationResolveTransformer(
annotationCall: FirAnnotationCall,
data: Multimap<AnnotationFqn, FirRegularClass>
): FirStatement {
return annotationCall.transformAnnotationTypeRef(typeResolverTransformer, ScopeClassDeclaration(scope, listOf()))
return annotationCall.transformAnnotationTypeRef(
typeResolverTransformer,
ScopeClassDeclaration(scope, classDeclarationsStack.lastOrNull())
)
}
override fun transformRegularClass(
regularClass: FirRegularClass,
data: Multimap<AnnotationFqn, FirRegularClass>
): FirStatement {
classDeclarations.add(regularClass)
val result = super.transformRegularClass(regularClass, data).also {
if (regularClass.classKind == ClassKind.ANNOTATION_CLASS && metaAnnotations.isNotEmpty()) {
val annotations = regularClass.annotations.mapNotNull { it.fqName(session) }
for (annotation in annotations.filter { it in metaAnnotations }) {
data.put(annotation, regularClass)
withClassDeclarationCleanup(classDeclarationsStack, classDeclarationsStack.last()) {
return super.transformRegularClass(regularClass, data).also {
if (regularClass.classKind == ClassKind.ANNOTATION_CLASS && metaAnnotations.isNotEmpty()) {
val annotations = regularClass.annotations.mapNotNull { it.fqName(session) }
for (annotation in annotations.filter { it in metaAnnotations }) {
data.put(annotation, regularClass)
}
}
}
}
classDeclarations.removeAt(classDeclarations.lastIndex)
return result
}
override fun transformAnnotatedDeclaration(
@@ -6,10 +6,6 @@
package org.jetbrains.kotlin.fir.declarations.utils
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.*
// ---------------------- callables with status ----------------------
@@ -108,6 +104,9 @@ inline val FirTypeAliasSymbol.isFun: Boolean get() = resolvedStatus.isFun
inline val FirClassLikeSymbol<*>.isLocal: Boolean get() = classId.isLocal
inline val FirClassSymbol<*>.isLocalClassOrAnonymousObject: Boolean
get() = classId.isLocal || this is FirAnonymousObjectSymbol
inline val FirClassSymbol<*>.isInterface: Boolean
get() = classKind.isInterface
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.name.Name
@@ -35,5 +36,8 @@ class FirTypeParameterSymbol : FirClassifierSymbol<FirTypeParameter>() {
val isReified: Boolean
get() = fir.isReified
val containingDeclarationSymbol: FirBasedSymbol<*>?
get() = fir.containingDeclarationSymbol
}
+1 -1
View File
@@ -3,7 +3,7 @@ package unresolved
class Pair<A, B>(val a: A, val b: B)
fun testGenericArgumentsCount() {
val p1: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Pair<Int><!> = Pair(2, 2)
val p1: Pair<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!> = Pair(2, 2)
val p2: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Pair<!> = Pair(2, 2)
}
@@ -1,8 +1,7 @@
interface A0<T : A0<T>>
interface A1<T : A1<*>>
interface A2<T : A2<out T>>
// StackOverflowError
//interface A3<T : A3<in T>>
interface A3<T : A3<in T>>
interface A4<T : A4<*>?>
interface B0<T : B1<*>>
@@ -11,7 +10,7 @@ interface B1<T : B0<*>>
interface AA<T: AA<*>>
interface BB<S : List<AA<*>>>
interface A<T: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>List<T, T, T><!>>
interface A<T: List<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T, T, T><!>>
class X<Y>
class D<T : X<in X<out X<T>>>>
class D<T : X<in X<out X<T>>>>
@@ -1,8 +1,7 @@
interface A0<T : A0<T>>
interface A1<<!FINITE_BOUNDS_VIOLATION!>T : A1<*><!>>
interface A2<<!FINITE_BOUNDS_VIOLATION!>T : A2<out T><!>>
// StackOverflowError
//interface A3<T : A3<in T>>
interface A3<<!FINITE_BOUNDS_VIOLATION!>T : A3<in T><!>>
interface A4<<!FINITE_BOUNDS_VIOLATION!>T : A4<*>?<!>>
interface B0<<!FINITE_BOUNDS_VIOLATION!>T : B1<*><!>>
@@ -14,4 +13,4 @@ interface BB<S : List<AA<*>>>
interface A<T: List<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><T, T, T><!>>
class X<Y>
class D<T : X<in X<out X<T>>>>
class D<T : X<in X<out X<T>>>>
@@ -24,6 +24,12 @@ public interface A2</*0*/ T : A2<out T>> {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface A3</*0*/ T : A3<in T>> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface A4</*0*/ T : A4<*>?> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -1,7 +1,7 @@
package p
public fun foo(a: Any) {
a is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<Int><!>
a is Map<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>
a is <!NO_TYPE_ARGUMENTS_ON_RHS!>Map<!>
a is Map<out Any?, Any?>
a is Map<*, *>
@@ -11,4 +11,4 @@ public fun foo(a: Any) {
a is Int
(a as <!NO_TYPE_ARGUMENTS_ON_RHS!>Map<!>) is Int
}
}
@@ -1,6 +1,6 @@
public fun foo(a: Any, b: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) {
when (a) {
is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<Int><!> -> {}
is Map<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!> -> {}
is <!NO_TYPE_ARGUMENTS_ON_RHS!>Map<!> -> {}
is Map<out Any?, Any?> -> {}
is Map<*, *> -> {}
@@ -10,4 +10,4 @@ public fun foo(a: Any, b: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) {
is Int -> {}
else -> {}
}
}
}
@@ -23,14 +23,14 @@ fun test() {
Foo<String>.Bar.Baz::class
a<Foo<String>.Bar>()
a<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Foo<String>.Bar.Baz<!>>()
a<Foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar.Baz>()
a<Foo.Bar<Int>>()
a<<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Foo.Bar<Int>.Baz<!>>()
a<Foo.Bar<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>.Baz>()
}
fun <T: Foo<<!UNRESOLVED_REFERENCE!>String.Bar<!>>> x() {}
fun Foo<String>.Bar.ext() {}
fun ex1(a: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Foo<String>.Bar<String><!>): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Foo<String>.Bar<String><!> {
fun ex1(a: Foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar<String>): Foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Bar<String> {
}
@@ -1,20 +0,0 @@
class Outer<E> {
inner class Inner<F, G> {
inner abstract class Inner2Base
inner class Inner2 : Inner2Base()
inner abstract class Inner3Base<B>
inner class Inner3<H> : Inner3Base<H>()
}
fun foo(x: Outer<*>.Inner<*, *>.Inner2Base) {
if (x is Inner.Inner2) return
}
}
fun bare(x: Outer<*>.Inner<*, *>.Inner2Base, y: Outer<*>.Inner<*, *>.Inner3Base<Int>) {
if (x is Outer.Inner.Inner2) return
if (y is Outer.Inner.Inner3) return
if (y is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<String>.Inner.Inner3<!>) return
if (y is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer.Inner<String, Int>.Inner3<Double><!>) return
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class Outer<E> {
inner class Inner<F, G> {
inner abstract class Inner2Base
@@ -3,7 +3,7 @@
class Outer<T> {
inner class Inner
fun foo(x: Outer<String>.Inner, y: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer.Inner<!>, z: Inner) {
fun foo(x: Outer<String>.Inner, y: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<!>.Inner, z: Inner) {
var inner = Inner()
x.checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Inner>() }
x.checkType { _<Outer<String>.Inner>() }
@@ -40,12 +40,12 @@ fun ok5(): test.Outer.Obj.Nested2<A>.Inner5<B> = null!!
// All arguments are resolved
fun errorTypeWithArguments(): <!UNRESOLVED_REFERENCE!>Q<A>.W<B, C, D>.R.M<!> = null!!
fun error1(): Outer<A>.Inner<B>.Inner3<C, D> = null!!
fun error2(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<A>.Inner<B, C, D>.Inner2<!> = null!!
fun error3(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer.Inner<A, B>.Inner3<C><!> = null!!
fun error1(): Outer<A>.Inner<B>.Inner3<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><C, D><!> = null!!
fun error2(): Outer<A>.Inner<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><B, C, D><!>.Inner2 = null!!
fun error3(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<!>.Inner<A, B>.Inner3<C> = null!!
fun error4(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<A>.Nested<B>.Inner4<C><!> = null!!
fun error5(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer<A>.Obj.Nested2<B>.Inner5<C><!> = null!!
fun error6(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Outer.Obj<A>.Nested2<B>.Inner5<C><!> = null!!
fun error4(): Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><A><!>.Nested<B>.Inner4<C> = null!!
fun error5(): Outer<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><A><!>.Obj.Nested2<B>.Inner5<C> = null!!
fun error6(): Outer.Obj<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><A><!>.Nested2<B>.Inner5<C> = null!!
fun error7(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>test<String>.Outer.Obj.Nested2<A>.Inner5<B><!> = null!!
fun error7(): test<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String><!>.Outer.Obj.Nested2<A>.Inner5<B> = null!!
@@ -1,19 +0,0 @@
class A
interface I0<T : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>>
interface I1<T> where T : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>
interface I2<<!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!><!>> where T : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>
fun <E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>> foo0() {}
fun <E> foo1() where E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!> {}
fun <<!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!><!>> foo2() where E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!> {}
val <E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>> E.p1: Int
get() = 1
val <E> E.p2: Int where E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>
get() = 1
val <<!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!><!>> E.p3: Int where E : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>
get() = 1
// See KT-8200
interface X
public class EnumAttribute<<!MISPLACED_TYPE_PARAMETER_CONSTRAINTS!>T : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>X<T><!><!>>(val klass: Class<T>) where T : Enum<T>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class A
interface I0<T : A<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>>
interface I1<T> where T : A<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>
@@ -6,7 +6,7 @@ package p
public class A<X, Y>
public class M1 {
public val a: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!> = A<Int, Int>()
public val a: A<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!> = A<Int, Int>()
}
// MODULE: m2
@@ -16,7 +16,7 @@ package p
public class A<X, Y>
public fun foo(a: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A<Int><!>) {
public fun foo(a: A<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>) {
}
// MODULE: m3(m1, m2)
@@ -27,4 +27,4 @@ import p.*
fun test() {
foo(M1().a)
foo(1) // error type on the declaration site
}
}
@@ -1,3 +0,0 @@
class B {}
val b : <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>B<*><!> = 1
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class B {}
val b : B<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><*><!> = 1
@@ -1,14 +0,0 @@
// KT-9620 AssertionError in checkBounds
interface E1<T : D<!TYPE_ARGUMENTS_NOT_ALLOWED!><String><!>, D>
interface A
interface B
interface D<X>
interface E2<T : D<!TYPE_ARGUMENTS_NOT_ALLOWED!><A><!>, D<!SYNTAX!><<!><!SYNTAX!>B<!><!SYNTAX!>><!><!SYNTAX!>><!>
// KT-11354 AE from DescriptorResolver
open class L<E>()
class M<C> : L<C<!TYPE_ARGUMENTS_NOT_ALLOWED!><C><!>>()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// KT-9620 AssertionError in checkBounds
interface E1<T : D<!TYPE_ARGUMENTS_NOT_ALLOWED!><String><!>, D>
@@ -5,6 +5,6 @@ class OuterClass<T1> {
typealias NestedType<T> = NestedClass<T>
}
typealias ON1<T1, T2> = <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>OuterClass<T1>.NestedClass<T2><!>
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 ON3<T2> = OuterClass.NestedType<T2>
@@ -41,10 +41,10 @@ interface Test<in I, out O, P> {
fun neOk11(i: Inv<in <!TYPE_VARIANCE_CONFLICT("I; in; out; Inv<in I>")!>I<!>>)
fun neOk12(i: Inv<out <!TYPE_VARIANCE_CONFLICT("O; out; in; Inv<out O>")!>O<!>>)
fun neOk30(i: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Pair<O, ><!>)
fun neOk30(i: Pair<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><O, ><!>)
fun neOk31(i: Pair<<!TYPE_VARIANCE_CONFLICT("O; out; in; Pair<O, ERROR CLASS: Wrong number of type arguments>")!>O<!>, <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<!>>)
fun neOk32(i: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<!>)
fun neOk33(i: Inv<<!SYNTAX!><!>>)
fun neOk34(i: Inv<<!UNRESOLVED_REFERENCE!>C<!>>)
fun neOk35(i: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<P, P><!>)
fun neOk35(i: Inv<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><P, P><!>)
}
@@ -38,10 +38,10 @@ interface Test<in I, out O, P> {
var neOk22: Inv<out <!TYPE_VARIANCE_CONFLICT("O; out; invariant; Inv<out O>")!>O<!>>
var neOk23: Inv<out <!TYPE_VARIANCE_CONFLICT("I; in; invariant; Inv<out I>")!>I<!>>
var neOk30: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Pair<I, ><!>
var neOk30: Pair<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><I, ><!>
var neOk31: Pair<<!TYPE_VARIANCE_CONFLICT("I; in; invariant; Pair<I, ERROR CLASS: Wrong number of type arguments>")!>I<!>, <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<!>>
var neOk32: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<!>
var neOk33: Inv<<!SYNTAX!><!>>
var neOk34: Inv<<!UNRESOLVED_REFERENCE!>C<!>>
var neOk35: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<P, P><!>
var neOk35: Inv<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><P, P><!>
}
@@ -33,10 +33,10 @@ interface Test<in I, out O, P> {
fun neOk10(): Inv<in <!TYPE_VARIANCE_CONFLICT("O; out; in; Inv<in O>")!>O<!>>
fun neOk11(): Inv<out <!TYPE_VARIANCE_CONFLICT("I; in; out; Inv<out I>")!>I<!>>
fun neOk30(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Pair<I, ><!>
fun neOk30(): Pair<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><I, ><!>
fun neOk31(): Pair<<!TYPE_VARIANCE_CONFLICT("I; in; out; Pair<I, ERROR CLASS: Wrong number of type arguments>")!>I<!>, <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<!>>
fun neOk32(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<!>
fun neOk33(): Inv<<!SYNTAX!><!>>
fun neOk34(): Inv<<!UNRESOLVED_REFERENCE!>C<!>>
fun neOk35(): <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inv<P, P><!>
fun neOk35(): Inv<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><P, P><!>
}
@@ -1336,7 +1336,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
add(FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS) { firDiagnostic ->
WrongNumberOfTypeArgumentsImpl(
firDiagnostic.a,
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b.fir as FirClass),
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.b.fir),
firDiagnostic as FirPsiDiagnostic,
token,
)
@@ -1351,7 +1351,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
}
add(FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED) { firDiagnostic ->
OuterClassArgumentsRequiredImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a) as KtNamedClassOrObjectSymbol,
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir),
firDiagnostic as FirPsiDiagnostic,
token,
)
@@ -958,7 +958,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract class OuterClassArgumentsRequired : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = OuterClassArgumentsRequired::class
abstract val outer: KtNamedClassOrObjectSymbol
abstract val outer: KtClassLikeSymbol
}
abstract class TypeParametersInObject : KtFirDiagnostic<PsiElement>() {
@@ -1537,7 +1537,7 @@ internal class NoTypeArgumentsOnRhsImpl(
}
internal class OuterClassArgumentsRequiredImpl(
override val outer: KtNamedClassOrObjectSymbol,
override val outer: KtClassLikeSymbol,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.OuterClassArgumentsRequired(), KtAbstractFirDiagnostic<PsiElement> {