[FIR] Missing NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE

^KT-59433 Fixed
This commit is contained in:
Vladimir Sukharev
2023-10-11 00:33:33 +02:00
committed by Space Team
parent da1fa8fce4
commit 16dfc6df71
11 changed files with 45 additions and 2 deletions
@@ -524,6 +524,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE) { firDiagnostic ->
NestedClassAccessedViaInstanceReferenceImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.SUPER_IS_NOT_AN_EXPRESSION) { firDiagnostic ->
SuperIsNotAnExpressionImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -414,6 +414,11 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val suggestedFunction: String
}
interface NestedClassAccessedViaInstanceReference : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = NestedClassAccessedViaInstanceReference::class
val symbol: KtClassLikeSymbol
}
interface SuperIsNotAnExpression : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = SuperIsNotAnExpression::class
}
@@ -480,6 +480,12 @@ internal class DeprecatedBinaryModImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.DeprecatedBinaryMod
internal class NestedClassAccessedViaInstanceReferenceImpl(
override val symbol: KtClassLikeSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.NestedClassAccessedViaInstanceReference
internal class SuperIsNotAnExpressionImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
@@ -225,6 +225,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirBasedSymbol<*>>("forbiddenFunction")
parameter<String>("suggestedFunction")
}
val NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE by error<PsiElement> {
parameter<FirClassLikeSymbol<*>>("symbol")
}
}
val SUPER by object : DiagnosticGroup("Super") {
@@ -194,6 +194,7 @@ object FirErrors {
val AMBIGUOUS_ALTERED_ASSIGN by error1<PsiElement, List<String?>>()
val FORBIDDEN_BINARY_MOD by error2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.OPERATOR_MODIFIER)
val DEPRECATED_BINARY_MOD by error2<PsiElement, FirBasedSymbol<*>, String>(SourceElementPositioningStrategies.OPERATOR_MODIFIER)
val NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE by error1<PsiElement, FirClassLikeSymbol<*>>()
// Super
val SUPER_IS_NOT_AN_EXPRESSION by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
@@ -68,6 +68,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
"AMBIGUOUS_ALTERED_ASSIGN",
"FORBIDDEN_BINARY_MOD",
"DEPRECATED_BINARY_MOD",
"NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE",
"SUPER_IS_NOT_AN_EXPRESSION",
"SUPER_NOT_AVAILABLE",
"ABSTRACT_SUPER_CALL",
@@ -127,6 +127,8 @@ private fun ConeDiagnostic.toKtDiagnostic(
FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source)
is ConeTypeArgumentsForOuterClassWhenNestedReferencedError ->
FirErrors.TYPE_ARGUMENTS_FOR_OUTER_CLASS_WHEN_NESTED_REFERENCED.createOn(this.source)
is ConeNestedClassAccessedViaInstanceReference ->
FirErrors.NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE.createOn(this.source, this.symbol)
is ConeOuterClassArgumentsRequired ->
FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(callOrAssignmentSource ?: source, this.symbol)
@@ -352,7 +352,7 @@ class FirCallResolver(
referencedSymbol,
qualifiedAccess.source,
qualifiedAccess.typeArguments,
diagnostic,
diagnostic ?: extractNestedClassAccessDiagnostic(nameReference.source, qualifiedAccess.explicitReceiver, referencedSymbol),
nonFatalDiagnostics = extractNonFatalDiagnostics(
nameReference.source,
qualifiedAccess.explicitReceiver,
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.calls.getSingleVisibleClassifier
import org.jetbrains.kotlin.fir.resolve.createCurrentScopeList
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDeprecated
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeNestedClassAccessedViaInstanceReference
import org.jetbrains.kotlin.fir.resolve.setTypeOfQualifier
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
@@ -184,6 +185,16 @@ private fun FqName.continueQualifierInPackage(
}
}
internal fun extractNestedClassAccessDiagnostic(
source: KtSourceElement?,
explicitReceiver: FirExpression?,
symbol: FirClassLikeSymbol<*>
): ConeDiagnostic? {
if ((explicitReceiver as? FirResolvedQualifier)?.typeArguments?.isNotEmpty() == true)
return ConeNestedClassAccessedViaInstanceReference(source!!, symbol)
return null
}
internal fun extractNonFatalDiagnostics(
source: KtSourceElement?,
explicitReceiver: FirExpression?,
@@ -272,6 +272,13 @@ class ConeTypeArgumentsForOuterClassWhenNestedReferencedError(source: KtSourceEl
override val reason: String get() = "Type arguments for outer class are redundant when nested class is referenced"
}
class ConeNestedClassAccessedViaInstanceReference(
source: KtSourceElement,
val symbol: FirClassLikeSymbol<*>,
) : ConeDiagnosticWithSource(source) {
override val reason: String get() = "Nested ${symbol.classId} accessed via instance reference"
}
class ConeNoTypeArgumentsOnRhsError(
override val desiredCount: Int,
override val symbol: FirClassLikeSymbol<*>
@@ -3,4 +3,4 @@ open class MyClass<T> {
}
val foo1 = MyClass.MyObject // it's ok
val foo2 = MyClass<Boolean>.MyObject // here's stofl
val foo2 = MyClass<Boolean>.<!NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE!>MyObject<!> // here's stofl