[FIR] Implement OUTER_CLASS_ARGUMENTS_REQUIRED diagnostics
This commit is contained in:
committed by
TeamCityServer
parent
f7ed2f813d
commit
0fc8be4d60
+3
@@ -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>()
|
||||||
|
|||||||
+7
@@ -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")
|
||||||
|
|||||||
+21
-1
@@ -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()
|
||||||
|
|||||||
+2
@@ -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
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-20
@@ -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())
|
||||||
|
|||||||
+8
@@ -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?
|
||||||
|
|||||||
+7
-7
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -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 ->
|
||||||
|
|||||||
+15
-8
@@ -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 {
|
||||||
|
|||||||
+12
@@ -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>) {
|
||||||
|
}
|
||||||
+7
-2
@@ -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(
|
||||||
|
|||||||
+7
-6
@@ -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(
|
||||||
|
|||||||
+2
@@ -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,
|
||||||
|
|||||||
+2
-1
@@ -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 {
|
||||||
|
|||||||
+3
-1
@@ -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)
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ class Outer<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Nested {
|
class Nested {
|
||||||
fun bar(x: Inner) {}
|
fun bar(x: <!OUTER_CLASS_ARGUMENTS_REQUIRED!>Inner<!>) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -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,
|
||||||
|
|||||||
+5
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user