[FIR] Implement OUTER_CLASS_ARGUMENTS_REQUIRED diagnostics

This commit is contained in:
Ivan Kochurkin
2021-06-17 17:53:42 +03:00
committed by TeamCityServer
parent f7ed2f813d
commit 0fc8be4d60
24 changed files with 225 additions and 59 deletions
@@ -452,6 +452,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<Int>("expectedCount") parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier") parameter<FirClassLikeSymbol<*>>("classifier")
} }
val OUTER_CLASS_ARGUMENTS_REQUIRED by error<PsiElement>() {
parameter<FirRegularClass>("outer")
}
val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>() val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<PsiElement>() val ILLEGAL_PROJECTION_USAGE by error<PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error<PsiElement>() val TYPE_PARAMETERS_IN_ENUM by error<PsiElement>()
@@ -297,6 +297,7 @@ object FirErrors {
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<PsiElement>() 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, FirClassLikeSymbol<*>>()
val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>() val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClass>()
val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>() val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>() val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>() val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>()
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNC
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_COLLECTION_OF_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_COLLECTION_OF_TYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
@@ -255,6 +256,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_RENAMED_ON_IMPORT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_RENAMED_ON_IMPORT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE_IMPORTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE_IMPORTED
@@ -717,6 +719,11 @@ class FirDefaultErrorMessages {
null, null,
SYMBOL SYMBOL
) )
map.put(
OUTER_CLASS_ARGUMENTS_REQUIRED,
"Type arguments should be specified for an outer {0}. Use full class name to specify them",
RENDER_CLASS_OR_OBJECT_NAME
)
map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects") map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects")
// map.put(ILLEGAL_PROJECTION_USAGE, ...) // & // map.put(ILLEGAL_PROJECTION_USAGE, ...) // &
map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters") map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters")
@@ -12,8 +12,9 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderer
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -79,6 +80,25 @@ object FirDiagnosticRenderers {
"$classOrObject $name" "$classOrObject $name"
} }
val RENDER_CLASS_OR_OBJECT_NAME = Renderer { firClassLike: FirClassLikeDeclaration ->
val name = firClassLike.classId.relativeClassName.shortName().asString()
val prefix = when (firClassLike) {
is FirTypeAlias -> "typealias"
is FirRegularClass -> {
when {
firClassLike.isCompanion -> "companion object"
firClassLike.isInterface -> "interface"
firClassLike.isEnumClass -> "enum class"
firClassLike.isFromEnumClass -> "enum entry"
firClassLike.isLocalClassOrAnonymousObject() -> "object"
else -> "class"
}
}
else -> AssertionError("Unexpected class: $firClassLike")
}
"$prefix '$name'"
}
val RENDER_TYPE = Renderer { t: ConeKotlinType -> val RENDER_TYPE = Renderer { t: ConeKotlinType ->
// TODO: need a way to tune granuality, e.g., without parameter names in functional types. // TODO: need a way to tune granuality, e.g., without parameter names in functional types.
t.render() t.render()
@@ -69,6 +69,8 @@ private fun ConeDiagnostic.toFirDiagnostic(
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString()) is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
is ConeWrongNumberOfTypeArgumentsError -> is ConeWrongNumberOfTypeArgumentsError ->
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type) FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
is ConeOuterClassArgumentsRequired ->
FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(qualifiedAccessSource ?: source, this.type)
is ConeNoTypeArgumentsOnRhsError -> is ConeNoTypeArgumentsOnRhsError ->
FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type) FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
is ConeSimpleDiagnostic -> when (source.kind) { is ConeSimpleDiagnostic -> when (source.kind) {
@@ -6,10 +6,11 @@
package org.jetbrains.kotlin.fir.resolve package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSessionComponent 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.scopes.FirScope
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
abstract class FirTypeResolver : FirSessionComponent { abstract class FirTypeResolver : FirSessionComponent {
abstract fun resolveType(typeRef: FirTypeRef, scope: FirScope, areBareTypesAllowed: Boolean): ConeKotlinType abstract fun resolveType(typeRef: FirTypeRef, scopeClassDeclaration: ScopeClassDeclaration, areBareTypesAllowed: Boolean): ConeKotlinType
} }
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* 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.expandedConeType
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
@@ -447,3 +448,44 @@ fun FirFunction.getAsForbiddenNamedArgumentsTarget(session: FirSession): Forbidd
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.functionProto
// org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto // org.jetbrains.kotlin.fir.serialization.FirElementSerializer.constructorProto
fun FirFunction.getHasStableParameterNames(session: FirSession): Boolean = getAsForbiddenNamedArgumentsTarget(session) == null 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 containsTypeParameter(currentClassDeclaration: FirRegularClass): Boolean {
val result = currentClassDeclaration.typeParameters.any { it.symbol == typeParameter.symbol }
if (result) {
return true
}
for (superTypeRef in currentClassDeclaration.superTypeRefs) {
val superClassFir = superTypeRef.firClassLike(session)
if (superClassFir == null || superClassFir is FirRegularClass && containsTypeParameter(superClassFir)) {
return true
}
}
return false
}
return containsTypeParameter(classDeclaration)
}
fun getClassThatContainsTypeParameter(klass: FirRegularClass, typeParameter: FirTypeParameterRef): FirRegularClass? {
if (klass.typeParameters.any { param -> param.symbol == typeParameter.symbol }) {
return klass
}
for (declaration in klass.declarations) {
if (declaration is FirRegularClass) {
val result = getClassThatContainsTypeParameter(declaration, typeParameter)
if (result != null) {
return result
}
}
}
return null
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.diagnostics
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration 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.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.resolve.calls.Candidate
@@ -113,6 +114,12 @@ class ConeNoTypeArgumentsOnRhsError(
override val reason: String get() = "No type arguments on RHS" override val reason: String get() = "No type arguments on RHS"
} }
class ConeOuterClassArgumentsRequired(
val type: FirRegularClass,
) : ConeDiagnostic() {
override val reason: String = "Type arguments should be specified for an outer class"
}
class ConeInstanceAccessBeforeSuperCall(val target: String) : ConeDiagnostic() { class ConeInstanceAccessBeforeSuperCall(val target: String) : ConeDiagnostic() {
override val reason: String get() = "Cannot access ''${target}'' before superclass constructor has been called" override val reason: String get() = "Cannot access ''${target}'' before superclass constructor has been called"
} }
@@ -8,15 +8,17 @@ package org.jetbrains.kotlin.fir.resolve.providers.impl
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.ThreadSafeMutableState 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.diagnostics.ConeUnexpectedTypeArgumentsError import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeOuterClassArgumentsRequired
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedQualifierError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedQualifierError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedDynamicType import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedDynamicType
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeWrongNumberOfTypeArgumentsError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeWrongNumberOfTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -46,7 +48,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
private fun resolveToSymbol( private fun resolveToSymbol(
typeRef: FirTypeRef, typeRef: FirTypeRef,
scope: FirScope scopeClassDeclaration: ScopeClassDeclaration
): Pair<FirClassifierSymbol<*>?, ConeSubstitutor?> { ): Pair<FirClassifierSymbol<*>?, ConeSubstitutor?> {
return when (typeRef) { return when (typeRef) {
is FirResolvedTypeRef -> { is FirResolvedTypeRef -> {
@@ -58,7 +60,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
val qualifierResolver = session.qualifierResolver val qualifierResolver = session.qualifierResolver
var resolvedSymbol: FirClassifierSymbol<*>? = null var resolvedSymbol: FirClassifierSymbol<*>? = null
var substitutor: ConeSubstitutor? = null var substitutor: ConeSubstitutor? = null
scope.processClassifiersByNameWithSubstitution(typeRef.qualifier.first().name) { symbol, substitutorFromScope -> scopeClassDeclaration.scope.processClassifiersByNameWithSubstitution(typeRef.qualifier.first().name) { symbol, substitutorFromScope ->
if (resolvedSymbol != null) return@processClassifiersByNameWithSubstitution if (resolvedSymbol != null) return@processClassifiersByNameWithSubstitution
resolvedSymbol = when (symbol) { resolvedSymbol = when (symbol) {
is FirClassLikeSymbol<*> -> { is FirClassLikeSymbol<*> -> {
@@ -94,7 +96,8 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
typeRef: FirUserTypeRef, typeRef: FirUserTypeRef,
symbol: FirClassifierSymbol<*>?, symbol: FirClassifierSymbol<*>?,
substitutor: ConeSubstitutor?, substitutor: ConeSubstitutor?,
areBareTypesAllowed: Boolean areBareTypesAllowed: Boolean,
scopeClassDeclaration: ScopeClassDeclaration
): ConeKotlinType { ): ConeKotlinType {
if (symbol == null) { if (symbol == null) {
return ConeKotlinErrorType(ConeUnresolvedQualifierError(typeRef.render())) return ConeKotlinErrorType(ConeUnresolvedQualifierError(typeRef.render()))
@@ -117,24 +120,43 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
return ConeClassErrorType(ConeWrongNumberOfTypeArgumentsError(symbol.fir.typeParameters.size, symbol)) return ConeClassErrorType(ConeWrongNumberOfTypeArgumentsError(symbol.fir.typeParameters.size, symbol))
} else { } else {
val substitutor = substitutor ?: ConeSubstitutor.Empty val substitutor = substitutor ?: ConeSubstitutor.Empty
var problemTypeParameter: FirTypeParameterRef? = null
val classDeclarations = scopeClassDeclaration.classDeclarations
val argumentsFromOuterClassesAndParents = symbol.fir.typeParameters.drop(typeArguments.size).mapNotNull { val argumentsFromOuterClassesAndParents = symbol.fir.typeParameters.drop(typeArguments.size).mapNotNull {
val type = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(it.symbol), isNullable = false) if (isValidTypeParameter(it, classDeclarations.lastOrNull(), session)) {
// we should report ConeSimpleDiagnostic(..., WrongNumberOfTypeArguments) val type = ConeTypeParameterTypeImpl(ConeTypeParameterLookupTag(it.symbol), isNullable = false)
// but genericArgumentNumberMismatch.kt test fails with // we should report ConeSimpleDiagnostic(..., WrongNumberOfTypeArguments)
// index out of bounds exception for start offset of // but genericArgumentNumberMismatch.kt test fails with
// the source // index out of bounds exception for start offset of
substitutor.substituteOrNull(type) // the source
substitutor.substituteOrNull(type)
} else {
if (problemTypeParameter == null) {
problemTypeParameter = it
}
null
}
}.toTypedArray<ConeTypeProjection>() }.toTypedArray<ConeTypeProjection>()
typeArguments += argumentsFromOuterClassesAndParents typeArguments += argumentsFromOuterClassesAndParents
if (typeArguments.size != symbol.fir.typeParameters.size) { if (typeArguments.size != symbol.fir.typeParameters.size) {
return ConeClassErrorType( if (problemTypeParameter != null) {
ConeWrongNumberOfTypeArgumentsError( var outerClass: FirRegularClass? = null
desiredCount = symbol.fir.typeParameters.size - argumentsFromOuterClassesAndParents.size, classDeclarations.forEach {
type = symbol getClassThatContainsTypeParameter(it, problemTypeParameter!!)?.let { result ->
outerClass = result
return@forEach
}
}
return ConeClassErrorType(ConeOuterClassArgumentsRequired(outerClass!!))
} else {
return ConeClassErrorType(
ConeWrongNumberOfTypeArgumentsError(
desiredCount = symbol.fir.typeParameters.size - argumentsFromOuterClassesAndParents.size,
type = symbol
)
) )
) }
} }
} }
} }
@@ -174,14 +196,14 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
override fun resolveType( override fun resolveType(
typeRef: FirTypeRef, typeRef: FirTypeRef,
scope: FirScope, scopeClassDeclaration: ScopeClassDeclaration,
areBareTypesAllowed: Boolean areBareTypesAllowed: Boolean
): ConeKotlinType { ): ConeKotlinType {
return when (typeRef) { return when (typeRef) {
is FirResolvedTypeRef -> typeRef.type is FirResolvedTypeRef -> typeRef.type
is FirUserTypeRef -> { is FirUserTypeRef -> {
val (symbol, substitutor) = resolveToSymbol(typeRef, scope) val (symbol, substitutor) = resolveToSymbol(typeRef, scopeClassDeclaration)
resolveUserType(typeRef, symbol, substitutor, areBareTypesAllowed) resolveUserType(typeRef, symbol, substitutor, areBareTypesAllowed, scopeClassDeclaration)
} }
is FirFunctionTypeRef -> createFunctionalType(typeRef) is FirFunctionTypeRef -> createFunctionalType(typeRef)
is FirDynamicTypeRef -> ConeKotlinErrorType(ConeUnsupportedDynamicType()) is FirDynamicTypeRef -> ConeKotlinErrorType(ConeUnsupportedDynamicType())
@@ -30,6 +30,7 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
protected val scopeSession: ScopeSession protected val scopeSession: ScopeSession
) : FirAbstractTreeTransformer<Any?>(phase) { ) : FirAbstractTreeTransformer<Any?>(phase) {
protected val scopes = mutableListOf<FirScope>() protected val scopes = mutableListOf<FirScope>()
protected val classDeclarations = mutableListOf<FirRegularClass>()
protected val towerScope = FirCompositeScope(scopes.asReversed()) protected val towerScope = FirCompositeScope(scopes.asReversed())
protected open fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = transformerPhase > firDeclaration.resolvePhase protected open fun needReplacePhase(firDeclaration: FirDeclaration): Boolean = transformerPhase > firDeclaration.resolvePhase
@@ -45,6 +46,13 @@ abstract class FirAbstractTreeTransformerWithSuperTypes(
return result return result
} }
protected inline fun <T> withClassDeclarationCleanup(declaration: FirRegularClass, crossinline l: () -> T): T {
classDeclarations.add(declaration)
val result = l()
classDeclarations.removeAt(classDeclarations.lastIndex)
return result
}
protected fun resolveNestedClassesSupertypes( protected fun resolveNestedClassesSupertypes(
firClass: FirClass, firClass: FirClass,
data: Any? data: Any?
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class FirSpecificTypeResolverTransformer( class FirSpecificTypeResolverTransformer(
override val session: FirSession, override val session: FirSession,
private val errorTypeAsResolved: Boolean = true private val errorTypeAsResolved: Boolean = true
) : FirAbstractTreeTransformer<FirScope>(phase = FirResolvePhase.SUPER_TYPES) { ) : FirAbstractTreeTransformer<ScopeClassDeclaration>(phase = FirResolvePhase.SUPER_TYPES) {
private val typeResolver = session.typeResolver private val typeResolver = session.typeResolver
@set:PrivateForInline @set:PrivateForInline
@@ -53,8 +53,8 @@ class FirSpecificTypeResolverTransformer(
} }
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
override fun transformTypeRef(typeRef: FirTypeRef, data: FirScope): FirResolvedTypeRef { override fun transformTypeRef(typeRef: FirTypeRef, data: ScopeClassDeclaration): FirResolvedTypeRef {
session.lookupTracker?.recordTypeLookup(typeRef, data.scopeOwnerLookupNames, currentFile?.source) session.lookupTracker?.recordTypeLookup(typeRef, data.scope.scopeOwnerLookupNames, currentFile?.source)
typeRef.transformChildren(this, data) typeRef.transformChildren(this, data)
return transformType(typeRef, typeResolver.resolveType(typeRef, data, areBareTypesAllowed)) return transformType(typeRef, typeResolver.resolveType(typeRef, data, areBareTypesAllowed))
} }
@@ -62,10 +62,10 @@ class FirSpecificTypeResolverTransformer(
@OptIn(PrivateForInline::class) @OptIn(PrivateForInline::class)
override fun transformFunctionTypeRef( override fun transformFunctionTypeRef(
functionTypeRef: FirFunctionTypeRef, functionTypeRef: FirFunctionTypeRef,
data: FirScope data: ScopeClassDeclaration
): FirResolvedTypeRef { ): FirResolvedTypeRef {
functionTypeRef.transformChildren(this, data) functionTypeRef.transformChildren(this, data)
session.lookupTracker?.recordTypeLookup(functionTypeRef, data.scopeOwnerLookupNames, currentFile?.source) session.lookupTracker?.recordTypeLookup(functionTypeRef, data.scope.scopeOwnerLookupNames, currentFile?.source)
val resolvedType = typeResolver.resolveType(functionTypeRef, data, areBareTypesAllowed).takeIfAcceptable() val resolvedType = typeResolver.resolveType(functionTypeRef, data, areBareTypesAllowed).takeIfAcceptable()
return if (resolvedType != null && resolvedType !is ConeClassErrorType) { return if (resolvedType != null && resolvedType !is ConeClassErrorType) {
buildResolvedTypeRef { buildResolvedTypeRef {
@@ -118,11 +118,11 @@ class FirSpecificTypeResolverTransformer(
!errorTypeAsResolved && it is ConeClassErrorType !errorTypeAsResolved && it is ConeClassErrorType
} }
override fun transformResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: FirScope): FirTypeRef { override fun transformResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: ScopeClassDeclaration): FirTypeRef {
return resolvedTypeRef return resolvedTypeRef
} }
override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: FirScope): FirTypeRef { override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: ScopeClassDeclaration): FirTypeRef {
return implicitTypeRef return implicitTypeRef
} }
} }
@@ -215,6 +215,7 @@ open class FirSupertypeResolverVisitor(
private val firProviderInterceptor: FirProviderInterceptor? = null, private val firProviderInterceptor: FirProviderInterceptor? = null,
) : FirDefaultVisitor<Unit, Any?>() { ) : FirDefaultVisitor<Unit, Any?>() {
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
private val classDeclarations = mutableListOf<FirRegularClass>()
private fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? = private fun getFirClassifierContainerFileIfAny(symbol: FirClassLikeSymbol<*>): FirFile? =
if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierContainerFileIfAny(symbol) if (firProviderInterceptor != null) firProviderInterceptor.getFirClassifierContainerFileIfAny(symbol)
@@ -291,7 +292,7 @@ open class FirSupertypeResolverVisitor(
private fun resolveSpecificClassLikeSupertypes( private fun resolveSpecificClassLikeSupertypes(
classLikeDeclaration: FirClassLikeDeclaration, classLikeDeclaration: FirClassLikeDeclaration,
resolveSuperTypeRefs: (FirTransformer<FirScope>, FirScope) -> List<FirResolvedTypeRef> resolveSuperTypeRefs: (FirTransformer<ScopeClassDeclaration>, ScopeClassDeclaration) -> List<FirResolvedTypeRef>
): List<FirTypeRef> { ): List<FirTypeRef> {
when (val status = supertypeComputationSession.getSupertypesComputationStatus(classLikeDeclaration)) { when (val status = supertypeComputationSession.getSupertypesComputationStatus(classLikeDeclaration)) {
is SupertypeComputationStatus.Computed -> return status.supertypeRefs is SupertypeComputationStatus.Computed -> return status.supertypeRefs
@@ -308,7 +309,7 @@ open class FirSupertypeResolverVisitor(
val scopes = prepareScopes(classLikeDeclaration) val scopes = prepareScopes(classLikeDeclaration)
val transformer = FirSpecificTypeResolverTransformer(session) val transformer = FirSpecificTypeResolverTransformer(session)
val resolvedTypesRefs = resolveSuperTypeRefs(transformer, FirCompositeScope(scopes)) val resolvedTypesRefs = resolveSuperTypeRefs(transformer, ScopeClassDeclaration(FirCompositeScope(scopes), classDeclarations))
supertypeComputationSession.storeSupertypes(classLikeDeclaration, resolvedTypesRefs) supertypeComputationSession.storeSupertypes(classLikeDeclaration, resolvedTypesRefs)
return resolvedTypesRefs return resolvedTypesRefs
@@ -319,8 +320,10 @@ open class FirSupertypeResolverVisitor(
} }
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?) { override fun visitRegularClass(regularClass: FirRegularClass, data: Any?) {
classDeclarations.add(regularClass)
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs) resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
visitDeclarationContent(regularClass, null) visitDeclarationContent(regularClass, null)
classDeclarations.removeAt(classDeclarations.lastIndex)
} }
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) { override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) {
@@ -332,12 +335,12 @@ open class FirSupertypeResolverVisitor(
classLikeDeclaration: FirClassLikeDeclaration, classLikeDeclaration: FirClassLikeDeclaration,
supertypeRefs: List<FirTypeRef> supertypeRefs: List<FirTypeRef>
): List<FirTypeRef> { ): List<FirTypeRef> {
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scope -> return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scopeDeclaration ->
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) { if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
session.lookupTracker?.let { session.lookupTracker?.let {
val fileSource = getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.source val fileSource = getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.source
for (supertypeRef in supertypeRefs) { for (supertypeRef in supertypeRefs) {
it.recordTypeLookup(supertypeRef, scope.scopeOwnerLookupNames, fileSource) it.recordTypeLookup(supertypeRef, scopeDeclaration.scope.scopeOwnerLookupNames, fileSource)
} }
} }
} }
@@ -348,7 +351,7 @@ open class FirSupertypeResolverVisitor(
So we create a copy of supertypeRefs to avoid it So we create a copy of supertypeRefs to avoid it
*/ */
supertypeRefs.createCopy().mapTo(mutableListOf()) { supertypeRefs.createCopy().mapTo(mutableListOf()) {
val superTypeRef = transformer.transformTypeRef(it, scope) val superTypeRef = transformer.transformTypeRef(it, scopeDeclaration)
val typeParameterType = superTypeRef.coneTypeSafe<ConeTypeParameterType>() val typeParameterType = superTypeRef.coneTypeSafe<ConeTypeParameterType>()
when { when {
typeParameterType != null -> typeParameterType != null ->
@@ -64,15 +64,17 @@ open class FirTypeResolveTransformer(
} }
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement { override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): FirStatement {
withScopeCleanup { return withClassDeclarationCleanup(regularClass) {
regularClass.addTypeParametersScope() withScopeCleanup {
regularClass.typeParameters.forEach { regularClass.addTypeParametersScope()
it.accept(this, data) regularClass.typeParameters.forEach {
it.accept(this, data)
}
unboundCyclesInTypeParametersSupertypes(regularClass)
} }
unboundCyclesInTypeParametersSupertypes(regularClass)
}
return resolveNestedClassesSupertypes(regularClass, data) resolveNestedClassesSupertypes(regularClass, data)
}
} }
override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): FirStatement { override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): FirStatement {
@@ -185,7 +187,12 @@ open class FirTypeResolveTransformer(
} }
override fun transformTypeRef(typeRef: FirTypeRef, data: Any?): FirResolvedTypeRef { override fun transformTypeRef(typeRef: FirTypeRef, data: Any?): FirResolvedTypeRef {
return typeResolverTransformer.withFile(currentFile) { typeRef.transform(typeResolverTransformer, towerScope) } return typeResolverTransformer.withFile(currentFile) {
typeRef.transform(
typeResolverTransformer,
ScopeClassDeclaration(towerScope, classDeclarations)
)
}
} }
override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): FirStatement { override fun transformValueParameter(valueParameter: FirValueParameter, data: Any?): FirStatement {
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.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>) {
}
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.impl.createCurrentScopeList import org.jetbrains.kotlin.fir.scopes.impl.createCurrentScopeList
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
@@ -46,6 +47,7 @@ open class FirBodyResolveTransformer(
internal open val expressionsTransformer = FirExpressionsResolveTransformer(this) internal open val expressionsTransformer = FirExpressionsResolveTransformer(this)
protected open val declarationsTransformer = FirDeclarationsResolveTransformer(this) protected open val declarationsTransformer = FirDeclarationsResolveTransformer(this)
private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this) private val controlFlowStatementsTransformer = FirControlFlowStatementsResolveTransformer(this)
private val classDeclarations = mutableListOf<FirRegularClass>()
override fun transformFile(file: FirFile, data: ResolutionMode): FirFile { override fun transformFile(file: FirFile, data: ResolutionMode): FirFile {
checkSessionConsistency(file) checkSessionConsistency(file)
@@ -68,7 +70,7 @@ open class FirBodyResolveTransformer(
typeRef typeRef
} else { } else {
typeResolverTransformer.withFile(context.file) { typeResolverTransformer.withFile(context.file) {
transformTypeRef(typeRef, FirCompositeScope(components.createCurrentScopeList())) transformTypeRef(typeRef, ScopeClassDeclaration(FirCompositeScope(components.createCurrentScopeList()), classDeclarations))
} }
} }
return resolvedTypeRef.transformAnnotations(this, data) return resolvedTypeRef.transformAnnotations(this, data)
@@ -261,7 +263,10 @@ open class FirBodyResolveTransformer(
} }
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement { override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirStatement {
return declarationsTransformer.transformRegularClass(regularClass, data) classDeclarations.add(regularClass)
val result = declarationsTransformer.transformRegularClass(regularClass, data)
classDeclarations.removeAt(classDeclarations.lastIndex)
return result
} }
override fun transformAnonymousObject( override fun transformAnonymousObject(
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.extensions.* import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.fqName import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractPhaseTransformer import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirSpecificTypeResolverTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
class FirPluginAnnotationsResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) { class FirPluginAnnotationsResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
@@ -93,6 +90,7 @@ private class FirAnnotationResolveTransformer(
) )
private var owners: PersistentList<FirAnnotatedDeclaration> = persistentListOf() private var owners: PersistentList<FirAnnotatedDeclaration> = persistentListOf()
protected val classDeclarations = mutableListOf<FirRegularClass>()
override fun beforeChildren(declaration: FirAnnotatedDeclaration): PersistentList<FirAnnotatedDeclaration> { override fun beforeChildren(declaration: FirAnnotatedDeclaration): PersistentList<FirAnnotatedDeclaration> {
val current = owners val current = owners
@@ -109,14 +107,15 @@ private class FirAnnotationResolveTransformer(
annotationCall: FirAnnotationCall, annotationCall: FirAnnotationCall,
data: Multimap<AnnotationFqn, FirRegularClass> data: Multimap<AnnotationFqn, FirRegularClass>
): FirStatement { ): FirStatement {
return annotationCall.transformAnnotationTypeRef(typeResolverTransformer, scope) return annotationCall.transformAnnotationTypeRef(typeResolverTransformer, ScopeClassDeclaration(scope, listOf()))
} }
override fun transformRegularClass( override fun transformRegularClass(
regularClass: FirRegularClass, regularClass: FirRegularClass,
data: Multimap<AnnotationFqn, FirRegularClass> data: Multimap<AnnotationFqn, FirRegularClass>
): FirStatement { ): FirStatement {
return super.transformRegularClass(regularClass, data).also { classDeclarations.add(regularClass)
val result = super.transformRegularClass(regularClass, data).also {
if (regularClass.classKind == ClassKind.ANNOTATION_CLASS && metaAnnotations.isNotEmpty()) { if (regularClass.classKind == ClassKind.ANNOTATION_CLASS && metaAnnotations.isNotEmpty()) {
val annotations = regularClass.annotations.mapNotNull { it.fqName(session) } val annotations = regularClass.annotations.mapNotNull { it.fqName(session) }
for (annotation in annotations.filter { it in metaAnnotations }) { for (annotation in annotations.filter { it in metaAnnotations }) {
@@ -124,6 +123,8 @@ private class FirAnnotationResolveTransformer(
} }
} }
} }
classDeclarations.removeAt(classDeclarations.lastIndex)
return result
} }
override fun transformAnnotatedDeclaration( override fun transformAnnotatedDeclaration(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.declarations.builder package org.jetbrains.kotlin.fir.declarations.builder
import kotlin.contracts.* import kotlin.contracts.*
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirPureAbstractElement import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
@@ -24,6 +25,7 @@ class FirOuterClassTypeParameterRefBuilder {
var source: FirSourceElement? = null var source: FirSourceElement? = null
lateinit var symbol: FirTypeParameterSymbol lateinit var symbol: FirTypeParameterSymbol
@OptIn(FirImplementationDetail::class)
fun build(): FirTypeParameterRef { fun build(): FirTypeParameterRef {
return FirOuterClassTypeParameterRef( return FirOuterClassTypeParameterRef(
source, source,
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.declarations.impl package org.jetbrains.kotlin.fir.declarations.impl
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirPureAbstractElement import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
@@ -16,7 +17,7 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY * DO NOT MODIFY IT MANUALLY
*/ */
internal class FirOuterClassTypeParameterRef( class FirOuterClassTypeParameterRef @FirImplementationDetail constructor(
override val source: FirSourceElement?, override val source: FirSourceElement?,
override val symbol: FirTypeParameterSymbol, override val symbol: FirTypeParameterSymbol,
) : FirPureAbstractElement(), FirTypeParameterRef { ) : FirPureAbstractElement(), FirTypeParameterRef {
@@ -25,7 +25,9 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
defaultTrue("isPrimary", withGetter = true) defaultTrue("isPrimary", withGetter = true)
} }
impl(typeParameterRef, "FirOuterClassTypeParameterRef") impl(typeParameterRef, "FirOuterClassTypeParameterRef") {
publicImplementation()
}
impl(typeParameterRef, "FirConstructedClassTypeParameterRef") impl(typeParameterRef, "FirConstructedClassTypeParameterRef")
noImpl(declarationStatus) noImpl(declarationStatus)
@@ -11,7 +11,7 @@ class Outer<E> {
} }
class Nested { class Nested {
fun bar(x: Inner) {} fun bar(x: <!OUTER_CLASS_ARGUMENTS_REQUIRED!>Inner<!>) {}
} }
} }
@@ -11,13 +11,13 @@ class A<T> {
} }
class Nested { class Nested {
val x: B<String>? = null val x: <!OUTER_CLASS_ARGUMENTS_REQUIRED("class 'A'")!>B<String>?<!> = null
val y: B<String>.C<String>? = null val y: <!OUTER_CLASS_ARGUMENTS_REQUIRED("class 'A'")!>B<String>.C<String>?<!> = null
val z: B<String>.D? = null val z: <!OUTER_CLASS_ARGUMENTS_REQUIRED("class 'A'")!>B<String>.D?<!> = null
val c: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>C<Int>?<!> = null val c: <!OUTER_CLASS_ARGUMENTS_REQUIRED("class 'B'")!>C<Int>?<!> = null
val d: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>D?<!> = null val d: <!OUTER_CLASS_ARGUMENTS_REQUIRED("class 'B'")!>D?<!> = null
val innerMost: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Innermost<String>?<!> = null val innerMost: <!OUTER_CLASS_ARGUMENTS_REQUIRED("class 'B'")!>Innermost<String>?<!> = null
} }
} }
@@ -1349,6 +1349,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED) { firDiagnostic ->
OuterClassArgumentsRequiredImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a) as KtNamedClassOrObjectSymbol,
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirErrors.TYPE_PARAMETERS_IN_OBJECT) { firDiagnostic -> add(FirErrors.TYPE_PARAMETERS_IN_OBJECT) { firDiagnostic ->
TypeParametersInObjectImpl( TypeParametersInObjectImpl(
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
@@ -956,6 +956,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val classifier: KtClassLikeSymbol abstract val classifier: KtClassLikeSymbol
} }
abstract class OuterClassArgumentsRequired : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = OuterClassArgumentsRequired::class
abstract val outer: KtNamedClassOrObjectSymbol
}
abstract class TypeParametersInObject : KtFirDiagnostic<PsiElement>() { abstract class TypeParametersInObject : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = TypeParametersInObject::class override val diagnosticClass get() = TypeParametersInObject::class
} }
@@ -1536,6 +1536,14 @@ internal class NoTypeArgumentsOnRhsImpl(
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
} }
internal class OuterClassArgumentsRequiredImpl(
override val outer: KtNamedClassOrObjectSymbol,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.OuterClassArgumentsRequired(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class TypeParametersInObjectImpl( internal class TypeParametersInObjectImpl(
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,