[FIR] Implement NO_RECEIVER_ALLOWED
This commit is contained in:
+1
@@ -119,6 +119,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<Boolean>("hasValueParameters")
|
||||
}
|
||||
val ILLEGAL_SELECTOR by error<PsiElement>()
|
||||
val NO_RECEIVER_ALLOWED by error<PsiElement>()
|
||||
}
|
||||
|
||||
val SUPER by object : DiagnosticGroup("Super") {
|
||||
|
||||
@@ -132,6 +132,7 @@ object FirErrors {
|
||||
val CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS by error0<KtExpression>()
|
||||
val FUNCTION_CALL_EXPECTED by error2<PsiElement, String, Boolean>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||
val ILLEGAL_SELECTOR by error0<PsiElement>()
|
||||
val NO_RECEIVER_ALLOWED by error0<PsiElement>()
|
||||
|
||||
// Super
|
||||
val SUPER_IS_NOT_AN_EXPRESSION by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||
|
||||
+2
@@ -272,6 +272,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ACTUAL_FOR_EXP
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_COMPANION_OBJECT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_GET_METHOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_RECEIVER_ALLOWED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_SET_METHOD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
|
||||
@@ -496,6 +497,7 @@ class FirDefaultErrorMessages {
|
||||
map.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class")
|
||||
map.put(FUNCTION_CALL_EXPECTED, "Function invocation ''{0}({1})'' expected", TO_STRING, FUNCTION_PARAMETERS)
|
||||
map.put(ILLEGAL_SELECTOR, "The expression cannot be a selector (occur after a dot)")
|
||||
map.put(NO_RECEIVER_ALLOWED, "No receiver can be passed to this function or property")
|
||||
|
||||
// Supertypes
|
||||
map.put(NOT_A_SUPERTYPE, "Not an immediate supertype")
|
||||
|
||||
+1
@@ -363,6 +363,7 @@ private fun ConeSimpleDiagnostic.getFactory(source: FirSourceElement): FirDiagno
|
||||
DiagnosticKind.RecursiveTypealiasExpansion -> FirErrors.RECURSIVE_TYPEALIAS_EXPANSION
|
||||
DiagnosticKind.LoopInSupertype -> FirErrors.CYCLIC_INHERITANCE_HIERARCHY
|
||||
DiagnosticKind.IllegalSelector -> FirErrors.ILLEGAL_SELECTOR
|
||||
DiagnosticKind.NoReceiverAllowed -> FirErrors.NO_RECEIVER_ALLOWED
|
||||
DiagnosticKind.IsEnumEntry -> FirErrors.IS_ENUM_ENTRY
|
||||
DiagnosticKind.EnumEntryAsType -> FirErrors.ENUM_ENTRY_AS_TYPE
|
||||
DiagnosticKind.UnresolvedSupertype,
|
||||
|
||||
+6
-4
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.lightTree.converter
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.psi.TokenType
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.KtNodeTypes.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
@@ -504,15 +503,18 @@ class ExpressionsConverter(
|
||||
val firExpression =
|
||||
getAsFirExpression<FirExpression>(it, "Incorrect ${if (isEffectiveSelector) "selector" else "receiver"} expression")
|
||||
if (isEffectiveSelector) {
|
||||
val callExpressionCallee = if (it.tokenType == CALL_EXPRESSION) it.getFirstChildExpressionUnwrapped() else null
|
||||
firSelector =
|
||||
if (it.tokenType is KtNameReferenceExpressionElementType || it.tokenType == KtNodeTypes.CALL_EXPRESSION) {
|
||||
if (it.tokenType is KtNameReferenceExpressionElementType ||
|
||||
(it.tokenType == CALL_EXPRESSION && callExpressionCallee?.tokenType != LAMBDA_EXPRESSION)
|
||||
) {
|
||||
firExpression
|
||||
} else {
|
||||
buildErrorExpression {
|
||||
source = it.toFirSourceElement()
|
||||
source = callExpressionCallee?.toFirSourceElement() ?: it.toFirSourceElement()
|
||||
diagnostic = ConeSimpleDiagnostic(
|
||||
"The expression cannot be a selector (occur after a dot)",
|
||||
DiagnosticKind.IllegalSelector
|
||||
if (callExpressionCallee == null) DiagnosticKind.IllegalSelector else DiagnosticKind.NoReceiverAllowed
|
||||
)
|
||||
expression = firExpression
|
||||
}
|
||||
|
||||
+22
-16
@@ -211,25 +211,31 @@ open class RawFirBuilder(
|
||||
return buildExpressionStub()
|
||||
} else {
|
||||
val result = this.convertSafe<FirExpression>()
|
||||
|
||||
if (result != null) {
|
||||
if (this != null &&
|
||||
this !is KtNameReferenceExpression &&
|
||||
this !is KtCallExpression &&
|
||||
this !is KtConstantExpression &&
|
||||
getQualifiedExpressionForSelector() != null
|
||||
) {
|
||||
return buildErrorExpression {
|
||||
source = toFirSourceElement()
|
||||
diagnostic =
|
||||
ConeSimpleDiagnostic(
|
||||
"The expression cannot be a selector (occur after a dot)",
|
||||
DiagnosticKind.IllegalSelector
|
||||
)
|
||||
expression = result
|
||||
}
|
||||
if (this == null) {
|
||||
return result
|
||||
}
|
||||
|
||||
return result
|
||||
val callExpressionCallee = (this as? KtCallExpression)?.calleeExpression?.unwrapParenthesesLabelsAndAnnotations()
|
||||
|
||||
if (this is KtNameReferenceExpression ||
|
||||
this is KtConstantExpression ||
|
||||
(this is KtCallExpression && callExpressionCallee !is KtLambdaExpression) ||
|
||||
getQualifiedExpressionForSelector() == null
|
||||
) {
|
||||
return result
|
||||
}
|
||||
|
||||
return buildErrorExpression {
|
||||
source = callExpressionCallee?.toFirSourceElement() ?: toFirSourceElement()
|
||||
diagnostic =
|
||||
ConeSimpleDiagnostic(
|
||||
"The expression cannot be a selector (occur after a dot)",
|
||||
if (callExpressionCallee == null) DiagnosticKind.IllegalSelector else DiagnosticKind.NoReceiverAllowed
|
||||
)
|
||||
expression = result
|
||||
}
|
||||
}
|
||||
|
||||
return buildErrorExpression(
|
||||
|
||||
@@ -23,6 +23,7 @@ enum class DiagnosticKind {
|
||||
NoThis,
|
||||
IllegalConstExpression,
|
||||
IllegalSelector,
|
||||
NoReceiverAllowed,
|
||||
IllegalUnderscore,
|
||||
DeserializationError,
|
||||
InferenceError,
|
||||
|
||||
@@ -83,5 +83,5 @@ fun test() {
|
||||
i.(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)();
|
||||
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
|
||||
1<!UNNECESSARY_SAFE_CALL!>?.<!>(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
|
||||
1.<!UNRESOLVED_REFERENCE!>{}<!>()
|
||||
1.<!NO_RECEIVER_ALLOWED!>{}<!>()
|
||||
}
|
||||
|
||||
+6
@@ -321,6 +321,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.NO_RECEIVER_ALLOWED) { firDiagnostic ->
|
||||
NoReceiverAllowedImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.SUPER_IS_NOT_AN_EXPRESSION) { firDiagnostic ->
|
||||
SuperIsNotAnExpressionImpl(
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
|
||||
+4
@@ -253,6 +253,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = IllegalSelector::class
|
||||
}
|
||||
|
||||
abstract class NoReceiverAllowed : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = NoReceiverAllowed::class
|
||||
}
|
||||
|
||||
abstract class SuperIsNotAnExpression : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = SuperIsNotAnExpression::class
|
||||
}
|
||||
|
||||
+7
@@ -374,6 +374,13 @@ internal class IllegalSelectorImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class NoReceiverAllowedImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.NoReceiverAllowed(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class SuperIsNotAnExpressionImpl(
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user